Merge "Switch from networkCreate[Physical/Vpn] to networkCreate"
diff --git a/Android.bp b/Android.bp
index 084c9f5..c5d557c 100644
--- a/Android.bp
+++ b/Android.bp
@@ -67,6 +67,7 @@
     name: "framework-non-updatable-sources",
     srcs: [
         // Java/AIDL sources under frameworks/base
+        ":framework-annotations",
         ":framework-blobstore-sources",
         ":framework-core-sources",
         ":framework-drm-sources",
@@ -210,6 +211,7 @@
         "apex_aidl_interface-java",
         "framework-protos",
         "updatable-driver-protos",
+        "ota_metadata_proto_java",
         "android.hidl.base-V1.0-java",
         "android.hardware.cas-V1.0-java",
         "android.hardware.cas-V1.1-java",
@@ -341,46 +343,6 @@
 }
 
 filegroup {
-    name: "framework-annotations",
-    srcs: [
-        "core/java/android/annotation/AnyThread.java",
-        "core/java/android/annotation/AppIdInt.java",
-        "core/java/android/annotation/BytesLong.java",
-        "core/java/android/annotation/CallbackExecutor.java",
-        "core/java/android/annotation/CallSuper.java",
-        "core/java/android/annotation/CheckResult.java",
-        "core/java/android/annotation/CurrentTimeMillisLong.java",
-        "core/java/android/annotation/CurrentTimeSecondsLong.java",
-        "core/java/android/annotation/DrawableRes.java",
-        "core/java/android/annotation/DurationMillisLong.java",
-        "core/java/android/annotation/Hide.java",
-        "core/java/android/annotation/IntDef.java",
-        "core/java/android/annotation/IntRange.java",
-        "core/java/android/annotation/LongDef.java",
-        "core/java/android/annotation/MainThread.java",
-        "core/java/android/annotation/NonNull.java",
-        "core/java/android/annotation/Nullable.java",
-        "core/java/android/annotation/RequiresPermission.java",
-        "core/java/android/annotation/SdkConstant.java",
-        "core/java/android/annotation/StringDef.java",
-        "core/java/android/annotation/SystemApi.java",
-        "core/java/android/annotation/SystemService.java",
-        "core/java/android/annotation/TestApi.java",
-        "core/java/android/annotation/UserIdInt.java",
-        "core/java/android/annotation/WorkerThread.java",
-        "core/java/com/android/internal/annotations/GuardedBy.java",
-        "core/java/com/android/internal/annotations/Immutable.java",
-        "core/java/com/android/internal/annotations/VisibleForTesting.java",
-    ],
-}
-
-java_library {
-    name: "framework-annotations-lib",
-    srcs: [":framework-annotations"],
-    sdk_version: "core_current",
-}
-
-filegroup {
     name: "framework-ike-shared-srcs",
     visibility: ["//packages/modules/IPsec"],
     srcs: [
@@ -473,8 +435,21 @@
     "--api-lint-ignore-prefix junit. " +
     "--api-lint-ignore-prefix org. "
 
+packages_to_document = [
+    "android",
+    "dalvik",
+    "java",
+    "javax",
+    "junit",
+    "org.apache.http",
+    "org.json",
+    "org.w3c.dom",
+    "org.xml.sax",
+    "org.xmlpull",
+]
+
 filegroup {
-    name: "framework-non-updatable-stub-sources",
+    name: "android-non-updatable-stub-sources",
     srcs: [
         ":framework-mime-sources", // mimemap builds separately but has no separate droidstubs.
         ":framework-non-updatable-sources",
@@ -486,6 +461,61 @@
     visibility: ["//visibility:private"],
 }
 
+// These defaults are used for both the jar stubs and the doc stubs.
+stubs_defaults {
+    name: "android-non-updatable-stubs-defaults",
+    srcs: [":android-non-updatable-stub-sources"],
+    sdk_version: "none",
+    system_modules: "none",
+    java_version: "1.8",
+    arg_files: ["core/res/AndroidManifest.xml"],
+    // TODO(b/147699819): remove below aidl includes.
+    aidl: {
+        local_include_dirs: [
+            "apex/media/aidl/stable",
+            // TODO: move to include-dirs for packages/modules/Connectivity when this moves out of
+            // frameworks/base
+            "packages/Connectivity/framework/aidl-export",
+            "telephony/java",
+        ],
+    },
+    // These are libs from framework-internal-utils that are required (i.e. being referenced)
+    // from framework-non-updatable-sources. Add more here when there's a need.
+    // DO NOT add the entire framework-internal-utils. It might cause unnecessary circular
+    // dependencies gets bigger.
+    libs: [
+        "android.hardware.cas-V1.2-java",
+        "android.hardware.health-V1.0-java-constants",
+        "android.hardware.radio-V1.5-java",
+        "android.hardware.radio-V1.6-java",
+        "android.hardware.thermal-V1.0-java-constants",
+        "android.hardware.thermal-V2.0-java",
+        "android.hardware.tv.input-V1.0-java-constants",
+        "android.hardware.tv.tuner-V1.0-java-constants",
+        "android.hardware.usb-V1.0-java-constants",
+        "android.hardware.usb-V1.1-java-constants",
+        "android.hardware.usb.gadget-V1.0-java",
+        "android.hardware.vibrator-V1.3-java",
+        "framework-protos",
+        "art.module.public.api",
+        // There are a few classes from modules used by the core that
+        // need to be resolved by metalava. We use a prebuilt stub of the
+        // full sdk to ensure we can resolve them. If a new class gets added,
+        // the prebuilts/sdk/current needs to be updated.
+        "sdk_system_current_android",
+        // NOTE: The below can be removed once the prebuilt stub contains IKE.
+        "sdk_system_current_android.net.ipsec.ike",
+    ],
+    filter_packages: packages_to_document,
+    high_mem: true, // Lots of sources => high memory use, see b/170701554
+    installable: false,
+    annotations_enabled: true,
+    previous_api: ":android.api.public.latest",
+    merge_annotations_dirs: ["metalava-manual"],
+    defaults_visibility: ["//visibility:private"],
+    visibility: ["//frameworks/base/api"],
+}
+
 build = [
     "StubLibraries.bp",
     "ApiDocs.bp",
diff --git a/ApiDocs.bp b/ApiDocs.bp
index d3bef7f..83ace02 100644
--- a/ApiDocs.bp
+++ b/ApiDocs.bp
@@ -56,9 +56,23 @@
 ]
 
 stubs_defaults {
+    name: "android-non-updatable-doc-stubs-defaults",
+    defaults: ["android-non-updatable-stubs-defaults"],
+    srcs: [
+        // No longer part of the stubs, but are included in the docs.
+        "test-base/src/**/*.java",
+        "test-mock/src/**/*.java",
+        "test-runner/src/**/*.java",
+    ],
+    libs: framework_docs_only_libs,
+    create_doc_stubs: true,
+    write_sdk_values: true,
+}
+
+stubs_defaults {
     name: "framework-doc-stubs-default",
     srcs: [
-        ":framework-non-updatable-stub-sources",
+        ":android-non-updatable-stub-sources",
 
         // Module sources
         ":art.module.public.api{.public.stubs.source}",
@@ -75,13 +89,14 @@
         ":updatable-media-srcs",
 
         // No longer part of the stubs, but are included in the docs.
-        "test-base/src/**/*.java",
-        "test-mock/src/**/*.java",
-        "test-runner/src/**/*.java",
+        ":android-test-base-sources",
+        ":android-test-mock-sources",
+        ":android-test-runner-sources",
     ],
     libs: framework_docs_only_libs,
     create_doc_stubs: true,
     annotations_enabled: true,
+    filter_packages: packages_to_document,
     api_levels_annotations_enabled: true,
     api_levels_annotations_dirs: [
         "sdk-dir",
@@ -94,14 +109,25 @@
 }
 
 droidstubs {
+    name: "android-non-updatable-doc-stubs",
+    defaults: ["android-non-updatable-doc-stubs-defaults"],
+    args: metalava_framework_docs_args,
+}
+
+droidstubs {
+    name: "android-non-updatable-doc-stubs-system",
+    defaults: ["android-non-updatable-doc-stubs-defaults"],
+    args: metalava_framework_docs_args +
+        " --show-annotation android.annotation.SystemApi\\(client=android.annotation.SystemApi.Client.PRIVILEGED_APPS\\) ",
+}
+
+droidstubs {
     name: "framework-doc-stubs",
     defaults: ["framework-doc-stubs-default"],
     arg_files: [
         "core/res/AndroidManifest.xml",
     ],
-    args: metalava_framework_docs_args +
-        // Needed for hidden libcore annotations for now.
-        " --ignore-classes-on-classpath ",
+    args: metalava_framework_docs_args,
     write_sdk_values: true,
 }
 
@@ -112,8 +138,6 @@
         "core/res/AndroidManifest.xml",
     ],
     args: metalava_framework_docs_args +
-        // Needed for hidden libcore annotations for now.
-        " --ignore-classes-on-classpath " +
         " --show-annotation android.annotation.SystemApi\\(client=android.annotation.SystemApi.Client.PRIVILEGED_APPS\\) ",
     write_sdk_values: true,
 }
diff --git a/StubLibraries.bp b/StubLibraries.bp
index 00d0771..626f977 100644
--- a/StubLibraries.bp
+++ b/StubLibraries.bp
@@ -27,74 +27,11 @@
 // Common metalava configs
 /////////////////////////////////////////////////////////////////////
 
-packages_to_document = [
-    "android",
-    "dalvik",
-    "java",
-    "javax",
-    "junit",
-    "org.apache.http",
-    "org.json",
-    "org.w3c.dom",
-    "org.xml.sax",
-    "org.xmlpull",
-]
-
 stubs_defaults {
     name: "metalava-non-updatable-api-stubs-default",
-    srcs: [":framework-non-updatable-stub-sources"],
-    sdk_version: "none",
-    system_modules: "none",
-    java_version: "1.8",
-    arg_files: ["core/res/AndroidManifest.xml"],
-    // TODO(b/147699819): remove below aidl includes.
-    aidl: {
-        local_include_dirs: [
-            "apex/media/aidl/stable",
-            // TODO: move to include-dirs for packages/modules/Connectivity when this moves out of
-            // frameworks/base
-            "packages/Connectivity/framework/aidl-export",
-            "telephony/java",
-        ],
-    },
-    // These are libs from framework-internal-utils that are required (i.e. being referenced)
-    // from framework-non-updatable-sources. Add more here when there's a need.
-    // DO NOT add the entire framework-internal-utils. It might cause unnecessary circular
-    // dependencies gets bigger.
-    libs: [
-        "android.hardware.cas-V1.2-java",
-        "android.hardware.health-V1.0-java-constants",
-        "android.hardware.radio-V1.5-java",
-        "android.hardware.radio-V1.6-java",
-        "android.hardware.thermal-V1.0-java-constants",
-        "android.hardware.thermal-V2.0-java",
-        "android.hardware.tv.input-V1.0-java-constants",
-        "android.hardware.tv.tuner-V1.0-java-constants",
-        "android.hardware.usb-V1.0-java-constants",
-        "android.hardware.usb-V1.1-java-constants",
-        "android.hardware.usb.gadget-V1.0-java",
-        "android.hardware.vibrator-V1.3-java",
-        "framework-protos",
-        "stable.core.platform.api.stubs",
-        // There are a few classes from modules used by the core that
-        // need to be resolved by metalava. We use a prebuilt stub of the
-        // full sdk to ensure we can resolve them. If a new class gets added,
-        // the prebuilts/sdk/current needs to be updated.
-        "sdk_system_current_android",
-        // NOTE: The below can be removed once the prebuilt stub contains IKE.
-        "sdk_system_current_android.net.ipsec.ike",
-    ],
-    high_mem: true, // Lots of sources => high memory use, see b/170701554
-    installable: false,
-    annotations_enabled: true,
-    previous_api: ":android.api.public.latest",
-    merge_annotations_dirs: [
-        "metalava-manual",
-    ],
+    defaults: ["android-non-updatable-stubs-defaults"],
     api_levels_annotations_enabled: false,
-    filter_packages: packages_to_document,
     defaults_visibility: ["//visibility:private"],
-    visibility: ["//frameworks/base/api"],
 }
 
 /////////////////////////////////////////////////////////////////////
@@ -347,7 +284,7 @@
     visibility: ["//visibility:private"],
 }
 
-java_library_static {
+java_library {
     name: "android-non-updatable.stubs",
     defaults: ["android-non-updatable_defaults_stubs_current"],
     srcs: [":api-stubs-docs-non-updatable"],
@@ -357,7 +294,7 @@
     },
 }
 
-java_library_static {
+java_library {
     name: "android-non-updatable.stubs.system",
     defaults: ["android-non-updatable_defaults_stubs_current"],
     srcs: [":system-api-stubs-docs-non-updatable"],
@@ -367,7 +304,7 @@
     },
 }
 
-java_library_static {
+java_library {
     name: "android-non-updatable.stubs.module_lib",
     defaults: ["android-non-updatable_defaults_stubs_current"],
     srcs: [":module-lib-api-stubs-docs-non-updatable"],
@@ -381,7 +318,7 @@
     },
 }
 
-java_library_static {
+java_library {
     name: "android-non-updatable.stubs.test",
     defaults: ["android-non-updatable_defaults_stubs_current"],
     srcs: [":test-api-stubs-docs-non-updatable"],
@@ -404,7 +341,7 @@
     defaults_visibility: ["//frameworks/base/services"],
 }
 
-java_library_static {
+java_library {
     name: "android_stubs_current",
     static_libs: modules_public_stubs + [
         "android-non-updatable.stubs",
@@ -413,7 +350,7 @@
     defaults: ["android.jar_defaults"],
 }
 
-java_library_static {
+java_library {
     name: "android_system_stubs_current",
     static_libs: modules_system_stubs + [
         "android-non-updatable.stubs.system",
@@ -439,7 +376,7 @@
     ],
 }
 
-java_library_static {
+java_library {
     name: "android_test_stubs_current",
     // Modules do not have test APIs, but we want to include their SystemApis, like we include
     // the SystemApi of framework-non-updatable-sources.
@@ -456,7 +393,7 @@
     },
 }
 
-java_library_static {
+java_library {
     name: "android_module_lib_stubs_current",
     defaults: [
         "android.jar_defaults",
@@ -471,6 +408,22 @@
     },
 }
 
+java_library {
+    name: "android_system_server_stubs_current",
+    defaults: ["android_stubs_dists_default"],
+    srcs: [":services-non-updatable-stubs"],
+    installable: false,
+    static_libs: [
+        "android_module_lib_stubs_current",
+    ],
+    sdk_version: "none",
+    system_modules: "none",
+    java_version: "1.8",
+    dist: {
+        dir: "apistubs/android/system-server",
+    },
+}
+
 /////////////////////////////////////////////////////////////////////
 // hwbinder.stubs provides APIs required for building HIDL Java
 // libraries.
@@ -504,7 +457,7 @@
     visibility: ["//visibility:private"],
 }
 
-java_library_static {
+java_library {
     name: "hwbinder.stubs",
     sdk_version: "core_current",
     libs: ["framework-annotations-lib"],
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobStore.java b/apex/jobscheduler/service/java/com/android/server/job/JobStore.java
index 26010ef6..bdab7d0 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobStore.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobStore.java
@@ -545,7 +545,7 @@
                 out.attribute(null, "net-capabilities", Long.toString(
                         BitUtils.packBits(network.getCapabilities())));
                 out.attribute(null, "net-unwanted-capabilities", Long.toString(
-                        BitUtils.packBits(network.getUnwantedCapabilities())));
+                        BitUtils.packBits(network.getForbiddenCapabilities())));
 
                 out.attribute(null, "net-transport-types", Long.toString(
                         BitUtils.packBits(network.getTransportTypes())));
@@ -968,22 +968,22 @@
             String val;
 
             final String netCapabilities = parser.getAttributeValue(null, "net-capabilities");
-            final String netUnwantedCapabilities = parser.getAttributeValue(
+            final String netforbiddenCapabilities = parser.getAttributeValue(
                     null, "net-unwanted-capabilities");
             final String netTransportTypes = parser.getAttributeValue(null, "net-transport-types");
             if (netCapabilities != null && netTransportTypes != null) {
                 final NetworkRequest.Builder builder = new NetworkRequest.Builder()
                         .clearCapabilities();
-                final long unwantedCapabilities = netUnwantedCapabilities != null
-                        ? Long.parseLong(netUnwantedCapabilities)
-                        : BitUtils.packBits(builder.build().getUnwantedCapabilities());
+                final long forbiddenCapabilities = netforbiddenCapabilities != null
+                        ? Long.parseLong(netforbiddenCapabilities)
+                        : BitUtils.packBits(builder.build().getForbiddenCapabilities());
                 // We're okay throwing NFE here; caught by caller
                 for (int capability : BitUtils.unpackBits(Long.parseLong(netCapabilities))) {
                     builder.addCapability(capability);
                 }
-                for (int unwantedCapability : BitUtils.unpackBits(
-                        Long.parseLong(netUnwantedCapabilities))) {
-                    builder.addUnwantedCapability(unwantedCapability);
+                for (int forbiddenCapability : BitUtils.unpackBits(
+                        Long.parseLong(netforbiddenCapabilities))) {
+                    builder.addForbiddenCapability(forbiddenCapability);
                 }
                 for (int transport : BitUtils.unpackBits(Long.parseLong(netTransportTypes))) {
                     builder.addTransportType(transport);
diff --git a/api/Android.bp b/api/Android.bp
index 6e83c08..2df31ec 100644
--- a/api/Android.bp
+++ b/api/Android.bp
@@ -341,7 +341,7 @@
         {
             targets: ["sdk", "win_sdk"],
             dir: "apistubs/android/system-server/api",
-            dest: "merge-android.txt",
+            dest: "android.txt",
         },
     ],
 }
@@ -364,7 +364,7 @@
         {
             targets: ["sdk", "win_sdk"],
             dir: "apistubs/android/system-server/api",
-            dest: "merge-removed.txt",
+            dest: "removed.txt",
         },
     ],
 }
diff --git a/boot/Android.bp b/boot/Android.bp
index ef2abc8..3caede4 100644
--- a/boot/Android.bp
+++ b/boot/Android.bp
@@ -98,4 +98,12 @@
             dest: "hiddenapi-unsupported.csv",
         },
     ],
+
+    required: [
+        "platform-systemserverclasspath",
+    ],
+}
+
+platform_systemserverclasspath {
+    name: "platform-systemserverclasspath",
 }
diff --git a/boot/OWNERS b/boot/OWNERS
index 0648888..0e258d0 100644
--- a/boot/OWNERS
+++ b/boot/OWNERS
@@ -1,2 +1,6 @@
 # soong-team@ as the platform_bootclasspath module is tightly coupled with Soong
 file:platform/build/soong:/OWNERS
+
+# art-team@ manages the boot image profiles for frameworks
+per-file boot-* = calin@google.com, yawanng@google.com, ngeoffray@google.com
+per-file preloaded-classes* = calin@google.com, yawanng@google.com, ngeoffray@google.com
diff --git a/boot/boot-image-profile.txt b/boot/boot-image-profile.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/boot/boot-image-profile.txt
diff --git a/boot/preloaded-classes b/boot/preloaded-classes
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/boot/preloaded-classes
diff --git a/cmds/idmap2/idmap2d/aidl/android/os/OverlayablePolicy.aidl b/cmds/idmap2/idmap2d/aidl/android/os/OverlayablePolicy.aidl
index 403d8c5..a47b8416 100644
--- a/cmds/idmap2/idmap2d/aidl/android/os/OverlayablePolicy.aidl
+++ b/cmds/idmap2/idmap2d/aidl/android/os/OverlayablePolicy.aidl
@@ -20,14 +20,16 @@
  * @see ResourcesTypes.h ResTable_overlayable_policy_header::PolicyFlags
  * @hide
  */
-interface OverlayablePolicy {
-  const int PUBLIC = 0x00000001;
-  const int SYSTEM_PARTITION = 0x00000002;
-  const int VENDOR_PARTITION = 0x00000004;
-  const int PRODUCT_PARTITION = 0x00000008;
-  const int SIGNATURE = 0x00000010;
-  const int ODM_PARTITION = 0x00000020;
-  const int OEM_PARTITION = 0x00000040;
-  const int ACTOR_SIGNATURE = 0x00000080;
-  const int CONFIG_SIGNATURE = 0x0000100;
+@Backing(type="int")
+enum OverlayablePolicy {
+  NONE = 0x00000000,
+  PUBLIC = 0x00000001,
+  SYSTEM_PARTITION = 0x00000002,
+  VENDOR_PARTITION = 0x00000004,
+  PRODUCT_PARTITION = 0x00000008,
+  SIGNATURE = 0x00000010,
+  ODM_PARTITION = 0x00000020,
+  OEM_PARTITION = 0x00000040,
+  ACTOR_SIGNATURE = 0x00000080,
+  CONFIG_SIGNATURE = 0x0000100,
 }
diff --git a/core/api/current.txt b/core/api/current.txt
index 0c63775..cd4e6f9 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -19377,15 +19377,23 @@
     field public static final int ENCODING_DEFAULT = 1; // 0x1
     field public static final int ENCODING_DOLBY_MAT = 19; // 0x13
     field public static final int ENCODING_DOLBY_TRUEHD = 14; // 0xe
+    field public static final int ENCODING_DRA = 28; // 0x1c
     field public static final int ENCODING_DTS = 7; // 0x7
     field public static final int ENCODING_DTS_HD = 8; // 0x8
+    field public static final int ENCODING_DTS_UHD = 27; // 0x1b
     field public static final int ENCODING_E_AC3 = 6; // 0x6
     field public static final int ENCODING_E_AC3_JOC = 18; // 0x12
     field public static final int ENCODING_IEC61937 = 13; // 0xd
     field public static final int ENCODING_INVALID = 0; // 0x0
     field public static final int ENCODING_MP3 = 9; // 0x9
+    field public static final int ENCODING_MPEGH_BL_L3 = 23; // 0x17
+    field public static final int ENCODING_MPEGH_BL_L4 = 24; // 0x18
+    field public static final int ENCODING_MPEGH_LC_L3 = 25; // 0x19
+    field public static final int ENCODING_MPEGH_LC_L4 = 26; // 0x1a
     field public static final int ENCODING_OPUS = 20; // 0x14
     field public static final int ENCODING_PCM_16BIT = 2; // 0x2
+    field public static final int ENCODING_PCM_24BIT_PACKED = 21; // 0x15
+    field public static final int ENCODING_PCM_32BIT = 22; // 0x16
     field public static final int ENCODING_PCM_8BIT = 3; // 0x3
     field public static final int ENCODING_PCM_FLOAT = 4; // 0x4
     field public static final int SAMPLE_RATE_UNSPECIFIED = 0; // 0x0
@@ -21438,6 +21446,8 @@
     field public static final String MIMETYPE_AUDIO_G711_ALAW = "audio/g711-alaw";
     field public static final String MIMETYPE_AUDIO_G711_MLAW = "audio/g711-mlaw";
     field public static final String MIMETYPE_AUDIO_MPEG = "audio/mpeg";
+    field public static final String MIMETYPE_AUDIO_MPEGH_MHA1 = "audio/mha1";
+    field public static final String MIMETYPE_AUDIO_MPEGH_MHM1 = "audio/mhm1";
     field public static final String MIMETYPE_AUDIO_MSGSM = "audio/gsm";
     field public static final String MIMETYPE_AUDIO_OPUS = "audio/opus";
     field public static final String MIMETYPE_AUDIO_QCELP = "audio/qcelp";
@@ -25138,9 +25148,6 @@
     field public static final int UNSUPPORTED = -1; // 0xffffffff
   }
 
-  public interface TunnelConnectionParams {
-  }
-
   public abstract class Uri implements java.lang.Comparable<android.net.Uri> android.os.Parcelable {
     method public abstract android.net.Uri.Builder buildUpon();
     method public int compareTo(android.net.Uri);
@@ -25705,16 +25712,16 @@
     method @NonNull public int[] getExposedCapabilities();
     method @NonNull public String getGatewayConnectionName();
     method @IntRange(from=android.net.vcn.VcnGatewayConnectionConfig.MIN_MTU_V6) public int getMaxMtu();
-    method @NonNull public long[] getRetryIntervalsMs();
+    method @NonNull public long[] getRetryIntervalsMillis();
   }
 
   public static final class VcnGatewayConnectionConfig.Builder {
-    ctor public VcnGatewayConnectionConfig.Builder(@NonNull String, @NonNull android.net.TunnelConnectionParams);
+    ctor public VcnGatewayConnectionConfig.Builder(@NonNull String, @NonNull android.net.ipsec.ike.IkeTunnelConnectionParams);
     method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder addExposedCapability(int);
     method @NonNull public android.net.vcn.VcnGatewayConnectionConfig build();
     method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder removeExposedCapability(int);
     method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder setMaxMtu(@IntRange(from=android.net.vcn.VcnGatewayConnectionConfig.MIN_MTU_V6) int);
-    method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder setRetryIntervalsMs(@NonNull long[]);
+    method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder setRetryIntervalsMillis(@NonNull long[]);
   }
 
   public class VcnManager {
@@ -31473,6 +31480,7 @@
     field public static final android.print.PrintAttributes.MediaSize JPN_HAGAKI;
     field public static final android.print.PrintAttributes.MediaSize JPN_KAHU;
     field public static final android.print.PrintAttributes.MediaSize JPN_KAKU2;
+    field @NonNull public static final android.print.PrintAttributes.MediaSize JPN_OE_PHOTO_L;
     field public static final android.print.PrintAttributes.MediaSize JPN_OUFUKU;
     field public static final android.print.PrintAttributes.MediaSize JPN_YOU4;
     field @NonNull public static final android.print.PrintAttributes.MediaSize NA_ARCH_A;
@@ -31494,7 +31502,6 @@
     field public static final android.print.PrintAttributes.MediaSize NA_QUARTO;
     field @NonNull public static final android.print.PrintAttributes.MediaSize NA_SUPER_B;
     field public static final android.print.PrintAttributes.MediaSize NA_TABLOID;
-    field @NonNull public static final android.print.PrintAttributes.MediaSize OE_PHOTO_L;
     field public static final android.print.PrintAttributes.MediaSize OM_DAI_PA_KAI;
     field public static final android.print.PrintAttributes.MediaSize OM_JUURO_KU_KAI;
     field public static final android.print.PrintAttributes.MediaSize OM_PA_KAI;
@@ -40401,7 +40408,6 @@
     method @IntRange(from=1, to=261) public int getBand();
     method @IntRange(from=1) public int getCellBandwidthDownlinkKhz();
     method @IntRange(from=1) public int getCellBandwidthUplinkKhz();
-    method @Deprecated public int getChannelNumber();
     method public int getConnectionStatus();
     method @IntRange(from=0) public int getDownlinkChannelNumber();
     method @IntRange(from=0) public int getDownlinkFrequencyKhz();
@@ -40790,6 +40796,8 @@
     method public static int getDefaultSmsSubscriptionId();
     method public static int getDefaultSubscriptionId();
     method public static int getDefaultVoiceSubscriptionId();
+    method public int getDeviceToDeviceStatusSharing(int);
+    method @NonNull public java.util.List<android.net.Uri> getDeviceToDeviceStatusSharingContacts(int);
     method @NonNull @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public java.util.List<android.telephony.SubscriptionInfo> getOpportunisticSubscriptions();
     method public static int getSlotIndex(int);
     method @Nullable public int[] getSubscriptionIds(int);
@@ -40802,6 +40810,8 @@
     method public void removeOnOpportunisticSubscriptionsChangedListener(@NonNull android.telephony.SubscriptionManager.OnOpportunisticSubscriptionsChangedListener);
     method public void removeOnSubscriptionsChangedListener(android.telephony.SubscriptionManager.OnSubscriptionsChangedListener);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void removeSubscriptionsFromGroup(@NonNull java.util.List<java.lang.Integer>, @NonNull android.os.ParcelUuid);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDeviceToDeviceStatusSharing(int, int);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDeviceToDeviceStatusSharingContacts(@NonNull java.util.List<android.net.Uri>, int);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setOpportunistic(boolean, int);
     method public void setSubscriptionOverrideCongested(int, boolean, long);
     method public void setSubscriptionOverrideCongested(int, boolean, @NonNull int[], long);
@@ -40813,6 +40823,12 @@
     field public static final String ACTION_DEFAULT_SUBSCRIPTION_CHANGED = "android.telephony.action.DEFAULT_SUBSCRIPTION_CHANGED";
     field public static final String ACTION_MANAGE_SUBSCRIPTION_PLANS = "android.telephony.action.MANAGE_SUBSCRIPTION_PLANS";
     field public static final String ACTION_REFRESH_SUBSCRIPTION_PLANS = "android.telephony.action.REFRESH_SUBSCRIPTION_PLANS";
+    field public static final int D2D_SHARING_ALL = 3; // 0x3
+    field public static final int D2D_SHARING_ALL_CONTACTS = 1; // 0x1
+    field public static final int D2D_SHARING_DISABLED = 0; // 0x0
+    field public static final int D2D_SHARING_SELECTED_CONTACTS = 2; // 0x2
+    field public static final String D2D_STATUS_SHARING = "d2d_sharing_status";
+    field public static final String D2D_STATUS_SHARING_SELECTED_CONTACTS = "d2d_sharing_contacts";
     field public static final int DATA_ROAMING_DISABLE = 0; // 0x0
     field public static final int DATA_ROAMING_ENABLE = 1; // 0x1
     field public static final int DEFAULT_SUBSCRIPTION_ID = 2147483647; // 0x7fffffff
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index 66ac74a..848f480 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -59,13 +59,13 @@
   public final class NetworkStateSnapshot implements android.os.Parcelable {
     ctor public NetworkStateSnapshot(@NonNull android.net.Network, @NonNull android.net.NetworkCapabilities, @NonNull android.net.LinkProperties, @Nullable String, int);
     method public int describeContents();
+    method public int getLegacyType();
+    method @NonNull public android.net.LinkProperties getLinkProperties();
+    method @NonNull public android.net.Network getNetwork();
+    method @NonNull public android.net.NetworkCapabilities getNetworkCapabilities();
+    method @Nullable public String getSubscriberId();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkStateSnapshot> CREATOR;
-    field public final int legacyType;
-    field @NonNull public final android.net.LinkProperties linkProperties;
-    field @NonNull public final android.net.Network network;
-    field @NonNull public final android.net.NetworkCapabilities networkCapabilities;
-    field @Nullable public final String subscriberId;
   }
 
   public class NetworkWatchlistManager {
@@ -89,11 +89,11 @@
   public final class UnderlyingNetworkInfo implements android.os.Parcelable {
     ctor public UnderlyingNetworkInfo(int, @NonNull String, @NonNull java.util.List<java.lang.String>);
     method public int describeContents();
+    method @NonNull public String getIface();
+    method public int getOwnerUid();
+    method @NonNull public java.util.List<java.lang.String> getUnderlyingIfaces();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.net.UnderlyingNetworkInfo> CREATOR;
-    field @NonNull public final String iface;
-    field public final int ownerUid;
-    field @NonNull public final java.util.List<java.lang.String> underlyingIfaces;
   }
 
   public class VpnManager {
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index ef3a543..bb42ddc 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -1124,10 +1124,11 @@
 package android.app.compat {
 
   public final class CompatChanges {
+    method @RequiresPermission(android.Manifest.permission.OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD) public static void addPackageOverrides(@NonNull String, @NonNull java.util.Map<java.lang.Long,android.app.compat.PackageOverride>);
     method public static boolean isChangeEnabled(long);
     method @RequiresPermission(allOf={"android.permission.READ_COMPAT_CHANGE_CONFIG", "android.permission.LOG_COMPAT_CHANGE"}) public static boolean isChangeEnabled(long, @NonNull String, @NonNull android.os.UserHandle);
     method @RequiresPermission(allOf={"android.permission.READ_COMPAT_CHANGE_CONFIG", "android.permission.LOG_COMPAT_CHANGE"}) public static boolean isChangeEnabled(long, int);
-    method @RequiresPermission(android.Manifest.permission.OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD) public static void setPackageOverride(@NonNull String, @NonNull java.util.Map<java.lang.Long,android.app.compat.PackageOverride>);
+    method @RequiresPermission(android.Manifest.permission.OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD) public static void removePackageOverrides(@NonNull String, @NonNull java.util.Set<java.lang.Long>);
   }
 
   public final class PackageOverride {
@@ -1503,7 +1504,7 @@
 
   public static interface BluetoothAdapter.OobDataCallback {
     method public void onError(int);
-    method public void onOobData(int, @Nullable android.bluetooth.OobData);
+    method public void onOobData(int, @NonNull android.bluetooth.OobData);
   }
 
   public final class BluetoothDevice implements android.os.Parcelable {
@@ -1685,8 +1686,6 @@
   }
 
   public final class OobData implements android.os.Parcelable {
-    method @NonNull public static android.bluetooth.OobData.ClassicBuilder createClassicBuilder(@NonNull byte[], @NonNull byte[], @NonNull byte[]);
-    method @NonNull public static android.bluetooth.OobData.LeBuilder createLeBuilder(@NonNull byte[], @NonNull byte[], int);
     method @NonNull public byte[] getClassOfDevice();
     method @NonNull public byte[] getClassicLength();
     method @NonNull public byte[] getConfirmationHash();
@@ -1719,6 +1718,7 @@
   }
 
   public static final class OobData.ClassicBuilder {
+    ctor public OobData.ClassicBuilder(@NonNull byte[], @NonNull byte[], @NonNull byte[]);
     method @NonNull public android.bluetooth.OobData build();
     method @NonNull public android.bluetooth.OobData.ClassicBuilder setClassOfDevice(@NonNull byte[]);
     method @NonNull public android.bluetooth.OobData.ClassicBuilder setDeviceName(@NonNull byte[]);
@@ -1726,6 +1726,7 @@
   }
 
   public static final class OobData.LeBuilder {
+    ctor public OobData.LeBuilder(@NonNull byte[], @NonNull byte[], int);
     method @NonNull public android.bluetooth.OobData build();
     method @NonNull public android.bluetooth.OobData.LeBuilder setDeviceName(@NonNull byte[]);
     method @NonNull public android.bluetooth.OobData.LeBuilder setLeFlags(int);
@@ -10069,6 +10070,7 @@
     method public boolean canManageSubscription(@NonNull android.telephony.SubscriptionInfo, @NonNull String);
     method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int[] getActiveSubscriptionIdList();
     method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.SubscriptionInfo getActiveSubscriptionInfoForIcc(@NonNull String);
+    method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public byte[] getAllSimSpecificSettingsForBackup();
     method public java.util.List<android.telephony.SubscriptionInfo> getAvailableSubscriptionInfoList();
     method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int[] getCompleteActiveSubscriptionIdList();
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getEnabledSubscriptionId(int);
@@ -10076,6 +10078,7 @@
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isSubscriptionEnabled(int);
     method public void requestEmbeddedSubscriptionInfoListRefresh();
     method public void requestEmbeddedSubscriptionInfoListRefresh(int);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void restoreAllSimSpecificSettingsFromBackup(@NonNull byte[]);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDefaultDataSubId(int);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDefaultSmsSubId(int);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDefaultVoiceSubscriptionId(int);
@@ -12328,6 +12331,7 @@
     field public static final int REGISTRATION_TECH_IWLAN = 1; // 0x1
     field public static final int REGISTRATION_TECH_LTE = 0; // 0x0
     field public static final int REGISTRATION_TECH_NONE = -1; // 0xffffffff
+    field public static final int REGISTRATION_TECH_NR = 3; // 0x3
   }
 
   public class ImsSmsImplBase {
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index fd6d47e..3b759a2 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -14,6 +14,7 @@
     field public static final String CONTROL_DEVICE_LIGHTS = "android.permission.CONTROL_DEVICE_LIGHTS";
     field public static final String FORCE_DEVICE_POLICY_MANAGER_LOGS = "android.permission.FORCE_DEVICE_POLICY_MANAGER_LOGS";
     field public static final String FORCE_STOP_PACKAGES = "android.permission.FORCE_STOP_PACKAGES";
+    field public static final String INSTALL_TEST_ONLY_PACKAGE = "android.permission.INSTALL_TEST_ONLY_PACKAGE";
     field public static final String KEEP_UNINSTALLED_PACKAGES = "android.permission.KEEP_UNINSTALLED_PACKAGES";
     field public static final String MANAGE_ACTIVITY_STACKS = "android.permission.MANAGE_ACTIVITY_STACKS";
     field public static final String MANAGE_CRATES = "android.permission.MANAGE_CRATES";
@@ -536,6 +537,10 @@
     field @NonNull public static final android.os.Parcelable.Creator<android.content.pm.ProviderInfoList> CREATOR;
   }
 
+  public final class SharedLibraryInfo implements android.os.Parcelable {
+    method @NonNull public java.util.List<java.lang.String> getAllCodePaths();
+  }
+
   public final class ShortcutInfo implements android.os.Parcelable {
     method public boolean isVisibleToPublisher();
   }
@@ -1190,6 +1195,7 @@
 
   public class VintfObject {
     method public static String[] getHalNamesAndVersions();
+    method @NonNull public static String getPlatformSepolicyVersion();
     method public static String getSepolicyVersion();
     method public static Long getTargetFrameworkCompatibilityMatrixVersion();
     method public static java.util.Map<java.lang.String,java.lang.String[]> getVndkSnapshots();
@@ -1683,6 +1689,7 @@
   public class TelephonyManager {
     method public int addDevicePolicyOverrideApn(@NonNull android.content.Context, @NonNull android.telephony.data.ApnSetting);
     method public int getCarrierIdListVersion();
+    method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.List<java.lang.String> getCertsFromCarrierPrivilegeAccessRules();
     method @NonNull public java.util.List<android.telephony.data.ApnSetting> getDevicePolicyOverrideApns(@NonNull android.content.Context);
     method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public String getLine1AlphaTag();
     method public android.util.Pair<java.lang.Integer,java.lang.Integer> getRadioHalVersion();
diff --git a/core/java/Android.bp b/core/java/Android.bp
index 965665d..874704e 100644
--- a/core/java/Android.bp
+++ b/core/java/Android.bp
@@ -46,43 +46,6 @@
         "android/accounts/AccountsException.java",
         "android/accounts/AuthenticatorException.java",
         "android/accounts/OperationCanceledException.java",
-        "android/annotation/AnimatorRes.java",
-        "android/annotation/AnimRes.java",
-        "android/annotation/AnyRes.java",
-        "android/annotation/ArrayRes.java",
-        "android/annotation/AttrRes.java",
-        "android/annotation/BoolRes.java",
-        "android/annotation/BroadcastBehavior.java",
-        "android/annotation/CallbackExecutor.java",
-        "android/annotation/CallSuper.java",
-        "android/annotation/CheckResult.java",
-        "android/annotation/ColorInt.java",
-        "android/annotation/ColorRes.java",
-        "android/annotation/DimenRes.java",
-        "android/annotation/DrawableRes.java",
-        "android/annotation/FontRes.java",
-        "android/annotation/FractionRes.java",
-        "android/annotation/IntDef.java",
-        "android/annotation/IntegerRes.java",
-        "android/annotation/IntRange.java",
-        "android/annotation/LayoutRes.java",
-        "android/annotation/NonNull.java",
-        "android/annotation/Nullable.java",
-        "android/annotation/PluralsRes.java",
-        "android/annotation/RawRes.java",
-        "android/annotation/RequiresPermission.java",
-        "android/annotation/SdkConstant.java",
-        "android/annotation/Size.java",
-        "android/annotation/StringDef.java",
-        "android/annotation/StringRes.java",
-        "android/annotation/StyleableRes.java",
-        "android/annotation/StyleRes.java",
-        "android/annotation/SuppressLint.java",
-        "android/annotation/SystemApi.java",
-        "android/annotation/SystemService.java",
-        "android/annotation/TestApi.java",
-        "android/annotation/UserIdInt.java",
-        "android/annotation/XmlRes.java",
         "android/app/Application.java",
         "android/app/IApplicationThread.aidl",
         "android/app/IServiceConnection.aidl",
@@ -123,7 +86,6 @@
         "android/util/AndroidException.java",
         "android/view/DisplayAdjustments.java",
         "android/view/ViewDebug.java",
-        "com/android/internal/annotations/VisibleForTesting.java",
     ],
     visibility: ["//frameworks/base/test-mock"],
 }
diff --git a/core/java/android/annotation/AnimRes.java b/core/java/android/annotation/AnimRes.java
deleted file mode 100644
index 56f8acf..0000000
--- a/core/java/android/annotation/AnimRes.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2013 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.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that an integer parameter, field or method return value is expected
- * to be an anim resource reference (e.g. {@link android.R.anim#fade_in}).
- *
- * {@hide}
- */
-@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface AnimRes {
-}
diff --git a/core/java/android/annotation/AnimatorRes.java b/core/java/android/annotation/AnimatorRes.java
deleted file mode 100644
index cd4c189..0000000
--- a/core/java/android/annotation/AnimatorRes.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2013 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.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that an integer parameter, field or method return value is expected
- * to be an animator resource reference (e.g. {@link android.R.animator#fade_in}).
- *
- * {@hide}
- */
-@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface AnimatorRes {
-}
diff --git a/core/java/android/annotation/AnyRes.java b/core/java/android/annotation/AnyRes.java
deleted file mode 100644
index 44411a0..0000000
--- a/core/java/android/annotation/AnyRes.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2013 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.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that an integer parameter, field or method return value is expected
- * to be a resource reference of any type. If the specific type is known, use
- * one of the more specific annotations instead, such as {@link StringRes} or
- * {@link DrawableRes}.
- *
- * {@hide}
- */
-@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface AnyRes {
-}
diff --git a/core/java/android/annotation/AnyThread.java b/core/java/android/annotation/AnyThread.java
deleted file mode 100644
index ee36a42..0000000
--- a/core/java/android/annotation/AnyThread.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2016 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.annotation;
-
-import static java.lang.annotation.ElementType.CONSTRUCTOR;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.ElementType.TYPE;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * Denotes that the annotated method can be called from any thread (e.g. it is
- * "thread safe".) If the annotated element is a class, then all methods in the
- * class can be called from any thread.
- * <p>
- * The main purpose of this method is to indicate that you believe a method can
- * be called from any thread; static tools can then check that nothing you call
- * from within this method or class have more strict threading requirements.
- * <p>
- * Example:
- *
- * <pre>
- * <code>
- *  &#64;AnyThread
- *  public void deliverResult(D data) { ... }
- * </code>
- * </pre>
- *
- * @memberDoc This method is safe to call from any thread.
- * @hide
- */
-@Retention(SOURCE)
-@Target({METHOD,CONSTRUCTOR,TYPE,PARAMETER})
-public @interface AnyThread {
-}
diff --git a/core/java/android/annotation/AppIdInt.java b/core/java/android/annotation/AppIdInt.java
deleted file mode 100644
index 29838dd..0000000
--- a/core/java/android/annotation/AppIdInt.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2016 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.annotation;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * Denotes that the annotated element is a multi-user application ID. This is
- * <em>not</em> the same as a UID.
- *
- * @hide
- */
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface AppIdInt {
-}
diff --git a/core/java/android/annotation/ArrayRes.java b/core/java/android/annotation/ArrayRes.java
deleted file mode 100644
index 1407af1..0000000
--- a/core/java/android/annotation/ArrayRes.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2013 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.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that an integer parameter, field or method return value is expected
- * to be an array resource reference (e.g. {@link android.R.array#phoneTypes}).
- *
- * {@hide}
- */
-@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface ArrayRes {
-}
diff --git a/core/java/android/annotation/AttrRes.java b/core/java/android/annotation/AttrRes.java
deleted file mode 100644
index 285b80c..0000000
--- a/core/java/android/annotation/AttrRes.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2013 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.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that an integer parameter, field or method return value is expected
- * to be an attribute reference (e.g. {@link android.R.attr#action}).
- *
- * {@hide}
- */
-@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface AttrRes {
-}
diff --git a/core/java/android/annotation/BinderThread.java b/core/java/android/annotation/BinderThread.java
deleted file mode 100644
index ca5e14c..0000000
--- a/core/java/android/annotation/BinderThread.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2015 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.annotation;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.CONSTRUCTOR;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.ElementType.TYPE;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that the annotated method should only be called on the binder thread.
- * If the annotated element is a class, then all methods in the class should be called
- * on the binder thread.
- * <p>
- * Example:
- * <pre><code>
- *  &#64;BinderThread
- *  public BeamShareData createBeamShareData() { ... }
- * </code></pre>
- *
- * {@hide}
- */
-@Retention(SOURCE)
-@Target({METHOD,CONSTRUCTOR,TYPE,PARAMETER})
-public @interface BinderThread {
-}
\ No newline at end of file
diff --git a/core/java/android/annotation/BoolRes.java b/core/java/android/annotation/BoolRes.java
deleted file mode 100644
index f50785b..0000000
--- a/core/java/android/annotation/BoolRes.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2013 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.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that an integer parameter, field or method return value is expected
- * to be a boolean resource reference.
- *
- * {@hide}
- */
-@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface BoolRes {
-}
diff --git a/core/java/android/annotation/BroadcastBehavior.java b/core/java/android/annotation/BroadcastBehavior.java
deleted file mode 100644
index 70d82cb..0000000
--- a/core/java/android/annotation/BroadcastBehavior.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2017 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.annotation;
-
-import android.content.Intent;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Description of how the annotated broadcast action behaves.
- *
- * @hide
- */
-@Target({ ElementType.FIELD })
-@Retention(RetentionPolicy.SOURCE)
-public @interface BroadcastBehavior {
-    /**
-     * This broadcast will only be delivered to an explicit target.
-     *
-     * @see Intent#setPackage(String)
-     * @see Intent#setComponent(android.content.ComponentName)
-     */
-    boolean explicitOnly() default false;
-
-    /**
-     * This broadcast will only be delivered to registered receivers.
-     *
-     * @see Intent#FLAG_RECEIVER_REGISTERED_ONLY
-     */
-    boolean registeredOnly() default false;
-
-    /**
-     * This broadcast will include all {@code AndroidManifest.xml} receivers
-     * regardless of process state.
-     *
-     * @see Intent#FLAG_RECEIVER_INCLUDE_BACKGROUND
-     */
-    boolean includeBackground() default false;
-
-    /**
-     * This broadcast is protected and can only be sent by the OS.
-     */
-    boolean protectedBroadcast() default false;
-}
diff --git a/core/java/android/annotation/BytesLong.java b/core/java/android/annotation/BytesLong.java
deleted file mode 100644
index f5e1a9c..0000000
--- a/core/java/android/annotation/BytesLong.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2017 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.annotation;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * @memberDoc Value is a non-negative number of bytes.
- * @paramDoc Value is a non-negative number of bytes.
- * @returnDoc Value is a non-negative number of bytes.
- * @hide
- */
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface BytesLong {
-}
diff --git a/core/java/android/annotation/CallSuper.java b/core/java/android/annotation/CallSuper.java
deleted file mode 100644
index c16b511..0000000
--- a/core/java/android/annotation/CallSuper.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2015 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.annotation;
-
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * Denotes that any overriding methods should invoke this method as well.
- * <p>
- * Example:
- *
- * <pre>
- * <code>
- *  &#64;CallSuper
- *  public abstract void onFocusLost();
- * </code>
- * </pre>
- *
- * @memberDoc If you override this method you <em>must</em> call through to the
- *            superclass implementation.
- * @hide
- */
-@Retention(SOURCE)
-@Target({METHOD})
-public @interface CallSuper {
-}
diff --git a/core/java/android/annotation/CallbackExecutor.java b/core/java/android/annotation/CallbackExecutor.java
deleted file mode 100644
index 4258f73..0000000
--- a/core/java/android/annotation/CallbackExecutor.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2017 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.annotation;
-
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-import java.util.concurrent.Executor;
-
-/**
- * @paramDoc Callback and listener events are dispatched through this
- *           {@link Executor}, providing an easy way to control which thread is
- *           used. To dispatch events through the main thread of your
- *           application, you can use
- *           {@link android.content.Context#getMainExecutor() Context.getMainExecutor()}.
- *           To dispatch events through a shared thread pool, you can use
- *           {@link android.os.AsyncTask#THREAD_POOL_EXECUTOR AsyncTask#THREAD_POOL_EXECUTOR}.
- * @hide
- */
-@Retention(SOURCE)
-@Target(PARAMETER)
-public @interface CallbackExecutor {
-}
diff --git a/core/java/android/annotation/CheckResult.java b/core/java/android/annotation/CheckResult.java
deleted file mode 100644
index 97d031a..0000000
--- a/core/java/android/annotation/CheckResult.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2015 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.annotation;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that the annotated method returns a result that it typically is
- * an error to ignore. This is usually used for methods that have no side effect,
- * so calling it without actually looking at the result usually means the developer
- * has misunderstood what the method does.
- * <p>
- * Example:
- * <pre>{@code
- *  public @CheckResult String trim(String s) { return s.trim(); }
- *  ...
- *  s.trim(); // this is probably an error
- *  s = s.trim(); // ok
- * }</pre>
- *
- * @hide
- */
-@Retention(SOURCE)
-@Target({METHOD})
-public @interface CheckResult {
-    /** Defines the name of the suggested method to use instead, if applicable (using
-     * the same signature format as javadoc.) If there is more than one possibility,
-     * list them all separated by commas.
-     * <p>
-     * For example, ProcessBuilder has a method named {@code redirectErrorStream()}
-     * which sounds like it might redirect the error stream. It does not. It's just
-     * a getter which returns whether the process builder will redirect the error stream,
-     * and to actually set it, you must call {@code redirectErrorStream(boolean)}.
-     * In that case, the method should be defined like this:
-     * <pre>
-     *  &#64;CheckResult(suggest="#redirectErrorStream(boolean)")
-     *  public boolean redirectErrorStream() { ... }
-     * </pre>
-     */
-    String suggest() default "";
-}
\ No newline at end of file
diff --git a/core/java/android/annotation/ColorInt.java b/core/java/android/annotation/ColorInt.java
deleted file mode 100644
index 4671b1b..0000000
--- a/core/java/android/annotation/ColorInt.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2015 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.annotation;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that the annotated element represents a packed color
- * int, {@code AARRGGBB}. If applied to an int array, every element
- * in the array represents a color integer.
- * <p>
- * Example:
- * <pre>{@code
- *  public abstract void setTextColor(@ColorInt int color);
- * }</pre>
- *
- * @hide
- */
-@Retention(SOURCE)
-@Target({PARAMETER,METHOD,LOCAL_VARIABLE,FIELD})
-public @interface ColorInt {
-}
\ No newline at end of file
diff --git a/core/java/android/annotation/ColorLong.java b/core/java/android/annotation/ColorLong.java
deleted file mode 100644
index 9b19c76..0000000
--- a/core/java/android/annotation/ColorLong.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2016 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.annotation;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * <p>Denotes that the annotated element represents a packed color
- * long. If applied to a long array, every element in the array
- * represents a color long. For more information on how colors
- * are packed in a long, please refer to the documentation of
- * the {@link android.graphics.Color} class.</p>
- *
- * <p>Example:</p>
- *
- * <pre>{@code
- *  public void setFillColor(@ColorLong long color);
- * }</pre>
- *
- * @see android.graphics.Color
- *
- * @hide
- */
-@Retention(SOURCE)
-@Target({PARAMETER,METHOD,LOCAL_VARIABLE,FIELD})
-public @interface ColorLong {
-}
diff --git a/core/java/android/annotation/ColorRes.java b/core/java/android/annotation/ColorRes.java
deleted file mode 100644
index 061faa0..0000000
--- a/core/java/android/annotation/ColorRes.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2013 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.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that an integer parameter, field or method return value is expected
- * to be a color resource reference (e.g. {@link android.R.color#black}).
- *
- * {@hide}
- */
-@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface ColorRes {
-}
diff --git a/core/java/android/annotation/Condemned.java b/core/java/android/annotation/Condemned.java
deleted file mode 100644
index 186409b..0000000
--- a/core/java/android/annotation/Condemned.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2017 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.annotation;
-
-import static java.lang.annotation.ElementType.CONSTRUCTOR;
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PACKAGE;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.ElementType.TYPE;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * A program element annotated &#64;Condemned is one that programmers are
- * blocked from using, typically because it's about to be completely destroyed.
- * <p>
- * This is a stronger version of &#64;Deprecated, and it's typically used to
- * mark APIs that only existed temporarily in a preview SDK, and which only
- * continue to exist temporarily to support binary compatibility.
- *
- * @hide
- */
-@Retention(SOURCE)
-@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
-public @interface Condemned {
-}
diff --git a/core/java/android/annotation/CurrentTimeMillisLong.java b/core/java/android/annotation/CurrentTimeMillisLong.java
deleted file mode 100644
index 355bb5a..0000000
--- a/core/java/android/annotation/CurrentTimeMillisLong.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2017 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.annotation;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * @memberDoc Value is a non-negative timestamp measured as the number of
- *            milliseconds since 1970-01-01T00:00:00Z.
- * @paramDoc Value is a non-negative timestamp measured as the number of
- *            milliseconds since 1970-01-01T00:00:00Z.
- * @returnDoc Value is a non-negative timestamp measured as the number of
- *            milliseconds since 1970-01-01T00:00:00Z.
- * @hide
- */
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface CurrentTimeMillisLong {
-}
diff --git a/core/java/android/annotation/CurrentTimeSecondsLong.java b/core/java/android/annotation/CurrentTimeSecondsLong.java
deleted file mode 100644
index 2b4ffd7..0000000
--- a/core/java/android/annotation/CurrentTimeSecondsLong.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2019 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.annotation;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * @memberDoc Value is a non-negative timestamp measured as the number of
- *            seconds since 1970-01-01T00:00:00Z.
- * @paramDoc Value is a non-negative timestamp measured as the number of
- *            seconds since 1970-01-01T00:00:00Z.
- * @returnDoc Value is a non-negative timestamp measured as the number of
- *            seconds since 1970-01-01T00:00:00Z.
- * @hide
- */
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface CurrentTimeSecondsLong {
-}
diff --git a/core/java/android/annotation/DimenRes.java b/core/java/android/annotation/DimenRes.java
deleted file mode 100644
index 02ae00c..0000000
--- a/core/java/android/annotation/DimenRes.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2013 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.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that an integer parameter, field or method return value is expected
- * to be a dimension resource reference (e.g. {@link android.R.dimen#app_icon_size}).
- *
- * {@hide}
- */
-@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface DimenRes {
-}
diff --git a/core/java/android/annotation/Dimension.java b/core/java/android/annotation/Dimension.java
deleted file mode 100644
index 5f705ad5..0000000
--- a/core/java/android/annotation/Dimension.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2016 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.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that a numeric parameter, field or method return value is expected
- * to represent a dimension.
- *
- * {@hide}
- */
-@Documented
-@Retention(SOURCE)
-@Target({METHOD,PARAMETER,FIELD,LOCAL_VARIABLE,ANNOTATION_TYPE})
-public @interface Dimension {
-    @Unit
-    int unit() default PX;
-
-    int DP = 0;
-    int PX = 1;
-    int SP = 2;
-
-    @IntDef({PX, DP, SP})
-    @Retention(SOURCE)
-    @interface Unit {}
-}
diff --git a/core/java/android/annotation/DrawableRes.java b/core/java/android/annotation/DrawableRes.java
deleted file mode 100644
index ebefa1d..0000000
--- a/core/java/android/annotation/DrawableRes.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2013 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.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that an integer parameter, field or method return value is expected
- * to be a drawable resource reference (e.g. {@link android.R.attr#alertDialogIcon}).
- *
- * {@hide}
- */
-@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface DrawableRes {
-}
diff --git a/core/java/android/annotation/DurationMillisLong.java b/core/java/android/annotation/DurationMillisLong.java
deleted file mode 100644
index ce77532..0000000
--- a/core/java/android/annotation/DurationMillisLong.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2017 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.annotation;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * @memberDoc Value is a non-negative duration in milliseconds.
- * @paramDoc Value is a non-negative duration in milliseconds.
- * @returnDoc Value is a non-negative duration in milliseconds.
- * @hide
- */
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface DurationMillisLong {
-}
diff --git a/core/java/android/annotation/ElapsedRealtimeLong.java b/core/java/android/annotation/ElapsedRealtimeLong.java
deleted file mode 100644
index f77ff72..0000000
--- a/core/java/android/annotation/ElapsedRealtimeLong.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2017 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.annotation;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import android.os.SystemClock;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * @memberDoc Value is a non-negative timestamp in the
- *            {@link SystemClock#elapsedRealtime()} time base.
- * @paramDoc Value is a non-negative timestamp in the
- *           {@link SystemClock#elapsedRealtime()} time base.
- * @returnDoc Value is a non-negative timestamp in the
- *            {@link SystemClock#elapsedRealtime()} time base.
- * @hide
- */
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface ElapsedRealtimeLong {
-}
diff --git a/core/java/android/annotation/FloatRange.java b/core/java/android/annotation/FloatRange.java
deleted file mode 100644
index 05b51680..0000000
--- a/core/java/android/annotation/FloatRange.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2015 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.annotation;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that the annotated element should be a float or double in the given range
- * <p>
- * Example:
- * <pre><code>
- *  &#64;FloatRange(from=0.0,to=1.0)
- *  public float getAlpha() {
- *      ...
- *  }
- * </code></pre>
- *
- * @hide
- */
-@Retention(SOURCE)
-@Target({METHOD,PARAMETER,FIELD,LOCAL_VARIABLE})
-public @interface FloatRange {
-    /** Smallest value. Whether it is inclusive or not is determined
-     * by {@link #fromInclusive} */
-    double from() default Double.NEGATIVE_INFINITY;
-    /** Largest value. Whether it is inclusive or not is determined
-     * by {@link #toInclusive} */
-    double to() default Double.POSITIVE_INFINITY;
-
-    /** Whether the from value is included in the range */
-    boolean fromInclusive() default true;
-
-    /** Whether the to value is included in the range */
-    boolean toInclusive() default true;
-}
\ No newline at end of file
diff --git a/core/java/android/annotation/FontRes.java b/core/java/android/annotation/FontRes.java
deleted file mode 100644
index dbacb58..0000000
--- a/core/java/android/annotation/FontRes.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2017 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.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that an integer parameter, field or method return value is expected
- * to be a Font resource reference (e.g. R.font.myfont).
- *
- * @hide
- */
-@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface FontRes {
-}
diff --git a/core/java/android/annotation/FractionRes.java b/core/java/android/annotation/FractionRes.java
deleted file mode 100644
index fd84d3e..0000000
--- a/core/java/android/annotation/FractionRes.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2013 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.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that an integer parameter, field or method return value is expected
- * to be a fraction resource reference.
- *
- * {@hide}
- */
-@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface FractionRes {
-}
diff --git a/core/java/android/annotation/HalfFloat.java b/core/java/android/annotation/HalfFloat.java
deleted file mode 100644
index 256008c..0000000
--- a/core/java/android/annotation/HalfFloat.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2016 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.annotation;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * <p>Denotes that the annotated element represents a half-precision floating point
- * value. Such values are stored in short data types and can be manipulated with
- * the {@link android.util.Half} class. If applied to an array of short, every
- * element in the array represents a half-precision float.</p>
- *
- * <p>Example:</p>
- *
- * <pre>{@code
- * public abstract void setPosition(@HalfFloat short x, @HalfFloat short y, @HalfFloat short z);
- * }</pre>
- *
- * @see android.util.Half
- * @see android.util.Half#toHalf(float)
- * @see android.util.Half#toFloat(short)
- *
- * @hide
- */
-@Retention(SOURCE)
-@Target({PARAMETER, METHOD, LOCAL_VARIABLE, FIELD})
-public @interface HalfFloat {
-}
diff --git a/core/java/android/annotation/Hide.java b/core/java/android/annotation/Hide.java
deleted file mode 100644
index c8e5a4a..0000000
--- a/core/java/android/annotation/Hide.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2019 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.annotation;
-
-import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
-import static java.lang.annotation.ElementType.CONSTRUCTOR;
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PACKAGE;
-import static java.lang.annotation.ElementType.TYPE;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Indicates that an API is hidden by default, in a similar fashion to the
- * <pre>@hide</pre> javadoc tag.
- *
- * <p>Note that, in order for this to work, metalava has to be invoked with
- * the flag {@code --hide-annotation android.annotation.Hide}.
- * @hide
- */
-@Target({TYPE, FIELD, METHOD, CONSTRUCTOR, ANNOTATION_TYPE, PACKAGE})
-@Retention(RetentionPolicy.CLASS)
-public @interface Hide {
-}
diff --git a/core/java/android/annotation/IdRes.java b/core/java/android/annotation/IdRes.java
deleted file mode 100644
index b286965..0000000
--- a/core/java/android/annotation/IdRes.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2013 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.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that an integer parameter, field or method return value is expected
- * to be an id resource reference (e.g. {@link android.R.id#copy}).
- *
- * {@hide}
- */
-@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface IdRes {
-}
diff --git a/core/java/android/annotation/IntDef.java b/core/java/android/annotation/IntDef.java
deleted file mode 100644
index f84a676..0000000
--- a/core/java/android/annotation/IntDef.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2013 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.annotation;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that the annotated element of integer type, represents
- * a logical type and that its value should be one of the explicitly
- * named constants. If the {@link #flag()} attribute is set to true,
- * multiple constants can be combined.
- * <p>
- * <pre><code>
- *  &#64;Retention(SOURCE)
- *  &#64;IntDef({NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS})
- *  public @interface NavigationMode {}
- *  public static final int NAVIGATION_MODE_STANDARD = 0;
- *  public static final int NAVIGATION_MODE_LIST = 1;
- *  public static final int NAVIGATION_MODE_TABS = 2;
- *  ...
- *  public abstract void setNavigationMode(@NavigationMode int mode);
- *  &#64;NavigationMode
- *  public abstract int getNavigationMode();
- * </code></pre>
- * For a flag, set the flag attribute:
- * <pre><code>
- *  &#64;IntDef(
- *      flag = true,
- *      value = {NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS})
- * </code></pre>
- *
- * @hide
- */
-@Retention(SOURCE)
-@Target({ANNOTATION_TYPE})
-public @interface IntDef {
-    /** Defines the constant prefix for this element */
-    String[] prefix() default {};
-    /** Defines the constant suffix for this element */
-    String[] suffix() default {};
-
-    /** Defines the allowed constants for this element */
-    int[] value() default {};
-
-    /** Defines whether the constants can be used as a flag, or just as an enum (the default) */
-    boolean flag() default false;
-}
diff --git a/core/java/android/annotation/IntRange.java b/core/java/android/annotation/IntRange.java
deleted file mode 100644
index c043e2d..0000000
--- a/core/java/android/annotation/IntRange.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2015 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.annotation;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that the annotated element should be an int or long in the given range
- * <p>
- * Example:
- * <pre><code>
- *  &#64;IntRange(from=0,to=255)
- *  public int getAlpha() {
- *      ...
- *  }
- * </code></pre>
- *
- * @hide
- */
-@Retention(SOURCE)
-@Target({METHOD,PARAMETER,FIELD,LOCAL_VARIABLE,ANNOTATION_TYPE})
-public @interface IntRange {
-    /** Smallest value, inclusive */
-    long from() default Long.MIN_VALUE;
-    /** Largest value, inclusive */
-    long to() default Long.MAX_VALUE;
-}
\ No newline at end of file
diff --git a/core/java/android/annotation/IntegerRes.java b/core/java/android/annotation/IntegerRes.java
deleted file mode 100644
index 5313f4a..0000000
--- a/core/java/android/annotation/IntegerRes.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2013 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.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that an integer parameter, field or method return value is expected
- * to be an integer resource reference (e.g. {@link android.R.integer#config_shortAnimTime}).
- *
- * {@hide}
- */
-@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface IntegerRes {
-}
diff --git a/core/java/android/annotation/InterpolatorRes.java b/core/java/android/annotation/InterpolatorRes.java
deleted file mode 100644
index 8877a5f..0000000
--- a/core/java/android/annotation/InterpolatorRes.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2013 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.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that an integer parameter, field or method return value is expected
- * to be an interpolator resource reference (e.g. {@link android.R.interpolator#cycle}).
- *
- * {@hide}
- */
-@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface InterpolatorRes {
-}
diff --git a/core/java/android/annotation/LayoutRes.java b/core/java/android/annotation/LayoutRes.java
deleted file mode 100644
index 15ba86f..0000000
--- a/core/java/android/annotation/LayoutRes.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2013 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.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that an integer parameter, field or method return value is expected
- * to be a layout resource reference (e.g. {@link android.R.layout#list_content}).
- *
- * {@hide}
- */
-@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface LayoutRes {
-}
diff --git a/core/java/android/annotation/LongDef.java b/core/java/android/annotation/LongDef.java
deleted file mode 100644
index 8723eef8..0000000
--- a/core/java/android/annotation/LongDef.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2017 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.annotation;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that the annotated long element represents
- * a logical type and that its value should be one of the explicitly
- * named constants. If the {@link #flag()} attribute is set to true,
- * multiple constants can be combined.
- * <p>
- * <pre><code>
- *  &#64;Retention(SOURCE)
- *  &#64;LongDef({NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS})
- *  public @interface NavigationMode {}
- *  public static final long NAVIGATION_MODE_STANDARD = 0;
- *  public static final long NAVIGATION_MODE_LIST = 1;
- *  public static final long NAVIGATION_MODE_TABS = 2;
- *  ...
- *  public abstract void setNavigationMode(@NavigationMode long mode);
- *  &#64;NavigationMode
- *  public abstract long getNavigationMode();
- * </code></pre>
- * For a flag, set the flag attribute:
- * <pre><code>
- *  &#64;LongDef(
- *      flag = true,
- *      value = {NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS})
- * </code></pre>
- *
- * @hide
- */
-@Retention(SOURCE)
-@Target({ANNOTATION_TYPE})
-public @interface LongDef {
-    /** Defines the constant prefix for this element */
-    String[] prefix() default "";
-
-    /** Defines the allowed constants for this element */
-    long[] value() default {};
-
-    /** Defines whether the constants can be used as a flag, or just as an enum (the default) */
-    boolean flag() default false;
-}
diff --git a/core/java/android/annotation/MainThread.java b/core/java/android/annotation/MainThread.java
deleted file mode 100644
index a070246..0000000
--- a/core/java/android/annotation/MainThread.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2015 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.annotation;
-
-import static java.lang.annotation.ElementType.CONSTRUCTOR;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.ElementType.TYPE;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * Denotes that the annotated method should only be called on the main thread.
- * If the annotated element is a class, then all methods in the class should be
- * called on the main thread.
- * <p>
- * Example:
- *
- * <pre>
- * <code>
- *  &#64;MainThread
- *  public void deliverResult(D data) { ... }
- * </code>
- * </pre>
- *
- * @memberDoc This method must be called from the main thread of your app.
- * @hide
- */
-@Retention(SOURCE)
-@Target({METHOD,CONSTRUCTOR,TYPE,PARAMETER})
-public @interface MainThread {
-}
diff --git a/core/java/android/annotation/MenuRes.java b/core/java/android/annotation/MenuRes.java
deleted file mode 100644
index b6dcc46..0000000
--- a/core/java/android/annotation/MenuRes.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2013 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.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that an integer parameter, field or method return value is expected
- * to be a menu resource reference.
- *
- * {@hide}
- */
-@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface MenuRes {
-}
diff --git a/core/java/android/annotation/NavigationRes.java b/core/java/android/annotation/NavigationRes.java
deleted file mode 100644
index 3af5ecf..0000000
--- a/core/java/android/annotation/NavigationRes.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2017 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.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that an integer parameter, field or method return value is expected
- * to be a navigation resource reference (e.g. {@code R.navigation.flow}).
- *
- * {@hide}
- */
-@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface NavigationRes {
-}
diff --git a/core/java/android/annotation/NonNull.java b/core/java/android/annotation/NonNull.java
deleted file mode 100644
index 20472ba..0000000
--- a/core/java/android/annotation/NonNull.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2013 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.annotation;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * Denotes that a parameter, field or method return value can never be null.
- * <p>
- * This is a marker annotation and it has no specific attributes.
- *
- * @paramDoc This value cannot be {@code null}.
- * @returnDoc This value cannot be {@code null}.
- * @hide
- */
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface NonNull {
-}
diff --git a/core/java/android/annotation/Nullable.java b/core/java/android/annotation/Nullable.java
deleted file mode 100644
index b8473e7..0000000
--- a/core/java/android/annotation/Nullable.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2013 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.annotation;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * Denotes that a parameter, field or method return value can be null.
- * <p>
- * When decorating a method call parameter, this denotes that the parameter can
- * legitimately be null and the method will gracefully deal with it. Typically
- * used on optional parameters.
- * <p>
- * When decorating a method, this denotes the method might legitimately return
- * null.
- * <p>
- * This is a marker annotation and it has no specific attributes.
- *
- * @paramDoc This value may be {@code null}.
- * @returnDoc This value may be {@code null}.
- * @hide
- */
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface Nullable {
-}
diff --git a/core/java/android/annotation/OWNERS b/core/java/android/annotation/OWNERS
deleted file mode 100644
index e1ef544..0000000
--- a/core/java/android/annotation/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-tnorbye@google.com
-aurimas@google.com
-per-file UnsupportedAppUsage.java = mathewi@google.com, satayev@google.com, andreionea@google.com
diff --git a/core/java/android/annotation/PluralsRes.java b/core/java/android/annotation/PluralsRes.java
deleted file mode 100644
index 31ac729..0000000
--- a/core/java/android/annotation/PluralsRes.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2013 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.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that an integer parameter, field or method return value is expected
- * to be a plurals resource reference.
- *
- * {@hide}
- */
-@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface PluralsRes {
-}
diff --git a/core/java/android/annotation/Px.java b/core/java/android/annotation/Px.java
deleted file mode 100644
index cec7f80..0000000
--- a/core/java/android/annotation/Px.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2016 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.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that a numeric parameter, field or method return value is expected
- * to represent a pixel dimension.
- *
- * @memberDoc This units of this value are pixels.
- * @paramDoc This units of this value are pixels.
- * @returnDoc This units of this value are pixels.
- * {@hide}
- */
-@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD, LOCAL_VARIABLE})
-@Dimension(unit = Dimension.PX)
-public @interface Px {
-}
diff --git a/core/java/android/annotation/RawRes.java b/core/java/android/annotation/RawRes.java
deleted file mode 100644
index 39970b3..0000000
--- a/core/java/android/annotation/RawRes.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2013 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.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that an integer parameter, field or method return value is expected
- * to be a raw resource reference.
- *
- * {@hide}
- */
-@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface RawRes {
-}
diff --git a/core/java/android/annotation/RequiresFeature.java b/core/java/android/annotation/RequiresFeature.java
deleted file mode 100644
index 08861d4..0000000
--- a/core/java/android/annotation/RequiresFeature.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2018 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.annotation;
-
-import static java.lang.annotation.ElementType.CONSTRUCTOR;
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.TYPE;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import android.content.pm.PackageManager;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * Denotes that the annotated element requires one or more device features. This
- * is used to auto-generate documentation.
- *
- * @hide
- */
-@Retention(SOURCE)
-@Target({TYPE,FIELD,METHOD,CONSTRUCTOR})
-public @interface RequiresFeature {
-    /**
-     * The name of the device feature that is required.
-     */
-    String value();
-
-    /**
-     * Defines the name of the method that should be called to check whether the feature is
-     * available, using the same signature format as javadoc. The feature checking method can have
-     * multiple parameters, but the feature name parameter must be of type String and must also be
-     * the first String-type parameter.
-     * <p>
-     * By default, the enforcement is {@link PackageManager#hasSystemFeature(String)}.
-     */
-    String enforcement() default("android.content.pm.PackageManager#hasSystemFeature");
-}
diff --git a/core/java/android/annotation/RequiresPermission.java b/core/java/android/annotation/RequiresPermission.java
deleted file mode 100644
index 1d89e31..0000000
--- a/core/java/android/annotation/RequiresPermission.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2015 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.annotation;
-
-import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
-import static java.lang.annotation.ElementType.CONSTRUCTOR;
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * Denotes that the annotated element requires (or may require) one or more permissions.
- * <p/>
- * Example of requiring a single permission:
- * <pre>{@code
- *   {@literal @}RequiresPermission(Manifest.permission.SET_WALLPAPER)
- *   public abstract void setWallpaper(Bitmap bitmap) throws IOException;
- *
- *   {@literal @}RequiresPermission(ACCESS_COARSE_LOCATION)
- *   public abstract Location getLastKnownLocation(String provider);
- * }</pre>
- * Example of requiring at least one permission from a set:
- * <pre>{@code
- *   {@literal @}RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
- *   public abstract Location getLastKnownLocation(String provider);
- * }</pre>
- * Example of requiring multiple permissions:
- * <pre>{@code
- *   {@literal @}RequiresPermission(allOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
- *   public abstract Location getLastKnownLocation(String provider);
- * }</pre>
- * Example of requiring separate read and write permissions for a content provider:
- * <pre>{@code
- *   {@literal @}RequiresPermission.Read(@RequiresPermission(READ_HISTORY_BOOKMARKS))
- *   {@literal @}RequiresPermission.Write(@RequiresPermission(WRITE_HISTORY_BOOKMARKS))
- *   public static final Uri BOOKMARKS_URI = Uri.parse("content://browser/bookmarks");
- * }</pre>
- * <p>
- * When specified on a parameter, the annotation indicates that the method requires
- * a permission which depends on the value of the parameter. For example, consider
- * {@link android.app.Activity#startActivity(android.content.Intent)
- * Activity#startActivity(Intent)}:
- * <pre>{@code
- *   public void startActivity(@RequiresPermission Intent intent) { ... }
- * }</pre>
- * Notice how there are no actual permission names listed in the annotation. The actual
- * permissions required will depend on the particular intent passed in. For example,
- * the code may look like this:
- * <pre>{@code
- *   Intent intent = new Intent(Intent.ACTION_CALL);
- *   startActivity(intent);
- * }</pre>
- * and the actual permission requirement for this particular intent is described on
- * the Intent name itself:
- * <pre>{@code
- *   {@literal @}RequiresPermission(Manifest.permission.CALL_PHONE)
- *   public static final String ACTION_CALL = "android.intent.action.CALL";
- * }</pre>
- *
- * @hide
- */
-@Retention(SOURCE)
-@Target({ANNOTATION_TYPE,METHOD,CONSTRUCTOR,FIELD,PARAMETER})
-public @interface RequiresPermission {
-    /**
-     * The name of the permission that is required, if precisely one permission
-     * is required. If more than one permission is required, specify either
-     * {@link #allOf()} or {@link #anyOf()} instead.
-     * <p>
-     * If specified, {@link #anyOf()} and {@link #allOf()} must both be null.
-     */
-    String value() default "";
-
-    /**
-     * Specifies a list of permission names that are all required.
-     * <p>
-     * If specified, {@link #anyOf()} and {@link #value()} must both be null.
-     */
-    String[] allOf() default {};
-
-    /**
-     * Specifies a list of permission names where at least one is required
-     * <p>
-     * If specified, {@link #allOf()} and {@link #value()} must both be null.
-     */
-    String[] anyOf() default {};
-
-    /**
-     * If true, the permission may not be required in all cases (e.g. it may only be
-     * enforced on certain platforms, or for certain call parameters, etc.
-     */
-    boolean conditional() default false;
-
-    /**
-     * Specifies that the given permission is required for read operations.
-     * <p>
-     * When specified on a parameter, the annotation indicates that the method requires
-     * a permission which depends on the value of the parameter (and typically
-     * the corresponding field passed in will be one of a set of constants which have
-     * been annotated with a <code>@RequiresPermission</code> annotation.)
-     */
-    @Target({FIELD, METHOD, PARAMETER})
-    @interface Read {
-        RequiresPermission value() default @RequiresPermission;
-    }
-
-    /**
-     * Specifies that the given permission is required for write operations.
-     * <p>
-     * When specified on a parameter, the annotation indicates that the method requires
-     * a permission which depends on the value of the parameter (and typically
-     * the corresponding field passed in will be one of a set of constants which have
-     * been annotated with a <code>@RequiresPermission</code> annotation.)
-     */
-    @Target({FIELD, METHOD, PARAMETER})
-    @interface Write {
-        RequiresPermission value() default @RequiresPermission;
-    }
-}
diff --git a/core/java/android/annotation/SdkConstant.java b/core/java/android/annotation/SdkConstant.java
deleted file mode 100644
index 0a53186..0000000
--- a/core/java/android/annotation/SdkConstant.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2008 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.annotation;
-
-import java.lang.annotation.Target;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Indicates a constant field value should be exported to be used in the SDK tools.
- * @hide
- */
-@Target({ ElementType.FIELD })
-@Retention(RetentionPolicy.SOURCE)
-public @interface SdkConstant {
-    public static enum SdkConstantType {
-        ACTIVITY_INTENT_ACTION, BROADCAST_INTENT_ACTION, SERVICE_ACTION, INTENT_CATEGORY, FEATURE;
-    }
-
-    SdkConstantType value();
-}
diff --git a/core/java/android/annotation/Size.java b/core/java/android/annotation/Size.java
deleted file mode 100644
index 7c3e70f..0000000
--- a/core/java/android/annotation/Size.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2015 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.annotation;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that the annotated element should have a given size or length.
- * Note that "-1" means "unset". Typically used with a parameter or
- * return value of type array or collection.
- * <p>
- * Example:
- * <pre>{@code
- *  public void getLocationInWindow(@Size(2) int[] location) {
- *      ...
- *  }
- * }</pre>
- *
- * @hide
- */
-@Retention(SOURCE)
-@Target({PARAMETER,LOCAL_VARIABLE,METHOD,FIELD})
-public @interface Size {
-    /** An exact size (or -1 if not specified) */
-    long value() default -1;
-    /** A minimum size, inclusive */
-    long min() default Long.MIN_VALUE;
-    /** A maximum size, inclusive */
-    long max() default Long.MAX_VALUE;
-    /** The size must be a multiple of this factor */
-    long multiple() default 1;
-}
\ No newline at end of file
diff --git a/core/java/android/annotation/StringDef.java b/core/java/android/annotation/StringDef.java
deleted file mode 100644
index a37535b..0000000
--- a/core/java/android/annotation/StringDef.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2013 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.annotation;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that the annotated String element, represents a logical
- * type and that its value should be one of the explicitly named constants.
- * <p>
- * Example:
- * <pre><code>
- *  &#64;Retention(SOURCE)
- *  &#64;StringDef({
- *     POWER_SERVICE,
- *     WINDOW_SERVICE,
- *     LAYOUT_INFLATER_SERVICE
- *  })
- *  public @interface ServiceName {}
- *  public static final String POWER_SERVICE = "power";
- *  public static final String WINDOW_SERVICE = "window";
- *  public static final String LAYOUT_INFLATER_SERVICE = "layout_inflater";
- *  ...
- *  public abstract Object getSystemService(@ServiceName String name);
- * </code></pre>
- *
- * @hide
- */
-@Retention(SOURCE)
-@Target({ANNOTATION_TYPE})
-public @interface StringDef {
-    /** Defines the constant prefix for this element */
-    String[] prefix() default {};
-    /** Defines the constant suffix for this element */
-    String[] suffix() default {};
-
-    /** Defines the allowed constants for this element */
-    String[] value() default {};
-}
diff --git a/core/java/android/annotation/StringRes.java b/core/java/android/annotation/StringRes.java
deleted file mode 100644
index 190b68a..0000000
--- a/core/java/android/annotation/StringRes.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2013 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.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that an integer parameter, field or method return value is expected
- * to be a String resource reference (e.g. {@link android.R.string#ok}).
- *
- * {@hide}
- */
-@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface StringRes {
-}
diff --git a/core/java/android/annotation/StyleRes.java b/core/java/android/annotation/StyleRes.java
deleted file mode 100644
index 4453b8d..0000000
--- a/core/java/android/annotation/StyleRes.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2013 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.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that a integer parameter, field or method return value is expected
- * to be a style resource reference (e.g. {@link android.R.style#TextAppearance}).
- *
- * {@hide}
- */
-@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface StyleRes {
-}
diff --git a/core/java/android/annotation/StyleableRes.java b/core/java/android/annotation/StyleableRes.java
deleted file mode 100644
index 3c1895e..0000000
--- a/core/java/android/annotation/StyleableRes.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2013 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.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that a integer parameter, field or method return value is expected
- * to be a styleable resource reference (e.g. {@link android.R.styleable#TextView_text}).
- *
- * {@hide}
- */
-@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface StyleableRes {
-}
diff --git a/core/java/android/annotation/SuppressAutoDoc.java b/core/java/android/annotation/SuppressAutoDoc.java
deleted file mode 100644
index e34e03b..0000000
--- a/core/java/android/annotation/SuppressAutoDoc.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2017 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.annotation;
-
-import static java.lang.annotation.ElementType.CONSTRUCTOR;
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.ElementType.TYPE;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * Denotes that any automatically generated documentation should be suppressed
- * for the annotated method, parameter, or field.
- *
- * @hide
- */
-@Retention(SOURCE)
-@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
-public @interface SuppressAutoDoc {
-}
diff --git a/core/java/android/annotation/SuppressLint.java b/core/java/android/annotation/SuppressLint.java
deleted file mode 100644
index 2d3456b..0000000
--- a/core/java/android/annotation/SuppressLint.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2012 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.annotation;
-
-import static java.lang.annotation.ElementType.CONSTRUCTOR;
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.ElementType.TYPE;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/** Indicates that Lint should ignore the specified warnings for the annotated element. */
-@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
-@Retention(RetentionPolicy.CLASS)
-public @interface SuppressLint {
-    /**
-     * The set of warnings (identified by the lint issue id) that should be
-     * ignored by lint. It is not an error to specify an unrecognized name.
-     */
-    String[] value();
-}
diff --git a/core/java/android/annotation/SystemApi.java b/core/java/android/annotation/SystemApi.java
deleted file mode 100644
index a468439..0000000
--- a/core/java/android/annotation/SystemApi.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2014 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.annotation;
-
-import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
-import static java.lang.annotation.ElementType.CONSTRUCTOR;
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PACKAGE;
-import static java.lang.annotation.ElementType.TYPE;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Indicates an API is exposed for use by bundled system applications.
- * <p>
- * These APIs are not guaranteed to remain consistent release-to-release,
- * and are not for use by apps linking against the Android SDK.
- * </p><p>
- * This annotation should only appear on API that is already marked <pre>@hide</pre>.
- * </p>
- *
- * @hide
- */
-@Target({TYPE, FIELD, METHOD, CONSTRUCTOR, ANNOTATION_TYPE, PACKAGE})
-@Retention(RetentionPolicy.RUNTIME)
-public @interface SystemApi {
-    enum Client {
-        /**
-         * Specifies that the intended clients of a SystemApi are privileged apps.
-         * This is the default value for {@link #client}.
-         */
-        PRIVILEGED_APPS,
-
-        /**
-         * Specifies that the intended clients of a SystemApi are used by classes in
-         * <pre>BOOTCLASSPATH</pre> in mainline modules. Mainline modules can also expose
-         * this type of system APIs too when they're used only by the non-updatable
-         * platform code.
-         */
-        MODULE_LIBRARIES,
-
-        /**
-         * Specifies that the system API is available only in the system server process.
-         * Use this to expose APIs from code loaded by the system server process <em>but</em>
-         * not in <pre>BOOTCLASSPATH</pre>.
-         */
-        SYSTEM_SERVER
-    }
-
-    /**
-     * The intended client of this SystemAPI.
-     */
-    Client client() default android.annotation.SystemApi.Client.PRIVILEGED_APPS;
-
-    /**
-     * Container for {@link SystemApi} that allows it to be applied repeatedly to types.
-     */
-    @Retention(RetentionPolicy.RUNTIME)
-    @Target(TYPE)
-    @interface Container {
-        SystemApi[] value();
-    }
-}
diff --git a/core/java/android/annotation/SystemService.java b/core/java/android/annotation/SystemService.java
deleted file mode 100644
index c05c1ba..0000000
--- a/core/java/android/annotation/SystemService.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2017 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.annotation;
-
-import static java.lang.annotation.ElementType.TYPE;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * Description of a system service available through
- * {@link android.content.Context#getSystemService(Class)}. This is used to auto-generate
- * documentation explaining how to obtain a reference to the service.
- *
- * @hide
- */
-@Retention(SOURCE)
-@Target(TYPE)
-public @interface SystemService {
-    /**
-     * The string name of the system service that can be passed to
-     * {@link android.content.Context#getSystemService(String)}.
-     *
-     * @see android.content.Context#getSystemServiceName(Class)
-     */
-    String value();
-}
diff --git a/core/java/android/annotation/TargetApi.java b/core/java/android/annotation/TargetApi.java
deleted file mode 100644
index 975318e..0000000
--- a/core/java/android/annotation/TargetApi.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2012 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.annotation;
-
-import static java.lang.annotation.ElementType.CONSTRUCTOR;
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.TYPE;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/** Indicates that Lint should treat this type as targeting a given API level, no matter what the
-    project target is. */
-@Target({TYPE, METHOD, CONSTRUCTOR, FIELD})
-@Retention(RetentionPolicy.CLASS)
-public @interface TargetApi {
-    /**
-     * This sets the target api level for the type..
-     */
-    int value();
-}
diff --git a/core/java/android/annotation/TestApi.java b/core/java/android/annotation/TestApi.java
deleted file mode 100644
index 0e9ed37..0000000
--- a/core/java/android/annotation/TestApi.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2015 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.annotation;
-
-import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
-import static java.lang.annotation.ElementType.CONSTRUCTOR;
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PACKAGE;
-import static java.lang.annotation.ElementType.TYPE;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Indicates an API is exposed for use by CTS.
- * <p>
- * These APIs are not guaranteed to remain consistent release-to-release,
- * and are not for use by apps linking against the Android SDK.
- * </p>
- *
- * @hide
- */
-@Target({TYPE, FIELD, METHOD, CONSTRUCTOR, ANNOTATION_TYPE, PACKAGE})
-@Retention(RetentionPolicy.SOURCE)
-public @interface TestApi {
-}
diff --git a/core/java/android/annotation/TransitionRes.java b/core/java/android/annotation/TransitionRes.java
deleted file mode 100644
index 06bac74..0000000
--- a/core/java/android/annotation/TransitionRes.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2015 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.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that an integer parameter, field or method return value is expected
- * to be a transition resource reference.
- *
- * {@hide}
- */
-@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface TransitionRes {
-}
diff --git a/core/java/android/annotation/UiThread.java b/core/java/android/annotation/UiThread.java
deleted file mode 100644
index 6d7eedc..0000000
--- a/core/java/android/annotation/UiThread.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2015 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.annotation;
-
-import static java.lang.annotation.ElementType.CONSTRUCTOR;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.ElementType.TYPE;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import android.os.Looper;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * Denotes that the annotated method or constructor should only be called on the
- * UI thread. If the annotated element is a class, then all methods in the class
- * should be called on the UI thread.
- * <p>
- * Example:
- *
- * <pre>
- * <code>
- *  &#64;UiThread
- *  public abstract void setText(@NonNull String text) { ... }
- * </code>
- * </pre>
- *
- * @memberDoc This method must be called on the thread that originally created
- *            this UI element. This is typically the
- *            {@linkplain Looper#getMainLooper() main thread} of your app.
- * @hide
- */
-@Retention(SOURCE)
-@Target({METHOD,CONSTRUCTOR,TYPE,PARAMETER})
-public @interface UiThread {
-}
diff --git a/core/java/android/annotation/UserHandleAware.java b/core/java/android/annotation/UserHandleAware.java
deleted file mode 100644
index 7d3d20b..0000000
--- a/core/java/android/annotation/UserHandleAware.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2019 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.annotation;
-
-import static java.lang.annotation.ElementType.CONSTRUCTOR;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PACKAGE;
-import static java.lang.annotation.ElementType.TYPE;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * Indicates an API that uses {@code context.getUser} or {@code context.getUserId}
- * to operate across users (as the user associated with the context)
- * <p>
- * To create a {@link android.content.Context} associated with a different user,
- *  use {@link android.content.Context#createContextAsUser} or
- *  {@link android.content.Context#createPackageContextAsUser}
- * <p>
- * Example:
- * <pre>{@code
- * {@literal @}UserHandleAware
- * public abstract PackageInfo getPackageInfo({@literal @}NonNull String packageName,
- *      {@literal @}PackageInfoFlags int flags) throws NameNotFoundException;
- * }</pre>
- *
- * @memberDoc This method uses {@linkplain android.content.Context#getUser}
- *            or {@linkplain android.content.Context#getUserId} to execute across users.
- * @hide
- */
-@Retention(SOURCE)
-@Target({TYPE, METHOD, CONSTRUCTOR, PACKAGE})
-public @interface UserHandleAware {
-}
diff --git a/core/java/android/annotation/UserIdInt.java b/core/java/android/annotation/UserIdInt.java
deleted file mode 100644
index 7b9ce25..0000000
--- a/core/java/android/annotation/UserIdInt.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2016 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.annotation;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * Denotes that the annotated element is a multi-user user ID. This is
- * <em>not</em> the same as a UID.
- *
- * @hide
- */
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface UserIdInt {
-}
diff --git a/core/java/android/annotation/Widget.java b/core/java/android/annotation/Widget.java
deleted file mode 100644
index 6756cd7..0000000
--- a/core/java/android/annotation/Widget.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2008 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.annotation;
-
-import java.lang.annotation.Target;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Indicates a class is a widget usable by application developers to create UI.
- * <p>
- * This must be used in cases where:
- * <ul>
- * <li>The widget is not in the package <code>android.widget</code></li>
- * <li>The widget extends <code>android.view.ViewGroup</code></li>
- * </ul>
- * @hide
- */
-@Target({ ElementType.TYPE })
-@Retention(RetentionPolicy.SOURCE)
-public @interface Widget {
-}
diff --git a/core/java/android/annotation/WorkerThread.java b/core/java/android/annotation/WorkerThread.java
deleted file mode 100644
index 8c2a4d3..0000000
--- a/core/java/android/annotation/WorkerThread.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2015 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.annotation;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.CONSTRUCTOR;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.ElementType.TYPE;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that the annotated method should only be called on a worker thread.
- * If the annotated element is a class, then all methods in the class should be
- * called on a worker thread.
- * <p>
- * Example:
- *
- * <pre>
- * <code>
- *  &#64;WorkerThread
- *  protected abstract FilterResults performFiltering(CharSequence constraint);
- * </code>
- * </pre>
- *
- * @memberDoc This method may take several seconds to complete, so it should
- *            only be called from a worker thread.
- * @hide
- */
-@Retention(SOURCE)
-@Target({METHOD,CONSTRUCTOR,TYPE,PARAMETER})
-public @interface WorkerThread {
-}
diff --git a/core/java/android/annotation/XmlRes.java b/core/java/android/annotation/XmlRes.java
deleted file mode 100644
index 5fb8a4a..0000000
--- a/core/java/android/annotation/XmlRes.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2013 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.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that an integer parameter, field or method return value is expected
- * to be an XML resource reference.
- *
- * {@hide}
- */
-@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface XmlRes {
-}
diff --git a/core/java/android/app/AppCompatCallbacks.java b/core/java/android/app/AppCompatCallbacks.java
index 28a21f7..134cef5 100644
--- a/core/java/android/app/AppCompatCallbacks.java
+++ b/core/java/android/app/AppCompatCallbacks.java
@@ -28,7 +28,7 @@
  *
  * @hide
  */
-public final class AppCompatCallbacks extends Compatibility.Callbacks {
+public final class AppCompatCallbacks implements Compatibility.BehaviorChangeDelegate {
     private final long[] mDisabledChanges;
     private final ChangeReporter mChangeReporter;
 
@@ -38,7 +38,7 @@
      * @param disabledChanges Set of compatibility changes that are disabled for this process.
      */
     public static void install(long[] disabledChanges) {
-        Compatibility.setCallbacks(new AppCompatCallbacks(disabledChanges));
+        Compatibility.setBehaviorChangeDelegate(new AppCompatCallbacks(disabledChanges));
     }
 
     private AppCompatCallbacks(long[] disabledChanges) {
@@ -48,11 +48,11 @@
                 ChangeReporter.SOURCE_APP_PROCESS);
     }
 
-    protected void reportChange(long changeId) {
+    public void onChangeReported(long changeId) {
         reportChange(changeId, ChangeReporter.STATE_LOGGED);
     }
 
-    protected boolean isChangeEnabled(long changeId) {
+    public boolean isChangeEnabled(long changeId) {
         if (Arrays.binarySearch(mDisabledChanges, changeId) < 0) {
             // Not present in the disabled array
             reportChange(changeId, ChangeReporter.STATE_ENABLED);
diff --git a/core/java/android/app/admin/OWNERS b/core/java/android/app/admin/OWNERS
index 8462cbe..6acbef2 100644
--- a/core/java/android/app/admin/OWNERS
+++ b/core/java/android/app/admin/OWNERS
@@ -3,9 +3,9 @@
 # Android Enterprise team
 rubinxu@google.com
 sandness@google.com
-eranm@google.com
 alexkershaw@google.com
 pgrafov@google.com
 
 # Emeritus
 yamasani@google.com
+eranm@google.com
diff --git a/core/java/android/app/compat/CompatChanges.java b/core/java/android/app/compat/CompatChanges.java
index 74e1ece..8ca43c4 100644
--- a/core/java/android/app/compat/CompatChanges.java
+++ b/core/java/android/app/compat/CompatChanges.java
@@ -26,9 +26,11 @@
 import android.os.UserHandle;
 
 import com.android.internal.compat.CompatibilityOverrideConfig;
+import com.android.internal.compat.CompatibilityOverridesToRemoveConfig;
 import com.android.internal.compat.IPlatformCompat;
 
 import java.util.Map;
+import java.util.Set;
 
 /**
  * CompatChanges APIs - to be used by platform code only (including mainline
@@ -98,15 +100,19 @@
     }
 
     /**
-     * Set an app compat override for a given package. This will check whether the caller is allowed
+     * Adds app compat overrides for a given package. This will check whether the caller is allowed
      * to perform this operation on the given apk and build. Only the installer package is allowed
      * to set overrides on a non-debuggable final build and a non-test apk.
      *
+     * <p>Note that calling this method doesn't remove previously added overrides for the given
+     * package if their change ID isn't in the given map, only replaces those that have the same
+     * change ID.
+     *
      * @param packageName The package name of the app in question.
-     * @param overrides A map from changeId to the override applied for this change id.
+     * @param overrides A map from change ID to the override applied for this change ID.
      */
     @RequiresPermission(android.Manifest.permission.OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD)
-    public static void setPackageOverride(@NonNull String packageName,
+    public static void addPackageOverrides(@NonNull String packageName,
             @NonNull Map<Long, PackageOverride> overrides) {
         IPlatformCompat platformCompat = IPlatformCompat.Stub.asInterface(
                 ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE));
@@ -117,4 +123,29 @@
             e.rethrowFromSystemServer();
         }
     }
+
+    /**
+     * Removes app compat overrides for a given package. This will check whether the caller is
+     * allowed to perform this operation on the given apk and build. Only the installer package is
+     * allowed to clear overrides on a non-debuggable final build and a non-test apk.
+     *
+     * <p>Note that calling this method with an empty set is a no-op and no overrides will be
+     * removed for the given package.
+     *
+     * @param packageName The package name of the app in question.
+     * @param overridesToRemove A set of change IDs for which to remove overrides.
+     */
+    @RequiresPermission(android.Manifest.permission.OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD)
+    public static void removePackageOverrides(@NonNull String packageName,
+            @NonNull Set<Long> overridesToRemove) {
+        IPlatformCompat platformCompat = IPlatformCompat.Stub.asInterface(
+                ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE));
+        CompatibilityOverridesToRemoveConfig config = new CompatibilityOverridesToRemoveConfig(
+                overridesToRemove);
+        try {
+            platformCompat.removeOverridesOnReleaseBuilds(config, packageName);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
 }
diff --git a/core/java/android/app/compat/PackageOverride.java b/core/java/android/app/compat/PackageOverride.java
index 59b3555..fad6cd3 100644
--- a/core/java/android/app/compat/PackageOverride.java
+++ b/core/java/android/app/compat/PackageOverride.java
@@ -19,6 +19,7 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.SystemApi;
+import android.content.pm.PackageInfo;
 import android.os.Parcel;
 
 import java.lang.annotation.Retention;
@@ -101,12 +102,20 @@
         return VALUE_UNDEFINED;
     }
 
-    /** Returns the minimum version code the override applies to. */
+    /**
+     * Returns the minimum APK version code the override applies to.
+     *
+     * @see PackageInfo#getLongVersionCode()
+     */
     public long getMinVersionCode() {
         return mMinVersionCode;
     }
 
-    /** Returns the minimum version code the override applies from. */
+    /**
+     * Returns the maximum APK version code the override applies from.
+     *
+     * @see PackageInfo#getLongVersionCode()
+     */
     public long getMaxVersionCode() {
         return mMaxVersionCode;
     }
@@ -146,9 +155,11 @@
         private boolean mEnabled;
 
         /**
-         * Sets the minimum version code the override should apply from.
+         * Sets the minimum APK version code the override should apply from.
          *
          * default value: {@code Long.MIN_VALUE}.
+         *
+         * @see PackageInfo#getLongVersionCode()
          */
         @NonNull
         public Builder setMinVersionCode(long minVersionCode) {
@@ -157,9 +168,11 @@
         }
 
         /**
-         * Sets the maximum version code the override should apply to.
+         * Sets the maximum APK version code the override should apply to.
          *
          * default value: {@code Long.MAX_VALUE}.
+         *
+         * @see PackageInfo#getLongVersionCode()
          */
         @NonNull
         public Builder setMaxVersionCode(long maxVersionCode) {
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 3802289..63221c5 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -3063,7 +3063,7 @@
          * @param transport - whether the {@link OobData} is generated for LE or Classic.
          * @param oobData - data generated in the host stack(LE) or controller (Classic)
          */
-        void onOobData(@Transport int transport, @Nullable OobData oobData);
+        void onOobData(@Transport int transport, @NonNull OobData oobData);
 
         /**
          * Provides feedback when things don't go as expected.
@@ -3104,7 +3104,7 @@
          *
          * @hide
          */
-        public void onOobData(@Transport int transport, OobData oobData) {
+        public void onOobData(@Transport int transport, @NonNull OobData oobData) {
             mExecutor.execute(new Runnable() {
                 public void run() {
                     mCallback.onOobData(transport, oobData);
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index a40bf34..11b45e3 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -1605,13 +1605,13 @@
      *
      * <p>This API is asynchronous and {@link #ACTION_UUID} intent is sent,
      * with the UUIDs supported by the remote end. If there is an error
-     * in getting the SDP records or if the process takes a long time,
-     * {@link #ACTION_UUID} intent is sent with the UUIDs that is currently
-     * present in the cache. Clients should use the {@link #getUuids} to get UUIDs
+     * in getting the SDP records or if the process takes a long time, or the device is bonding and
+     * we have its UUIDs cached, {@link #ACTION_UUID} intent is sent with the UUIDs that is
+     * currently present in the cache. Clients should use the {@link #getUuids} to get UUIDs
      * if service discovery is not to be performed.
      *
      * @return False if the check fails, True if the process of initiating an ACL connection
-     * to the remote device was started.
+     * to the remote device was started or cached UUIDs will be broadcast.
      */
     @RequiresPermission(Manifest.permission.BLUETOOTH)
     public boolean fetchUuidsWithSdp() {
diff --git a/core/java/android/bluetooth/OobData.java b/core/java/android/bluetooth/OobData.java
index d6868e0..2dfa91d 100644
--- a/core/java/android/bluetooth/OobData.java
+++ b/core/java/android/bluetooth/OobData.java
@@ -25,7 +25,6 @@
 
 import com.android.internal.util.Preconditions;
 
-import java.lang.IllegalArgumentException;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
@@ -165,68 +164,6 @@
     public static final int LE_FLAG_SIMULTANEOUS_HOST = 0x04;
 
     /**
-     * Main creation method for creating a Classic version of {@link OobData}.
-     *
-     * <p>This object will allow the caller to call {@link ClassicBuilder#build()}
-     * to build the data object or add any option information to the builder.
-     *
-     * @param confirmationHash byte array consisting of {@link OobData#CONFIRMATION_OCTETS} octets
-     * of data. Data is derived from controller/host stack and is required for pairing OOB.
-     * @param classicLength byte array representing the length of data from 8-65535 across 2
-     * octets (0xXXXX).
-     * @param deviceAddressWithType byte array representing the Bluetooth Address of the device
-     * that owns the OOB data. (i.e. the originator) [6 octets]
-     *
-     * @return a Classic Builder instance with all the given data set or null.
-     *
-     * @throws IllegalArgumentException if any of the values fail to be set.
-     * @throws NullPointerException if any argument is null.
-     *
-     * @hide
-     */
-    @NonNull
-    @SystemApi
-    public static ClassicBuilder createClassicBuilder(@NonNull byte[] confirmationHash,
-            @NonNull byte[] classicLength, @NonNull byte[] deviceAddressWithType) {
-        return new ClassicBuilder(confirmationHash, classicLength, deviceAddressWithType);
-    }
-
-    /**
-     * Main creation method for creating a LE version of {@link OobData}.
-     *
-     * <p>This object will allow the caller to call {@link LeBuilder#build()}
-     * to build the data object or add any option information to the builder.
-     *
-     * @param deviceAddressWithType the LE device address plus the address type (7 octets);
-     * not null.
-     * @param leDeviceRole whether the device supports Peripheral, Central,
-     * Both including preference; not null. (1 octet)
-     * @param confirmationHash Array consisting of {@link OobData#CONFIRMATION_OCTETS} octets
-     * of data. Data is derived from controller/host stack and is
-     * required for pairing OOB.
-     *
-     * <p>Possible LE Device Role Values:
-     * 0x00 Only Peripheral supported
-     * 0x01 Only Central supported
-     * 0x02 Central & Peripheral supported; Peripheral Preferred
-     * 0x03 Only peripheral supported; Central Preferred
-     * 0x04 - 0xFF Reserved
-     *
-     * @return a LeBuilder instance with all the given data set or null.
-     *
-     * @throws IllegalArgumentException if any of the values fail to be set.
-     * @throws NullPointerException if any argument is null.
-     *
-     * @hide
-     */
-    @NonNull
-    @SystemApi
-    public static LeBuilder createLeBuilder(@NonNull byte[] confirmationHash,
-            @NonNull byte[] deviceAddressWithType, @LeRole int leDeviceRole) {
-        return new LeBuilder(confirmationHash, deviceAddressWithType, leDeviceRole);
-    }
-
-    /**
      * Builds an {@link OobData} object and validates that the required combination
      * of values are present to create the LE specific OobData type.
      *
@@ -342,16 +279,18 @@
         private @LeFlag int mLeFlags = LE_FLAG_GENERAL_DISCOVERY_MODE; // Invalid default
 
         /**
-         * Constructing an OobData object for use with LE requires
-         * a LE Device Address and LE Device Role as well as the Confirmation
-         * and optionally, the Randomizer, however it is recommended to use.
+         * Main creation method for creating a LE version of {@link OobData}.
          *
-         * @param confirmationHash byte array consisting of {@link OobData#CONFIRMATION_OCTETS}
-         * octets of data. Data is derived from controller/host stack and is required for
-         * pairing OOB.
-         * @param deviceAddressWithType 7 bytes containing the 6 byte address with the 1 byte
-         * address type.
-         * @param leDeviceRole indicating device's role and preferences (Central or Peripheral)
+         * <p>This object will allow the caller to call {@link LeBuilder#build()}
+         * to build the data object or add any option information to the builder.
+         *
+         * @param deviceAddressWithType the LE device address plus the address type (7 octets);
+         * not null.
+         * @param leDeviceRole whether the device supports Peripheral, Central,
+         * Both including preference; not null. (1 octet)
+         * @param confirmationHash Array consisting of {@link OobData#CONFIRMATION_OCTETS} octets
+         * of data. Data is derived from controller/host stack and is
+         * required for pairing OOB.
          *
          * <p>Possible Values:
          * {@link LE_DEVICE_ROLE_PERIPHERAL_ONLY} Only Peripheral supported
@@ -361,11 +300,13 @@
          * {@link LE_DEVICE_ROLE_BOTH_PREFER_CENTRAL} Only peripheral supported; Central Preferred
          * 0x04 - 0xFF Reserved
          *
-         * @throws IllegalArgumentException if deviceAddressWithType is not
-         *                                  {@link LE_DEVICE_ADDRESS_OCTETS} octets
+         * @throws IllegalArgumentException if any of the values fail to be set.
          * @throws NullPointerException if any argument is null.
+         *
+         * @hide
          */
-        private LeBuilder(@NonNull byte[] confirmationHash, @NonNull byte[] deviceAddressWithType,
+        @SystemApi
+        public LeBuilder(@NonNull byte[] confirmationHash, @NonNull byte[] deviceAddressWithType,
                 @LeRole int leDeviceRole) {
             Preconditions.checkNotNull(confirmationHash);
             Preconditions.checkNotNull(deviceAddressWithType);
@@ -572,25 +513,26 @@
         private byte[] mClassOfDevice = null;
 
         /**
+         * Main creation method for creating a Classic version of {@link OobData}.
+         *
+         * <p>This object will allow the caller to call {@link ClassicBuilder#build()}
+         * to build the data object or add any option information to the builder.
+         *
          * @param confirmationHash byte array consisting of {@link OobData#CONFIRMATION_OCTETS}
          * octets of data. Data is derived from controller/host stack and is required for pairing
          * OOB.
-         * @param randomizerHash byte array consisting of {@link OobData#RANDOMIZER_OCTETS} octets
-         * of data. Data is derived from controller/host stack and is required
-         * for pairing OOB. Also, randomizerHash may be all 0s or null in which case
-         * it becomes all 0s.
          * @param classicLength byte array representing the length of data from 8-65535 across 2
-         * octets (0xXXXX). Inclusive of this value in the length.
+         * octets (0xXXXX).
          * @param deviceAddressWithType byte array representing the Bluetooth Address of the device
-         * that owns the OOB data. (i.e. the originator) [7 octets] this includes the Address Type
-         * as the last octet.
+         * that owns the OOB data. (i.e. the originator) [6 octets]
          *
-         * @throws IllegalArgumentException if any value is not the correct length
-         * @throws NullPointerException if anything passed is null
+         * @throws IllegalArgumentException if any of the values fail to be set.
+         * @throws NullPointerException if any argument is null.
          *
          * @hide
          */
-        private ClassicBuilder(@NonNull byte[] confirmationHash, @NonNull byte[] classicLength,
+        @SystemApi
+        public ClassicBuilder(@NonNull byte[] confirmationHash, @NonNull byte[] classicLength,
                 @NonNull byte[] deviceAddressWithType) {
             Preconditions.checkNotNull(confirmationHash);
             Preconditions.checkNotNull(classicLength);
diff --git a/core/java/android/bluetooth/le/ScanFilter.java b/core/java/android/bluetooth/le/ScanFilter.java
index 3c20dca..a74c663 100644
--- a/core/java/android/bluetooth/le/ScanFilter.java
+++ b/core/java/android/bluetooth/le/ScanFilter.java
@@ -587,6 +587,10 @@
          * @throws IllegalArgumentException If the {@code deviceAddress} is invalid.
          */
         public Builder setDeviceAddress(String deviceAddress) {
+            if (deviceAddress == null) {
+                mDeviceAddress = deviceAddress;
+                return this;
+            }
             return setDeviceAddress(deviceAddress, BluetoothDevice.ADDRESS_TYPE_PUBLIC);
         }
 
diff --git a/core/java/android/content/pm/OWNERS b/core/java/android/content/pm/OWNERS
index f0def805..4e674f6 100644
--- a/core/java/android/content/pm/OWNERS
+++ b/core/java/android/content/pm/OWNERS
@@ -4,7 +4,8 @@
 toddke@google.com
 patb@google.com
 
-per-file PackageParser.java = chiuwinson@google.com
+per-file PackageParser.java = set noparent
+per-file PackageParser.java = chiuwinson@google.com,patb@google.com,toddke@google.com
 per-file *Shortcut* = file:/core/java/android/content/pm/SHORTCUT_OWNERS
 per-file AppSearchPerson.java = file:/core/java/android/content/pm/SHORTCUT_OWNERS
 per-file *Launcher* = file:/core/java/android/content/pm/LAUNCHER_OWNERS
diff --git a/core/java/android/content/pm/SharedLibraryInfo.java b/core/java/android/content/pm/SharedLibraryInfo.java
index da2a3d8..933a0c9 100644
--- a/core/java/android/content/pm/SharedLibraryInfo.java
+++ b/core/java/android/content/pm/SharedLibraryInfo.java
@@ -20,6 +20,7 @@
 import android.annotation.IntRange;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.TestApi;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -29,6 +30,7 @@
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
+import java.util.Objects;
 
 /**
  * This class provides information for a shared library. There are
@@ -177,7 +179,8 @@
      *
      * @hide
      */
-    public List<String> getAllCodePaths() {
+    @TestApi
+    public @NonNull List<String> getAllCodePaths() {
         if (getPath() != null) {
             // Builtin library.
             ArrayList<String> list = new ArrayList<>();
@@ -185,7 +188,7 @@
             return list;
         } else {
             // Static or dynamic library.
-            return mCodePaths;
+            return Objects.requireNonNull(mCodePaths);
         }
     }
 
diff --git a/core/java/android/database/sqlite/package.html b/core/java/android/database/sqlite/package.html
index 4d6ba28..6ececa2 100644
--- a/core/java/android/database/sqlite/package.html
+++ b/core/java/android/database/sqlite/package.html
@@ -20,6 +20,9 @@
 <p>The version of SQLite depends on the version of Android. See the following table:
 <table style="width:auto;">
   <tr><th>Android API</th><th>SQLite Version</th></tr>
+  <tr><td>API 31</td><td>3.32</td></tr>
+  <tr><td>API 30</td><td>3.28</td></tr>
+  <tr><td>API 28</td><td>3.22</td></tr>
   <tr><td>API 27</td><td>3.19</td></tr>
   <tr><td>API 26</td><td>3.18</td></tr>
   <tr><td>API 24</td><td>3.9</td></tr>
diff --git a/core/java/android/hardware/biometrics/BiometricManager.java b/core/java/android/hardware/biometrics/BiometricManager.java
index e385cd2..362a205 100644
--- a/core/java/android/hardware/biometrics/BiometricManager.java
+++ b/core/java/android/hardware/biometrics/BiometricManager.java
@@ -26,6 +26,7 @@
 import android.annotation.SystemService;
 import android.content.Context;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.security.keystore.KeyGenParameterSpec;
 import android.security.keystore.KeyProperties;
 import android.util.Slog;
@@ -334,11 +335,23 @@
      * in Keystore land as SIDs, and are used during key generation.
      * @hide
      */
-    @RequiresPermission(USE_BIOMETRIC_INTERNAL)
     public long[] getAuthenticatorIds() {
+        return getAuthenticatorIds(UserHandle.myUserId());
+    }
+
+    /**
+     * Get a list of AuthenticatorIDs for biometric authenticators which have 1) enrolled templates,
+     * and 2) meet the requirements for integrating with Keystore. The AuthenticatorIDs are known
+     * in Keystore land as SIDs, and are used during key generation.
+     *
+     * @param userId Android user ID for user to look up.
+     *
+     * @hide
+     */
+    public long[] getAuthenticatorIds(int userId) {
         if (mService != null) {
             try {
-                return mService.getAuthenticatorIds();
+                return mService.getAuthenticatorIds(userId);
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
@@ -347,6 +360,5 @@
             return new long[0];
         }
     }
-
 }
 
diff --git a/core/java/android/hardware/biometrics/IAuthService.aidl b/core/java/android/hardware/biometrics/IAuthService.aidl
index a6f6c1e..35424829 100644
--- a/core/java/android/hardware/biometrics/IAuthService.aidl
+++ b/core/java/android/hardware/biometrics/IAuthService.aidl
@@ -55,5 +55,7 @@
     // Get a list of AuthenticatorIDs for authenticators which have enrolled templates and meet
     // the requirements for integrating with Keystore. The AuthenticatorID are known in Keystore
     // land as SIDs, and are used during key generation.
-    long[] getAuthenticatorIds();
+    // If userId is not equal to the calling user ID, the caller must have the
+    // USE_BIOMETRIC_INTERNAL permission.
+    long[] getAuthenticatorIds(in int userId);
 }
diff --git a/core/java/android/hardware/face/OWNERS b/core/java/android/hardware/face/OWNERS
index be10df1..0b4d9d9 100644
--- a/core/java/android/hardware/face/OWNERS
+++ b/core/java/android/hardware/face/OWNERS
@@ -1,7 +1,3 @@
 # Bug component: 879035
 
-curtislb@google.com
-ilyamaty@google.com
-jaggies@google.com
-joshmccloskey@google.com
-kchyn@google.com
+include /services/core/java/com/android/server/biometrics/OWNERS
diff --git a/core/java/android/hardware/fingerprint/OWNERS b/core/java/android/hardware/fingerprint/OWNERS
index e55b8c56..5c93672 100644
--- a/core/java/android/hardware/fingerprint/OWNERS
+++ b/core/java/android/hardware/fingerprint/OWNERS
@@ -1,8 +1,3 @@
 # Bug component: 114777
 
-curtislb@google.com
-ilyamaty@google.com
-jaggies@google.com
-joshmccloskey@google.com
-kchyn@google.com
-
+include /services/core/java/com/android/server/biometrics/OWNERS
diff --git a/core/java/android/hardware/hdmi/OWNERS b/core/java/android/hardware/hdmi/OWNERS
index 16c15e3..60d43fd 100644
--- a/core/java/android/hardware/hdmi/OWNERS
+++ b/core/java/android/hardware/hdmi/OWNERS
@@ -4,3 +4,4 @@
 
 marvinramin@google.com
 nchalko@google.com
+lcnathalie@google.com
diff --git a/core/java/android/hardware/iris/OWNERS b/core/java/android/hardware/iris/OWNERS
index 33527f8..0b4d9d9 100644
--- a/core/java/android/hardware/iris/OWNERS
+++ b/core/java/android/hardware/iris/OWNERS
@@ -1,3 +1,3 @@
 # Bug component: 879035
 
-jaggies@google.com
+include /services/core/java/com/android/server/biometrics/OWNERS
diff --git a/core/java/android/net/IpSecManager.java b/core/java/android/net/IpSecManager.java
index 98acd98..01d1aa5 100644
--- a/core/java/android/net/IpSecManager.java
+++ b/core/java/android/net/IpSecManager.java
@@ -79,6 +79,16 @@
     public static final int DIRECTION_OUT = 1;
 
     /**
+     * Used when applying a transform to direct traffic through an {@link IpSecTransform} for
+     * forwarding between interfaces.
+     *
+     * <p>See {@link #applyTransportModeTransform(Socket, int, IpSecTransform)}.
+     *
+     * @hide
+     */
+    public static final int DIRECTION_FWD = 2;
+
+    /**
      * The Security Parameter Index (SPI) 0 indicates an unknown or invalid index.
      *
      * <p>No IPsec packet may contain an SPI of 0.
diff --git a/core/java/android/net/NetworkIdentity.java b/core/java/android/net/NetworkIdentity.java
index 1eef7d9..3bde6fa 100644
--- a/core/java/android/net/NetworkIdentity.java
+++ b/core/java/android/net/NetworkIdentity.java
@@ -186,19 +186,19 @@
      */
     public static NetworkIdentity buildNetworkIdentity(Context context,
             NetworkStateSnapshot snapshot, boolean defaultNetwork, @NetworkType int subType) {
-        final int legacyType = snapshot.legacyType;
+        final int legacyType = snapshot.getLegacyType();
 
-        final String subscriberId = snapshot.subscriberId;
+        final String subscriberId = snapshot.getSubscriberId();
         String networkId = null;
-        boolean roaming = !snapshot.networkCapabilities.hasCapability(
+        boolean roaming = !snapshot.getNetworkCapabilities().hasCapability(
                 NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING);
-        boolean metered = !snapshot.networkCapabilities.hasCapability(
+        boolean metered = !snapshot.getNetworkCapabilities().hasCapability(
                 NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
 
-        final int oemManaged = getOemBitfield(snapshot.networkCapabilities);
+        final int oemManaged = getOemBitfield(snapshot.getNetworkCapabilities());
 
         if (legacyType == TYPE_WIFI) {
-            networkId = snapshot.networkCapabilities.getSsid();
+            networkId = snapshot.getNetworkCapabilities().getSsid();
             if (networkId == null) {
                 final WifiManager wifi = context.getSystemService(WifiManager.class);
                 final WifiInfo info = wifi.getConnectionInfo();
diff --git a/core/java/android/net/NetworkStateSnapshot.java b/core/java/android/net/NetworkStateSnapshot.java
index 0d26c2d..9df861a 100644
--- a/core/java/android/net/NetworkStateSnapshot.java
+++ b/core/java/android/net/NetworkStateSnapshot.java
@@ -37,47 +37,76 @@
 public final class NetworkStateSnapshot implements Parcelable {
     /** The network associated with this snapshot. */
     @NonNull
-    public final Network network;
+    private final Network mNetwork;
 
     /** The {@link NetworkCapabilities} of the network associated with this snapshot. */
     @NonNull
-    public final NetworkCapabilities networkCapabilities;
+    private final NetworkCapabilities mNetworkCapabilities;
 
     /** The {@link LinkProperties} of the network associated with this snapshot. */
     @NonNull
-    public final LinkProperties linkProperties;
+    private final LinkProperties mLinkProperties;
 
     /**
      * The Subscriber Id of the network associated with this snapshot. See
      * {@link android.telephony.TelephonyManager#getSubscriberId()}.
      */
     @Nullable
-    public final String subscriberId;
+    private final String mSubscriberId;
 
     /**
      * The legacy type of the network associated with this snapshot. See
      * {@code ConnectivityManager#TYPE_*}.
      */
-    public final int legacyType;
+    private final int mLegacyType;
 
     public NetworkStateSnapshot(@NonNull Network network,
             @NonNull NetworkCapabilities networkCapabilities,
             @NonNull LinkProperties linkProperties,
             @Nullable String subscriberId, int legacyType) {
-        this.network = Objects.requireNonNull(network);
-        this.networkCapabilities = Objects.requireNonNull(networkCapabilities);
-        this.linkProperties = Objects.requireNonNull(linkProperties);
-        this.subscriberId = subscriberId;
-        this.legacyType = legacyType;
+        mNetwork = Objects.requireNonNull(network);
+        mNetworkCapabilities = Objects.requireNonNull(networkCapabilities);
+        mLinkProperties = Objects.requireNonNull(linkProperties);
+        mSubscriberId = subscriberId;
+        mLegacyType = legacyType;
     }
 
     /** @hide */
     public NetworkStateSnapshot(@NonNull Parcel in) {
-        network = in.readParcelable(null);
-        networkCapabilities = in.readParcelable(null);
-        linkProperties = in.readParcelable(null);
-        subscriberId = in.readString();
-        legacyType = in.readInt();
+        mNetwork = in.readParcelable(null);
+        mNetworkCapabilities = in.readParcelable(null);
+        mLinkProperties = in.readParcelable(null);
+        mSubscriberId = in.readString();
+        mLegacyType = in.readInt();
+    }
+
+    /** Get the network associated with this snapshot */
+    @NonNull
+    public Network getNetwork() {
+        return mNetwork;
+    }
+
+    /** Get {@link NetworkCapabilities} of the network associated with this snapshot. */
+    @NonNull
+    public NetworkCapabilities getNetworkCapabilities() {
+        return mNetworkCapabilities;
+    }
+
+    /** Get the {@link LinkProperties} of the network associated with this snapshot. */
+    @NonNull
+    public LinkProperties getLinkProperties() {
+        return mLinkProperties;
+    }
+
+    /** Get the Subscriber Id of the network associated with this snapshot. */
+    @Nullable
+    public String getSubscriberId() {
+        return mSubscriberId;
+    }
+
+    /** Get the legacy type of the network associated with this snapshot. */
+    public int getLegacyType() {
+        return mLegacyType;
     }
 
     @Override
@@ -87,11 +116,11 @@
 
     @Override
     public void writeToParcel(@NonNull Parcel out, int flags) {
-        out.writeParcelable(network, flags);
-        out.writeParcelable(networkCapabilities, flags);
-        out.writeParcelable(linkProperties, flags);
-        out.writeString(subscriberId);
-        out.writeInt(legacyType);
+        out.writeParcelable(mNetwork, flags);
+        out.writeParcelable(mNetworkCapabilities, flags);
+        out.writeParcelable(mLinkProperties, flags);
+        out.writeString(mSubscriberId);
+        out.writeInt(mLegacyType);
     }
 
     @NonNull
@@ -115,26 +144,27 @@
         if (this == o) return true;
         if (!(o instanceof NetworkStateSnapshot)) return false;
         NetworkStateSnapshot that = (NetworkStateSnapshot) o;
-        return legacyType == that.legacyType
-                && Objects.equals(network, that.network)
-                && Objects.equals(networkCapabilities, that.networkCapabilities)
-                && Objects.equals(linkProperties, that.linkProperties)
-                && Objects.equals(subscriberId, that.subscriberId);
+        return mLegacyType == that.mLegacyType
+                && Objects.equals(mNetwork, that.mNetwork)
+                && Objects.equals(mNetworkCapabilities, that.mNetworkCapabilities)
+                && Objects.equals(mLinkProperties, that.mLinkProperties)
+                && Objects.equals(mSubscriberId, that.mSubscriberId);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(network, networkCapabilities, linkProperties, subscriberId, legacyType);
+        return Objects.hash(mNetwork,
+                mNetworkCapabilities, mLinkProperties, mSubscriberId, mLegacyType);
     }
 
     @Override
     public String toString() {
         return "NetworkStateSnapshot{"
-                + "network=" + network
-                + ", networkCapabilities=" + networkCapabilities
-                + ", linkProperties=" + linkProperties
-                + ", subscriberId='" + NetworkIdentityUtils.scrubSubscriberId(subscriberId) + '\''
-                + ", legacyType=" + legacyType
+                + "network=" + mNetwork
+                + ", networkCapabilities=" + mNetworkCapabilities
+                + ", linkProperties=" + mLinkProperties
+                + ", subscriberId='" + NetworkIdentityUtils.scrubSubscriberId(mSubscriberId) + '\''
+                + ", legacyType=" + mLegacyType
                 + '}';
     }
 }
diff --git a/core/java/android/net/NetworkStats.java b/core/java/android/net/NetworkStats.java
index d42beae..6ccbab7 100644
--- a/core/java/android/net/NetworkStats.java
+++ b/core/java/android/net/NetworkStats.java
@@ -38,6 +38,7 @@
 import java.lang.annotation.RetentionPolicy;
 import java.util.Arrays;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 import java.util.function.Predicate;
@@ -1423,11 +1424,11 @@
      * @hide
      */
     public void migrateTun(int tunUid, @NonNull String tunIface,
-            @NonNull String[] underlyingIfaces) {
+            @NonNull List<String> underlyingIfaces) {
         // Combined usage by all apps using VPN.
         final Entry tunIfaceTotal = new Entry();
         // Usage by VPN, grouped by its {@code underlyingIfaces}.
-        final Entry[] perInterfaceTotal = new Entry[underlyingIfaces.length];
+        final Entry[] perInterfaceTotal = new Entry[underlyingIfaces.size()];
         // Usage by VPN, summed across all its {@code underlyingIfaces}.
         final Entry underlyingIfacesTotal = new Entry();
 
@@ -1468,7 +1469,7 @@
      *     {@code underlyingIfaces}
      */
     private void tunAdjustmentInit(int tunUid, @NonNull String tunIface,
-            @NonNull String[] underlyingIfaces, @NonNull Entry tunIfaceTotal,
+            @NonNull List<String> underlyingIfaces, @NonNull Entry tunIfaceTotal,
             @NonNull Entry[] perInterfaceTotal, @NonNull Entry underlyingIfacesTotal) {
         final Entry recycle = new Entry();
         for (int i = 0; i < size; i++) {
@@ -1488,8 +1489,8 @@
 
             if (recycle.uid == tunUid) {
                 // Add up traffic through tunUid's underlying interfaces.
-                for (int j = 0; j < underlyingIfaces.length; j++) {
-                    if (Objects.equals(underlyingIfaces[j], recycle.iface)) {
+                for (int j = 0; j < underlyingIfaces.size(); j++) {
+                    if (Objects.equals(underlyingIfaces.get(j), recycle.iface)) {
                         perInterfaceTotal[j].add(recycle);
                         underlyingIfacesTotal.add(recycle);
                         break;
@@ -1515,12 +1516,12 @@
      *     underlyingIfaces}
      */
     private Entry[] addTrafficToApplications(int tunUid, @NonNull String tunIface,
-            @NonNull String[] underlyingIfaces, @NonNull Entry tunIfaceTotal,
+            @NonNull List<String> underlyingIfaces, @NonNull Entry tunIfaceTotal,
             @NonNull Entry[] perInterfaceTotal, @NonNull Entry underlyingIfacesTotal) {
         // Traffic that should be moved off of each underlying interface for tunUid (see
         // deductTrafficFromVpnApp below).
-        final Entry[] moved = new Entry[underlyingIfaces.length];
-        for (int i = 0; i < underlyingIfaces.length; i++) {
+        final Entry[] moved = new Entry[underlyingIfaces.size()];
+        for (int i = 0; i < underlyingIfaces.size(); i++) {
             moved[i] = new Entry();
         }
 
@@ -1582,8 +1583,8 @@
             }
             // In a second pass, distribute these values across interfaces in the proportion that
             // each interface represents of the total traffic of the underlying interfaces.
-            for (int j = 0; j < underlyingIfaces.length; j++) {
-                tmpEntry.iface = underlyingIfaces[j];
+            for (int j = 0; j < underlyingIfaces.size(); j++) {
+                tmpEntry.iface = underlyingIfaces.get(j);
                 tmpEntry.rxBytes = 0;
                 // Reset 'set' to correct value since it gets updated when adding debug info below.
                 tmpEntry.set = set[i];
@@ -1638,14 +1639,14 @@
 
     private void deductTrafficFromVpnApp(
             int tunUid,
-            @NonNull String[] underlyingIfaces,
+            @NonNull List<String> underlyingIfaces,
             @NonNull Entry[] moved) {
-        for (int i = 0; i < underlyingIfaces.length; i++) {
+        for (int i = 0; i < underlyingIfaces.size(); i++) {
             moved[i].uid = tunUid;
             // Add debug info
             moved[i].set = SET_DBG_VPN_OUT;
             moved[i].tag = TAG_NONE;
-            moved[i].iface = underlyingIfaces[i];
+            moved[i].iface = underlyingIfaces.get(i);
             moved[i].metered = METERED_ALL;
             moved[i].roaming = ROAMING_ALL;
             moved[i].defaultNetwork = DEFAULT_NETWORK_ALL;
@@ -1658,7 +1659,7 @@
             // METERED_NO, which should be the case as it comes directly from the /proc file.
             // We only blend in the roaming data after applying these adjustments, by checking the
             // NetworkIdentity of the underlying iface.
-            final int idxVpnBackground = findIndex(underlyingIfaces[i], tunUid, SET_DEFAULT,
+            final int idxVpnBackground = findIndex(underlyingIfaces.get(i), tunUid, SET_DEFAULT,
                             TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO);
             if (idxVpnBackground != -1) {
                 // Note - tunSubtract also updates moved[i]; whatever traffic that's left is removed
@@ -1666,7 +1667,7 @@
                 tunSubtract(idxVpnBackground, this, moved[i]);
             }
 
-            final int idxVpnForeground = findIndex(underlyingIfaces[i], tunUid, SET_FOREGROUND,
+            final int idxVpnForeground = findIndex(underlyingIfaces.get(i), tunUid, SET_FOREGROUND,
                             TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO);
             if (idxVpnForeground != -1) {
                 tunSubtract(idxVpnForeground, this, moved[i]);
diff --git a/core/java/android/net/NetworkTemplate.java b/core/java/android/net/NetworkTemplate.java
index c83dd99..d3c8957 100644
--- a/core/java/android/net/NetworkTemplate.java
+++ b/core/java/android/net/NetworkTemplate.java
@@ -82,6 +82,24 @@
     public static final int MATCH_WIFI_WILDCARD = 7;
     public static final int MATCH_BLUETOOTH = 8;
     public static final int MATCH_PROXY = 9;
+    public static final int MATCH_CARRIER = 10;
+
+    /**
+     * Value of the match rule of the subscriberId to match networks with specific subscriberId.
+     */
+    public static final int SUBSCRIBER_ID_MATCH_RULE_EXACT = 0;
+    /**
+     * Value of the match rule of the subscriberId to match networks with any subscriberId which
+     * includes null and non-null.
+     */
+    public static final int SUBSCRIBER_ID_MATCH_RULE_ALL = 1;
+
+    /**
+     * Wi-Fi Network ID is never supposed to be null (if it is, it is a bug that
+     * should be fixed), so it's not possible to want to match null vs
+     * non-null. Therefore it's fine to use null as a sentinel for Network ID.
+     */
+    public static final String WIFI_NETWORKID_ALL = null;
 
     /**
      * Include all network types when filtering. This is meant to merge in with the
@@ -125,6 +143,7 @@
             case MATCH_WIFI_WILDCARD:
             case MATCH_BLUETOOTH:
             case MATCH_PROXY:
+            case MATCH_CARRIER:
                 return true;
 
             default:
@@ -168,10 +187,12 @@
             @NetworkType int ratType) {
         if (TextUtils.isEmpty(subscriberId)) {
             return new NetworkTemplate(MATCH_MOBILE_WILDCARD, null, null, null,
-                    METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, ratType, OEM_MANAGED_ALL);
+                    METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, ratType, OEM_MANAGED_ALL,
+                    SUBSCRIBER_ID_MATCH_RULE_EXACT);
         }
         return new NetworkTemplate(MATCH_MOBILE, subscriberId, new String[]{subscriberId}, null,
-                METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, ratType, OEM_MANAGED_ALL);
+                METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, ratType, OEM_MANAGED_ALL,
+                SUBSCRIBER_ID_MATCH_RULE_EXACT);
     }
 
     /**
@@ -189,6 +210,8 @@
      */
     @UnsupportedAppUsage
     public static NetworkTemplate buildTemplateWifiWildcard() {
+        // TODO: Consider replace this with MATCH_WIFI with NETWORK_ID_ALL
+        // and SUBSCRIBER_ID_MATCH_RULE_ALL.
         return new NetworkTemplate(MATCH_WIFI_WILDCARD, null, null);
     }
 
@@ -202,8 +225,27 @@
      * Template to match {@link ConnectivityManager#TYPE_WIFI} networks with the
      * given SSID.
      */
-    public static NetworkTemplate buildTemplateWifi(String networkId) {
-        return new NetworkTemplate(MATCH_WIFI, null, networkId);
+    public static NetworkTemplate buildTemplateWifi(@NonNull String networkId) {
+        Objects.requireNonNull(networkId);
+        return new NetworkTemplate(MATCH_WIFI, null /* subscriberId */,
+                new String[] { null } /* matchSubscriberIds */,
+                networkId, METERED_ALL, ROAMING_ALL,
+                DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_ALL,
+                SUBSCRIBER_ID_MATCH_RULE_ALL);
+    }
+
+    /**
+     * Template to match all {@link ConnectivityManager#TYPE_WIFI} networks with the given SSID,
+     * and IMSI.
+     *
+     * Call with {@link #WIFI_NETWORKID_ALL} for {@code networkId} to get result regardless of SSID.
+     */
+    public static NetworkTemplate buildTemplateWifi(@Nullable String networkId,
+            @Nullable String subscriberId) {
+        return new NetworkTemplate(MATCH_WIFI, subscriberId, new String[] { subscriberId },
+                networkId, METERED_ALL, ROAMING_ALL,
+                DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_ALL,
+                SUBSCRIBER_ID_MATCH_RULE_EXACT);
     }
 
     /**
@@ -231,6 +273,14 @@
         return new NetworkTemplate(MATCH_PROXY, null, null);
     }
 
+    /**
+     * Template to match all carrier networks with the given IMSI.
+     */
+    public static NetworkTemplate buildTemplateCarrier(@NonNull String subscriberId) {
+        Objects.requireNonNull(subscriberId);
+        return new NetworkTemplate(MATCH_CARRIER, subscriberId, null);
+    }
+
     private final int mMatchRule;
     private final String mSubscriberId;
 
@@ -251,10 +301,26 @@
     private final int mRoaming;
     private final int mDefaultNetwork;
     private final int mSubType;
+    private final int mSubscriberIdMatchRule;
 
     // Bitfield containing OEM network properties{@code NetworkIdentity#OEM_*}.
     private final int mOemManaged;
 
+    private void checkValidSubscriberIdMatchRule() {
+        switch (mMatchRule) {
+            case MATCH_MOBILE:
+            case MATCH_CARRIER:
+                // MOBILE and CARRIER templates must always specify a subscriber ID.
+                if (mSubscriberIdMatchRule == SUBSCRIBER_ID_MATCH_RULE_ALL) {
+                    throw new IllegalArgumentException("Invalid SubscriberIdMatchRule"
+                            + "on match rule: " + getMatchRuleName(mMatchRule));
+                }
+                return;
+            default:
+                return;
+        }
+    }
+
     @UnsupportedAppUsage
     public NetworkTemplate(int matchRule, String subscriberId, String networkId) {
         this(matchRule, subscriberId, new String[] { subscriberId }, networkId);
@@ -263,14 +329,25 @@
     public NetworkTemplate(int matchRule, String subscriberId, String[] matchSubscriberIds,
             String networkId) {
         this(matchRule, subscriberId, matchSubscriberIds, networkId, METERED_ALL, ROAMING_ALL,
-                DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_ALL);
+                DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_ALL,
+                SUBSCRIBER_ID_MATCH_RULE_EXACT);
+    }
+
+    // TODO: Remove it after updating all of the caller.
+    public NetworkTemplate(int matchRule, String subscriberId, String[] matchSubscriberIds,
+            String networkId, int metered, int roaming, int defaultNetwork, int subType,
+            int oemManaged) {
+        this(matchRule, subscriberId, matchSubscriberIds, networkId, metered, roaming,
+                defaultNetwork, subType, oemManaged, SUBSCRIBER_ID_MATCH_RULE_EXACT);
     }
 
     public NetworkTemplate(int matchRule, String subscriberId, String[] matchSubscriberIds,
             String networkId, int metered, int roaming, int defaultNetwork, int subType,
-            int oemManaged) {
+            int oemManaged, int subscriberIdMatchRule) {
         mMatchRule = matchRule;
         mSubscriberId = subscriberId;
+        // TODO: Check whether mMatchSubscriberIds = null or mMatchSubscriberIds = {null} when
+        // mSubscriberId is null
         mMatchSubscriberIds = matchSubscriberIds;
         mNetworkId = networkId;
         mMetered = metered;
@@ -278,7 +355,8 @@
         mDefaultNetwork = defaultNetwork;
         mSubType = subType;
         mOemManaged = oemManaged;
-
+        mSubscriberIdMatchRule = subscriberIdMatchRule;
+        checkValidSubscriberIdMatchRule();
         if (!isKnownMatchRule(matchRule)) {
             Log.e(TAG, "Unknown network template rule " + matchRule
                     + " will not match any identity.");
@@ -295,6 +373,7 @@
         mDefaultNetwork = in.readInt();
         mSubType = in.readInt();
         mOemManaged = in.readInt();
+        mSubscriberIdMatchRule = in.readInt();
     }
 
     @Override
@@ -308,6 +387,7 @@
         dest.writeInt(mDefaultNetwork);
         dest.writeInt(mSubType);
         dest.writeInt(mOemManaged);
+        dest.writeInt(mSubscriberIdMatchRule);
     }
 
     @Override
@@ -346,13 +426,15 @@
         if (mOemManaged != OEM_MANAGED_ALL) {
             builder.append(", oemManaged=").append(mOemManaged);
         }
+        builder.append(", subscriberIdMatchRule=")
+                .append(subscriberIdMatchRuleToString(mSubscriberIdMatchRule));
         return builder.toString();
     }
 
     @Override
     public int hashCode() {
         return Objects.hash(mMatchRule, mSubscriberId, mNetworkId, mMetered, mRoaming,
-                mDefaultNetwork, mSubType, mOemManaged);
+                mDefaultNetwork, mSubType, mOemManaged, mSubscriberIdMatchRule);
     }
 
     @Override
@@ -366,11 +448,23 @@
                     && mRoaming == other.mRoaming
                     && mDefaultNetwork == other.mDefaultNetwork
                     && mSubType == other.mSubType
-                    && mOemManaged == other.mOemManaged;
+                    && mOemManaged == other.mOemManaged
+                    && mSubscriberIdMatchRule == other.mSubscriberIdMatchRule;
         }
         return false;
     }
 
+    private String subscriberIdMatchRuleToString(int rule) {
+        switch (rule) {
+            case SUBSCRIBER_ID_MATCH_RULE_EXACT:
+                return "EXACT_MATCH";
+            case SUBSCRIBER_ID_MATCH_RULE_ALL:
+                return "ALL";
+            default:
+                return "Unknown rule " + rule;
+        }
+    }
+
     public boolean isMatchRuleMobile() {
         switch (mMatchRule) {
             case MATCH_MOBILE:
@@ -386,6 +480,14 @@
             case MATCH_MOBILE_WILDCARD:
             case MATCH_WIFI_WILDCARD:
                 return false;
+            case MATCH_CARRIER:
+                return mSubscriberId != null;
+            case MATCH_WIFI:
+                if (Objects.equals(mNetworkId, WIFI_NETWORKID_ALL)
+                        && mSubscriberIdMatchRule == SUBSCRIBER_ID_MATCH_RULE_ALL) {
+                    return false;
+                }
+                return true;
             default:
                 return true;
         }
@@ -405,6 +507,10 @@
         return mNetworkId;
     }
 
+    public int getSubscriberIdMatchRule() {
+        return mSubscriberIdMatchRule;
+    }
+
     /**
      * Test if given {@link NetworkIdentity} matches this template.
      */
@@ -429,6 +535,8 @@
                 return matchesBluetooth(ident);
             case MATCH_PROXY:
                 return matchesProxy(ident);
+            case MATCH_CARRIER:
+                return matchesCarrier(ident);
             default:
                 // We have no idea what kind of network template we are, so we
                 // just claim not to match anything.
@@ -466,8 +574,23 @@
                 || getCollapsedRatType(mSubType) == getCollapsedRatType(ident.mSubType);
     }
 
-    public boolean matchesSubscriberId(String subscriberId) {
-        return ArrayUtils.contains(mMatchSubscriberIds, subscriberId);
+    /**
+     * Check if this template matches {@code subscriberId}. Returns true if this
+     * template was created with {@code SUBSCRIBER_ID_MATCH_RULE_ALL}, or with a
+     * {@code mMatchSubscriberIds} array that contains {@code subscriberId}.
+     */
+    public boolean matchesSubscriberId(@Nullable String subscriberId) {
+        return mSubscriberIdMatchRule == SUBSCRIBER_ID_MATCH_RULE_ALL
+                || ArrayUtils.contains(mMatchSubscriberIds, subscriberId);
+    }
+
+    /**
+     * Check if network with matching SSID. Returns true when the SSID matches, or when
+     * {@code mNetworkId} is {@code WIFI_NETWORKID_ALL}.
+     */
+    private boolean matchesWifiNetworkId(@Nullable String networkId) {
+        return Objects.equals(mNetworkId, WIFI_NETWORKID_ALL)
+                || Objects.equals(sanitizeSsid(mNetworkId), sanitizeSsid(networkId));
     }
 
     /**
@@ -566,8 +689,8 @@
     private boolean matchesWifi(NetworkIdentity ident) {
         switch (ident.mType) {
             case TYPE_WIFI:
-                return Objects.equals(
-                        sanitizeSsid(mNetworkId), sanitizeSsid(ident.mNetworkId));
+                return matchesSubscriberId(ident.mSubscriberId)
+                        && matchesWifiNetworkId(ident.mNetworkId);
             default:
                 return false;
         }
@@ -583,6 +706,15 @@
         return false;
     }
 
+    /**
+     * Check if matches carrier network. The carrier networks means it includes the subscriberId.
+     */
+    private boolean matchesCarrier(NetworkIdentity ident) {
+        return ident.mSubscriberId != null
+                && !ArrayUtils.isEmpty(mMatchSubscriberIds)
+                && ArrayUtils.contains(mMatchSubscriberIds, ident.mSubscriberId);
+    }
+
     private boolean matchesMobileWildcard(NetworkIdentity ident) {
         if (ident.mType == TYPE_WIMAX) {
             return true;
@@ -635,6 +767,8 @@
                 return "BLUETOOTH";
             case MATCH_PROXY:
                 return "PROXY";
+            case MATCH_CARRIER:
+                return "CARRIER";
             default:
                 return "UNKNOWN(" + matchRule + ")";
         }
diff --git a/core/java/android/net/TunnelConnectionParams.java b/core/java/android/net/TunnelConnectionParams.java
deleted file mode 100644
index f5b3539..0000000
--- a/core/java/android/net/TunnelConnectionParams.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * 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;
-
-/**
- * TunnelConnectionParams represents a configuration to set up a tunnel connection.
- *
- * <p>Concrete implementations for a control plane protocol should implement this interface.
- * Subclasses should be immutable data classes containing connection, authentication and
- * authorization parameters required to establish a tunnel connection.
- *
- * @see android.net.ipsec.ike.IkeTunnelConnectionParams
- */
-// TODO:b/186071626 Remove TunnelConnectionParams when non-updatable API stub can resolve
-// IkeTunnelConnectionParams
-public interface TunnelConnectionParams {}
diff --git a/core/java/android/net/UnderlyingNetworkInfo.java b/core/java/android/net/UnderlyingNetworkInfo.java
index 7bf9231..459fdac 100644
--- a/core/java/android/net/UnderlyingNetworkInfo.java
+++ b/core/java/android/net/UnderlyingNetworkInfo.java
@@ -37,36 +37,56 @@
 @SystemApi(client = MODULE_LIBRARIES)
 public final class UnderlyingNetworkInfo implements Parcelable {
     /** The owner of this network. */
-    public final int ownerUid;
+    private final int mOwnerUid;
+
     /** The interface name of this network. */
     @NonNull
-    public final String iface;
+    private final String mIface;
+
     /** The names of the interfaces underlying this network. */
     @NonNull
-    public final List<String> underlyingIfaces;
+    private final List<String> mUnderlyingIfaces;
 
     public UnderlyingNetworkInfo(int ownerUid, @NonNull String iface,
             @NonNull List<String> underlyingIfaces) {
         Objects.requireNonNull(iface);
         Objects.requireNonNull(underlyingIfaces);
-        this.ownerUid = ownerUid;
-        this.iface = iface;
-        this.underlyingIfaces = Collections.unmodifiableList(new ArrayList<>(underlyingIfaces));
+        mOwnerUid = ownerUid;
+        mIface = iface;
+        mUnderlyingIfaces = Collections.unmodifiableList(new ArrayList<>(underlyingIfaces));
     }
 
     private UnderlyingNetworkInfo(@NonNull Parcel in) {
-        this.ownerUid = in.readInt();
-        this.iface = in.readString();
-        this.underlyingIfaces = new ArrayList<>();
-        in.readList(this.underlyingIfaces, null /*classLoader*/);
+        mOwnerUid = in.readInt();
+        mIface = in.readString();
+        List<String> underlyingIfaces = new ArrayList<>();
+        in.readList(underlyingIfaces, null /*classLoader*/);
+        mUnderlyingIfaces = Collections.unmodifiableList(underlyingIfaces);
+    }
+
+    /** Get the owner of this network. */
+    public int getOwnerUid() {
+        return mOwnerUid;
+    }
+
+    /** Get the interface name of this network. */
+    @NonNull
+    public String getIface() {
+        return mIface;
+    }
+
+    /** Get the names of the interfaces underlying this network. */
+    @NonNull
+    public List<String> getUnderlyingIfaces() {
+        return mUnderlyingIfaces;
     }
 
     @Override
     public String toString() {
         return "UnderlyingNetworkInfo{"
-                + "ownerUid=" + ownerUid
-                + ", iface='" + iface + '\''
-                + ", underlyingIfaces='" + underlyingIfaces.toString() + '\''
+                + "ownerUid=" + mOwnerUid
+                + ", iface='" + mIface + '\''
+                + ", underlyingIfaces='" + mUnderlyingIfaces.toString() + '\''
                 + '}';
     }
 
@@ -77,9 +97,9 @@
 
     @Override
     public void writeToParcel(@NonNull Parcel dest, int flags) {
-        dest.writeInt(ownerUid);
-        dest.writeString(iface);
-        dest.writeList(underlyingIfaces);
+        dest.writeInt(mOwnerUid);
+        dest.writeString(mIface);
+        dest.writeList(mUnderlyingIfaces);
     }
 
     @NonNull
@@ -103,13 +123,13 @@
         if (this == o) return true;
         if (!(o instanceof UnderlyingNetworkInfo)) return false;
         final UnderlyingNetworkInfo that = (UnderlyingNetworkInfo) o;
-        return ownerUid == that.ownerUid
-                && Objects.equals(iface, that.iface)
-                && Objects.equals(underlyingIfaces, that.underlyingIfaces);
+        return mOwnerUid == that.getOwnerUid()
+                && Objects.equals(mIface, that.getIface())
+                && Objects.equals(mUnderlyingIfaces, that.getUnderlyingIfaces());
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(ownerUid, iface, underlyingIfaces);
+        return Objects.hash(mOwnerUid, mIface, mUnderlyingIfaces);
     }
 }
diff --git a/core/java/android/net/vcn/VcnConfig.java b/core/java/android/net/vcn/VcnConfig.java
index d41c0b4..caab152 100644
--- a/core/java/android/net/vcn/VcnConfig.java
+++ b/core/java/android/net/vcn/VcnConfig.java
@@ -52,12 +52,17 @@
     private static final String GATEWAY_CONNECTION_CONFIGS_KEY = "mGatewayConnectionConfigs";
     @NonNull private final Set<VcnGatewayConnectionConfig> mGatewayConnectionConfigs;
 
+    private static final String IS_TEST_MODE_PROFILE_KEY = "mIsTestModeProfile";
+    private final boolean mIsTestModeProfile;
+
     private VcnConfig(
             @NonNull String packageName,
-            @NonNull Set<VcnGatewayConnectionConfig> gatewayConnectionConfigs) {
+            @NonNull Set<VcnGatewayConnectionConfig> gatewayConnectionConfigs,
+            boolean isTestModeProfile) {
         mPackageName = packageName;
         mGatewayConnectionConfigs =
                 Collections.unmodifiableSet(new ArraySet<>(gatewayConnectionConfigs));
+        mIsTestModeProfile = isTestModeProfile;
 
         validate();
     }
@@ -77,6 +82,7 @@
                 new ArraySet<>(
                         PersistableBundleUtils.toList(
                                 gatewayConnectionConfigsBundle, VcnGatewayConnectionConfig::new));
+        mIsTestModeProfile = in.getBoolean(IS_TEST_MODE_PROFILE_KEY);
 
         validate();
     }
@@ -104,6 +110,15 @@
     }
 
     /**
+     * Returns whether or not this VcnConfig is restricted to test networks.
+     *
+     * @hide
+     */
+    public boolean isTestModeProfile() {
+        return mIsTestModeProfile;
+    }
+
+    /**
      * Serializes this object to a PersistableBundle.
      *
      * @hide
@@ -119,13 +134,14 @@
                         new ArrayList<>(mGatewayConnectionConfigs),
                         VcnGatewayConnectionConfig::toPersistableBundle);
         result.putPersistableBundle(GATEWAY_CONNECTION_CONFIGS_KEY, gatewayConnectionConfigsBundle);
+        result.putBoolean(IS_TEST_MODE_PROFILE_KEY, mIsTestModeProfile);
 
         return result;
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(mPackageName, mGatewayConnectionConfigs);
+        return Objects.hash(mPackageName, mGatewayConnectionConfigs, mIsTestModeProfile);
     }
 
     @Override
@@ -136,7 +152,8 @@
 
         final VcnConfig rhs = (VcnConfig) other;
         return mPackageName.equals(rhs.mPackageName)
-                && mGatewayConnectionConfigs.equals(rhs.mGatewayConnectionConfigs);
+                && mGatewayConnectionConfigs.equals(rhs.mGatewayConnectionConfigs)
+                && mIsTestModeProfile == rhs.mIsTestModeProfile;
     }
 
     // Parcelable methods
@@ -172,6 +189,8 @@
         @NonNull
         private final Set<VcnGatewayConnectionConfig> mGatewayConnectionConfigs = new ArraySet<>();
 
+        private boolean mIsTestModeProfile = false;
+
         public Builder(@NonNull Context context) {
             Objects.requireNonNull(context, "context was null");
 
@@ -207,13 +226,29 @@
         }
 
         /**
+         * Restricts this VcnConfig to matching with test networks (only).
+         *
+         * <p>This method is for testing only, and must not be used by apps. Calling {@link
+         * VcnManager#setVcnConfig(ParcelUuid, VcnConfig)} with a VcnConfig where test-network usage
+         * is enabled will require the MANAGE_TEST_NETWORKS permission.
+         *
+         * @return this {@link Builder} instance, for chaining
+         * @hide
+         */
+        @NonNull
+        public Builder setIsTestModeProfile() {
+            mIsTestModeProfile = true;
+            return this;
+        }
+
+        /**
          * Builds and validates the VcnConfig.
          *
          * @return an immutable VcnConfig instance
          */
         @NonNull
         public VcnConfig build() {
-            return new VcnConfig(mPackageName, mGatewayConnectionConfigs);
+            return new VcnConfig(mPackageName, mGatewayConnectionConfigs, mIsTestModeProfile);
         }
     }
 }
diff --git a/core/java/android/net/vcn/VcnGatewayConnectionConfig.java b/core/java/android/net/vcn/VcnGatewayConnectionConfig.java
index adcbe25..2df3e6c7 100644
--- a/core/java/android/net/vcn/VcnGatewayConnectionConfig.java
+++ b/core/java/android/net/vcn/VcnGatewayConnectionConfig.java
@@ -15,6 +15,8 @@
  */
 package android.net.vcn;
 
+import static android.net.ipsec.ike.IkeSessionParams.IKE_OPTION_MOBIKE;
+
 import static com.android.internal.annotations.VisibleForTesting.Visibility;
 
 import android.annotation.IntDef;
@@ -24,7 +26,7 @@
 import android.annotation.SuppressLint;
 import android.net.Network;
 import android.net.NetworkCapabilities;
-import android.net.TunnelConnectionParams;
+import android.net.ipsec.ike.IkeTunnelConnectionParams;
 import android.net.vcn.persistablebundleutils.TunnelConnectionParamsUtils;
 import android.os.PersistableBundle;
 import android.util.ArraySet;
@@ -136,7 +138,7 @@
      * <p>To ensure the device is not constantly being woken up, this retry interval MUST be greater
      * than this value.
      *
-     * @see {@link Builder#setRetryIntervalsMs()}
+     * @see {@link Builder#setRetryIntervalsMillis()}
      */
     private static final long MINIMUM_REPEATING_RETRY_INTERVAL_MS = TimeUnit.MINUTES.toMillis(15);
 
@@ -154,7 +156,7 @@
     @NonNull private final String mGatewayConnectionName;
 
     private static final String TUNNEL_CONNECTION_PARAMS_KEY = "mTunnelConnectionParams";
-    @NonNull private TunnelConnectionParams mTunnelConnectionParams;
+    @NonNull private IkeTunnelConnectionParams mTunnelConnectionParams;
 
     private static final String EXPOSED_CAPABILITIES_KEY = "mExposedCapabilities";
     @NonNull private final SortedSet<Integer> mExposedCapabilities;
@@ -171,7 +173,7 @@
     /** Builds a VcnGatewayConnectionConfig with the specified parameters. */
     private VcnGatewayConnectionConfig(
             @NonNull String gatewayConnectionName,
-            @NonNull TunnelConnectionParams tunnelConnectionParams,
+            @NonNull IkeTunnelConnectionParams tunnelConnectionParams,
             @NonNull Set<Integer> exposedCapabilities,
             @NonNull Set<Integer> underlyingCapabilities,
             @NonNull long[] retryIntervalsMs,
@@ -271,7 +273,7 @@
      * @hide
      */
     @NonNull
-    public TunnelConnectionParams getTunnelConnectionParams() {
+    public IkeTunnelConnectionParams getTunnelConnectionParams() {
         return mTunnelConnectionParams;
     }
 
@@ -337,10 +339,10 @@
     /**
      * Retrieves the configured retry intervals.
      *
-     * @see Builder#setRetryIntervalsMs(long[])
+     * @see Builder#setRetryIntervalsMillis(long[])
      */
     @NonNull
-    public long[] getRetryIntervalsMs() {
+    public long[] getRetryIntervalsMillis() {
         return Arrays.copyOf(mRetryIntervalsMs, mRetryIntervalsMs.length);
     }
 
@@ -414,7 +416,7 @@
      */
     public static final class Builder {
         @NonNull private final String mGatewayConnectionName;
-        @NonNull private final TunnelConnectionParams mTunnelConnectionParams;
+        @NonNull private final IkeTunnelConnectionParams mTunnelConnectionParams;
         @NonNull private final Set<Integer> mExposedCapabilities = new ArraySet();
         @NonNull private final Set<Integer> mUnderlyingCapabilities = new ArraySet();
         @NonNull private long[] mRetryIntervalsMs = DEFAULT_RETRY_INTERVALS_MS;
@@ -432,15 +434,21 @@
          *     VcnConfig} must be given a unique name. This name is used by the caller to
          *     distinguish between VcnGatewayConnectionConfigs configured on a single {@link
          *     VcnConfig}. This will be used as the identifier in VcnStatusCallback invocations.
-         * @param tunnelConnectionParams the tunnel connection configuration
-         * @see TunnelConnectionParams
+         * @param tunnelConnectionParams the IKE tunnel connection configuration
+         * @throws IllegalArgumentException if the provided IkeTunnelConnectionParams is not
+         *     configured to support MOBIKE
+         * @see IkeTunnelConnectionParams
          * @see VcnManager.VcnStatusCallback#onGatewayConnectionError
          */
         public Builder(
                 @NonNull String gatewayConnectionName,
-                @NonNull TunnelConnectionParams tunnelConnectionParams) {
+                @NonNull IkeTunnelConnectionParams tunnelConnectionParams) {
             Objects.requireNonNull(gatewayConnectionName, "gatewayConnectionName was null");
             Objects.requireNonNull(tunnelConnectionParams, "tunnelConnectionParams was null");
+            if (!tunnelConnectionParams.getIkeSessionParams().hasIkeOption(IKE_OPTION_MOBIKE)) {
+                throw new IllegalArgumentException(
+                        "MOBIKE must be configured for the provided IkeSessionParams");
+            }
 
             mGatewayConnectionName = gatewayConnectionName;
             mTunnelConnectionParams = tunnelConnectionParams;
@@ -550,7 +558,7 @@
          * @see VcnManager for additional discussion on fail-safe mode
          */
         @NonNull
-        public Builder setRetryIntervalsMs(@NonNull long[] retryIntervalsMs) {
+        public Builder setRetryIntervalsMillis(@NonNull long[] retryIntervalsMs) {
             validateRetryInterval(retryIntervalsMs);
 
             mRetryIntervalsMs = retryIntervalsMs;
diff --git a/core/java/android/net/vcn/VcnNetworkPolicyResult.java b/core/java/android/net/vcn/VcnNetworkPolicyResult.java
index 5e93820..14e70cf 100644
--- a/core/java/android/net/vcn/VcnNetworkPolicyResult.java
+++ b/core/java/android/net/vcn/VcnNetworkPolicyResult.java
@@ -87,6 +87,16 @@
                 && mNetworkCapabilities.equals(that.mNetworkCapabilities);
     }
 
+    @Override
+    public String toString() {
+        return "VcnNetworkPolicyResult { "
+                + "mIsTeardownRequested = "
+                + mIsTearDownRequested
+                + ", mNetworkCapabilities"
+                + mNetworkCapabilities
+                + " }";
+    }
+
     /** {@inheritDoc} */
     @Override
     public int describeContents() {
diff --git a/core/java/android/net/vcn/VcnTransportInfo.java b/core/java/android/net/vcn/VcnTransportInfo.java
index 4d8cf91..0e9ccf1 100644
--- a/core/java/android/net/vcn/VcnTransportInfo.java
+++ b/core/java/android/net/vcn/VcnTransportInfo.java
@@ -16,14 +16,23 @@
 
 package android.net.vcn;
 
+import static android.net.NetworkCapabilities.REDACT_ALL;
+import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS;
+import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+
+import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE;
+
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.net.NetworkCapabilities;
 import android.net.TransportInfo;
 import android.net.wifi.WifiInfo;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.telephony.SubscriptionManager;
 
+import com.android.internal.annotations.VisibleForTesting;
+
 import java.util.Objects;
 
 /**
@@ -37,28 +46,41 @@
  * SubscriptionManager#INVALID_SUBSCRIPTION_ID}. If the underlying Network is Cellular, the WifiInfo
  * will be {@code null}.
  *
+ * <p>Receipt of a VcnTransportInfo requires the NETWORK_SETTINGS permission; else the entire
+ * VcnTransportInfo instance will be redacted.
+ *
  * @hide
  */
 public class VcnTransportInfo implements TransportInfo, Parcelable {
     @Nullable private final WifiInfo mWifiInfo;
     private final int mSubId;
 
+    /**
+     * The redaction scheme to use when parcelling.
+     *
+     * <p>The TransportInfo/NetworkCapabilities redaction mechanisms rely on redaction being
+     * performed at parcelling time. This means that the redaction scheme must be stored for later
+     * use.
+     *
+     * <p>Since the redaction scheme itself is not parcelled, this field is listed as a transient.
+     *
+     * <p>Defaults to REDACT_ALL when constructed using public constructors, or creating from
+     * parcels.
+     */
+    private final transient long mRedactions;
+
     public VcnTransportInfo(@NonNull WifiInfo wifiInfo) {
-        this(wifiInfo, SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+        this(wifiInfo, INVALID_SUBSCRIPTION_ID, REDACT_ALL);
     }
 
     public VcnTransportInfo(int subId) {
-        this(null /* wifiInfo */, subId);
+        this(null /* wifiInfo */, subId, REDACT_ALL);
     }
 
-    private VcnTransportInfo(@Nullable WifiInfo wifiInfo, int subId) {
-        if (wifiInfo == null && subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
-            throw new IllegalArgumentException(
-                    "VcnTransportInfo requires either non-null WifiInfo or valid subId");
-        }
-
+    private VcnTransportInfo(@Nullable WifiInfo wifiInfo, int subId, long redactions) {
         mWifiInfo = wifiInfo;
         mSubId = subId;
+        mRedactions = redactions;
     }
 
     /**
@@ -86,8 +108,19 @@
         return mSubId;
     }
 
+    /**
+     * Gets the redaction scheme
+     *
+     * @hide
+     */
+    @VisibleForTesting(visibility = PRIVATE)
+    public long getRedaction() {
+        return mRedactions;
+    }
+
     @Override
     public int hashCode() {
+        // mRedactions not hashed, as it is a transient, for control of parcelling
         return Objects.hash(mWifiInfo, mSubId);
     }
 
@@ -96,6 +129,7 @@
         if (!(o instanceof VcnTransportInfo)) return false;
         final VcnTransportInfo that = (VcnTransportInfo) o;
 
+        // mRedactions not compared, as it is a transient, for control of parcelling
         return Objects.equals(mWifiInfo, that.mWifiInfo) && mSubId == that.mSubId;
     }
 
@@ -105,17 +139,59 @@
         return 0;
     }
 
+    @Override
+    @NonNull
+    public TransportInfo makeCopy(long redactions) {
+        return new VcnTransportInfo(
+                mWifiInfo == null ? null : mWifiInfo.makeCopy(redactions), mSubId, redactions);
+    }
+
+    @Override
+    public long getApplicableRedactions() {
+        long redactions = REDACT_FOR_NETWORK_SETTINGS;
+
+        // Add additional wifi redactions if necessary
+        if (mWifiInfo != null) {
+            redactions |= mWifiInfo.getApplicableRedactions();
+        }
+
+        return redactions;
+    }
+
+    private boolean shouldParcelNetworkSettingsFields() {
+        return (mRedactions & NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS) == 0;
+    }
+
     /** {@inheritDoc} */
     @Override
-    public void writeToParcel(@NonNull Parcel dest, int flags) {}
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeInt(shouldParcelNetworkSettingsFields() ? mSubId : INVALID_SUBSCRIPTION_ID);
+        dest.writeParcelable(
+                shouldParcelNetworkSettingsFields() ? (Parcelable) mWifiInfo : null, flags);
+    }
+
+    @Override
+    public String toString() {
+        return "VcnTransportInfo { mWifiInfo = " + mWifiInfo + ", mSubId = " + mSubId + " }";
+    }
 
     /** Implement the Parcelable interface */
     public static final @NonNull Creator<VcnTransportInfo> CREATOR =
             new Creator<VcnTransportInfo>() {
                 public VcnTransportInfo createFromParcel(Parcel in) {
-                    // return null instead of a default VcnTransportInfo to avoid leaking
-                    // information about this being a VCN Network (instead of macro cellular, etc)
-                    return null;
+                    final int subId = in.readInt();
+                    final WifiInfo wifiInfo = in.readParcelable(null);
+
+                    // If all fields are their null values, return null TransportInfo to avoid
+                    // leaking information about this being a VCN Network (instead of macro
+                    // cellular, etc)
+                    if (wifiInfo == null && subId == INVALID_SUBSCRIPTION_ID) {
+                        return null;
+                    }
+
+                    // Prevent further forwarding by redacting everything in future parcels from
+                    // this VcnTransportInfo
+                    return new VcnTransportInfo(wifiInfo, subId, REDACT_ALL);
                 }
 
                 public VcnTransportInfo[] newArray(int size) {
diff --git a/core/java/android/net/vcn/VcnUnderlyingNetworkPolicy.java b/core/java/android/net/vcn/VcnUnderlyingNetworkPolicy.java
index b47d564..b0d4f3b 100644
--- a/core/java/android/net/vcn/VcnUnderlyingNetworkPolicy.java
+++ b/core/java/android/net/vcn/VcnUnderlyingNetworkPolicy.java
@@ -85,6 +85,11 @@
         return mVcnNetworkPolicyResult.equals(that.mVcnNetworkPolicyResult);
     }
 
+    @Override
+    public String toString() {
+        return mVcnNetworkPolicyResult.toString();
+    }
+
     /** {@inheritDoc} */
     @Override
     public int describeContents() {
diff --git a/core/java/android/net/vcn/persistablebundleutils/TunnelConnectionParamsUtils.java b/core/java/android/net/vcn/persistablebundleutils/TunnelConnectionParamsUtils.java
index 690e4e7..4bc5b49 100644
--- a/core/java/android/net/vcn/persistablebundleutils/TunnelConnectionParamsUtils.java
+++ b/core/java/android/net/vcn/persistablebundleutils/TunnelConnectionParamsUtils.java
@@ -16,7 +16,6 @@
 package android.net.vcn.persistablebundleutils;
 
 import android.annotation.NonNull;
-import android.net.TunnelConnectionParams;
 import android.net.ipsec.ike.IkeSessionParams;
 import android.net.ipsec.ike.IkeTunnelConnectionParams;
 import android.net.ipsec.ike.TunnelModeChildSessionParams;
@@ -25,7 +24,7 @@
 import java.util.Objects;
 
 /**
- * Utility class to convert TunnelConnectionParams to/from PersistableBundle
+ * Utility class to convert Tunnel Connection Params to/from PersistableBundle
  *
  * @hide
  */
@@ -34,30 +33,28 @@
 
     private static final String PARAMS_TYPE_IKE = "IKE";
 
-    /** Serializes an TunnelConnectionParams to a PersistableBundle. */
+    /** Serializes an IkeTunnelConnectionParams to a PersistableBundle. */
     @NonNull
-    public static PersistableBundle toPersistableBundle(@NonNull TunnelConnectionParams params) {
+    public static PersistableBundle toPersistableBundle(@NonNull IkeTunnelConnectionParams params) {
         final PersistableBundle result = new PersistableBundle();
 
-        if (params instanceof IkeTunnelConnectionParams) {
-            result.putPersistableBundle(
-                    PARAMS_TYPE_IKE,
-                    IkeTunnelConnectionParamsUtils.serializeIkeParams(
-                            (IkeTunnelConnectionParams) params));
-            return result;
-        } else {
-            throw new UnsupportedOperationException("Invalid TunnelConnectionParams type");
-        }
+        result.putPersistableBundle(
+                PARAMS_TYPE_IKE,
+                IkeTunnelConnectionParamsUtils.serializeIkeParams(
+                        (IkeTunnelConnectionParams) params));
+        return result;
     }
 
-    /** Constructs an TunnelConnectionParams by deserializing a PersistableBundle. */
+    /** Constructs an IkeTunnelConnectionParams by deserializing a PersistableBundle. */
     @NonNull
-    public static TunnelConnectionParams fromPersistableBundle(@NonNull PersistableBundle in) {
+    public static IkeTunnelConnectionParams fromPersistableBundle(@NonNull PersistableBundle in) {
         Objects.requireNonNull(in, "PersistableBundle was null");
 
         if (in.keySet().size() != EXPECTED_BUNDLE_KEY_CNT) {
             throw new IllegalArgumentException(
-                    "Expect PersistableBundle to have one element but found: " + in.keySet());
+                    String.format(
+                            "Expect PersistableBundle to have %d element but found: %d",
+                            EXPECTED_BUNDLE_KEY_CNT, in.keySet()));
         }
 
         if (in.get(PARAMS_TYPE_IKE) != null) {
@@ -66,7 +63,7 @@
         }
 
         throw new IllegalArgumentException(
-                "Invalid TunnelConnectionParams type " + in.keySet().iterator().next());
+                "Invalid Tunnel Connection Params type " + in.keySet().iterator().next());
     }
 
     private static final class IkeTunnelConnectionParamsUtils {
diff --git a/core/java/android/nfc/NfcControllerAlwaysOnListener.java b/core/java/android/nfc/NfcControllerAlwaysOnListener.java
index 96707bb..6ae58fd 100644
--- a/core/java/android/nfc/NfcControllerAlwaysOnListener.java
+++ b/core/java/android/nfc/NfcControllerAlwaysOnListener.java
@@ -52,6 +52,14 @@
      */
     public void register(@NonNull Executor executor,
             @NonNull ControllerAlwaysOnListener listener) {
+        try {
+            if (!mAdapter.isControllerAlwaysOnSupported()) {
+                return;
+            }
+        } catch (RemoteException e) {
+            Log.w(TAG, "Failed to register");
+            return;
+        }
         synchronized (this) {
             if (mListenerMap.containsKey(listener)) {
                 return;
@@ -75,6 +83,14 @@
      * @param listener user implementation of the {@link ControllerAlwaysOnListener}
      */
     public void unregister(@NonNull ControllerAlwaysOnListener listener) {
+        try {
+            if (!mAdapter.isControllerAlwaysOnSupported()) {
+                return;
+            }
+        } catch (RemoteException e) {
+            Log.w(TAG, "Failed to unregister");
+            return;
+        }
         synchronized (this) {
             if (!mListenerMap.containsKey(listener)) {
                 return;
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index e47ffcc..5017d9e 100755
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -424,7 +424,8 @@
          * Magic version number for a current development build, which has
          * not yet turned into an official release.
          */
-        public static final int CUR_DEVELOPMENT = VMRuntime.SDK_VERSION_CUR_DEVELOPMENT;
+        // This must match VMRuntime.SDK_VERSION_CUR_DEVELOPMENT.
+        public static final int CUR_DEVELOPMENT = 10000;
 
         /**
          * October 2008: The original, first, version of Android.  Yay!
@@ -1311,6 +1312,7 @@
      * selinux into "permissive" mode in particular.
      * @hide
      */
+    @UnsupportedAppUsage
     public static final boolean IS_DEBUGGABLE =
             SystemProperties.getInt("ro.debuggable", 0) == 1;
 
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java
index 1e60f74..a7516a4 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -74,8 +74,9 @@
      *
      * @deprecated Accurate counting is a burden on the runtime and may be removed.
      */
+    // This must match VMDebug.TRACE_COUNT_ALLOCS.
     @Deprecated
-    public static final int TRACE_COUNT_ALLOCS  = VMDebug.TRACE_COUNT_ALLOCS;
+    public static final int TRACE_COUNT_ALLOCS  = 1;
 
     /**
      * Flags for printLoadedClasses().  Default behavior is to only show
diff --git a/core/java/android/os/IRecoverySystem.aidl b/core/java/android/os/IRecoverySystem.aidl
index 9368b68..88bdb7f 100644
--- a/core/java/android/os/IRecoverySystem.aidl
+++ b/core/java/android/os/IRecoverySystem.aidl
@@ -23,6 +23,7 @@
 /** @hide */
 
 interface IRecoverySystem {
+    boolean allocateSpaceForUpdate(in String packageFilePath);
     boolean uncrypt(in String packageFile, IRecoverySystemProgressListener listener);
     boolean setupBcb(in String command);
     boolean clearBcb();
diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java
index 051447f..944b717 100644
--- a/core/java/android/os/RecoverySystem.java
+++ b/core/java/android/os/RecoverySystem.java
@@ -672,6 +672,14 @@
             if (!rs.setupBcb(command)) {
                 throw new IOException("Setup BCB failed");
             }
+            try {
+                if (!rs.allocateSpaceForUpdate(packageFile)) {
+                    throw new IOException("Failed to allocate space for update "
+                            + packageFile.getAbsolutePath());
+                }
+            } catch (RemoteException e) {
+                e.rethrowAsRuntimeException();
+            }
 
             // Having set up the BCB (bootloader control block), go ahead and reboot
             PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
@@ -1392,6 +1400,13 @@
     }
 
     /**
+     * Talks to RecoverySystemService via Binder to allocate space
+     */
+    private boolean allocateSpaceForUpdate(File packageFile) throws RemoteException {
+        return mService.allocateSpaceForUpdate(packageFile.getAbsolutePath());
+    }
+
+    /**
      * Talks to RecoverySystemService via Binder to clear up the BCB.
      */
     private boolean clearBcb() {
diff --git a/core/java/android/os/VintfObject.java b/core/java/android/os/VintfObject.java
index 7af8f71..bf0b655 100644
--- a/core/java/android/os/VintfObject.java
+++ b/core/java/android/os/VintfObject.java
@@ -16,6 +16,7 @@
 
 package android.os;
 
+import android.annotation.NonNull;
 import android.annotation.TestApi;
 import android.util.Slog;
 
@@ -112,6 +113,15 @@
     public static native String getSepolicyVersion();
 
     /**
+     * @return the PLATFORM_SEPOLICY_VERSION build flag available in framework
+     * compatibility matrix.
+     *
+     * @hide
+     */
+    @TestApi
+    public static native @NonNull String getPlatformSepolicyVersion();
+
+    /**
      * @return a list of VNDK snapshots supported by the framework, as
      * specified in framework manifest. For example,
      * [("27", ["libjpeg.so", "libbase.so"]),
diff --git a/core/java/android/print/PrintAttributes.java b/core/java/android/print/PrintAttributes.java
index c198848..f508101 100644
--- a/core/java/android/print/PrintAttributes.java
+++ b/core/java/android/print/PrintAttributes.java
@@ -837,8 +837,8 @@
                 new MediaSize("JPN_YOU4", "android",
                         R.string.mediasize_japanese_you4, 4134, 9252);
         /** Japanese Photo L media size: 89mm x 127mm (3.5 x 5") */
-        public static final @NonNull MediaSize OE_PHOTO_L =
-                new MediaSize("OE_PHOTO_L", "android",
+        public static final @NonNull MediaSize JPN_OE_PHOTO_L =
+                new MediaSize("JPN_OE_PHOTO_L", "android",
                         R.string.mediasize_japanese_l, 3500, 5000);
 
         private final @NonNull String mId;
diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java
index a3a910a..d22f7e3 100644
--- a/core/java/android/provider/Telephony.java
+++ b/core/java/android/provider/Telephony.java
@@ -5327,5 +5327,29 @@
          * @hide
          */
         public static final String COLUMN_RCS_CONFIG = "rcs_config";
+
+        /**
+         * TelephonyProvider column name for device to device sharing status.
+         *
+         * @hide
+         */
+        public static final String COLUMN_D2D_STATUS_SHARING = "d2d_sharing_status";
+
+        /**
+         * TelephonyProvider column name for VoIMS provisioning. Default is 0.
+         * <P>Type: INTEGER </P>
+         *
+         * @hide
+         */
+        public static final String COLUMN_VOIMS_OPT_IN_STATUS = "voims_opt_in_status";
+
+        /**
+         * TelephonyProvider column name for information selected contacts that allow device to
+         * device sharing.
+         *
+         * @hide
+         */
+        public static final String COLUMN_D2D_STATUS_SHARING_SELECTED_CONTACTS =
+                "d2d_sharing_contacts";
     }
 }
diff --git a/core/java/android/security/keymaster/KeymasterDefs.java b/core/java/android/security/keymaster/KeymasterDefs.java
index 5a89cdf..0b11aeb 100644
--- a/core/java/android/security/keymaster/KeymasterDefs.java
+++ b/core/java/android/security/keymaster/KeymasterDefs.java
@@ -66,9 +66,6 @@
     public static final int KM_TAG_CALLER_NONCE = Tag.CALLER_NONCE; // KM_BOOL | 7;
     public static final int KM_TAG_MIN_MAC_LENGTH = Tag.MIN_MAC_LENGTH; // KM_UINT | 8;
 
-    public static final int KM_TAG_BLOB_USAGE_REQUIREMENTS =
-            Tag.BLOB_USAGE_REQUIREMENTS; // KM_ENUM | 705;
-
     public static final int KM_TAG_RSA_PUBLIC_EXPONENT = Tag.RSA_PUBLIC_EXPONENT; // KM_ULONG | 200;
     public static final int KM_TAG_INCLUDE_UNIQUE_ID = Tag.INCLUDE_UNIQUE_ID; // KM_BOOL | 202;
 
diff --git a/core/java/android/util/JsonReader.java b/core/java/android/util/JsonReader.java
index 50f63f8..c75e238 100644
--- a/core/java/android/util/JsonReader.java
+++ b/core/java/android/util/JsonReader.java
@@ -16,7 +16,7 @@
 
 package android.util;
 
-import libcore.internal.StringPool;
+import com.android.internal.util.StringPool;
 
 import java.io.Closeable;
 import java.io.EOFException;
diff --git a/core/java/android/uwb/AdapterStateListener.java b/core/java/android/uwb/AdapterStateListener.java
index b990095..91847f7 100644
--- a/core/java/android/uwb/AdapterStateListener.java
+++ b/core/java/android/uwb/AdapterStateListener.java
@@ -68,8 +68,7 @@
                     mIsRegistered = true;
                 } catch (RemoteException e) {
                     Log.w(TAG, "Failed to register adapter state callback");
-                    executor.execute(() -> callback.onStateChanged(mAdapterState,
-                            AdapterStateCallback.STATE_CHANGED_REASON_ERROR_UNKNOWN));
+                    throw e.rethrowFromSystemServer();
                 }
             } else {
                 sendCurrentState(callback);
@@ -95,6 +94,7 @@
                     mAdapter.unregisterAdapterStateCallbacks(this);
                 } catch (RemoteException e) {
                     Log.w(TAG, "Failed to unregister AdapterStateCallback with service");
+                    throw e.rethrowFromSystemServer();
                 }
                 mIsRegistered = false;
             }
@@ -115,24 +115,24 @@
                     mAdapter.setEnabled(isEnabled);
                 } catch (RemoteException e) {
                     Log.w(TAG, "Failed to set adapter state");
-                    sendErrorState();
+                    throw e.rethrowFromSystemServer();
                 }
             }
         }
     }
 
-    private void sendErrorState() {
+    /**
+     * Gets the adapter enabled state
+     *
+     * @return integer representing adapter enabled state
+     */
+    public int getAdapterState() {
         synchronized (this) {
-            for (AdapterStateCallback callback: mCallbackMap.keySet()) {
-                Executor executor = mCallbackMap.get(callback);
-
-                final long identity = Binder.clearCallingIdentity();
-                try {
-                    executor.execute(() -> callback.onStateChanged(
-                            mAdapterState, mAdapterStateChangeReason));
-                } finally {
-                    Binder.restoreCallingIdentity(identity);
-                }
+            try {
+                return mAdapter.getAdapterState();
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed to get adapter state");
+                throw e.rethrowFromSystemServer();
             }
         }
     }
diff --git a/core/java/android/uwb/IUwbAdapter.aidl b/core/java/android/uwb/IUwbAdapter.aidl
index 5804d04..e02e5eb 100644
--- a/core/java/android/uwb/IUwbAdapter.aidl
+++ b/core/java/android/uwb/IUwbAdapter.aidl
@@ -158,6 +158,18 @@
      */
     void setEnabled(boolean enabled);
 
+   /**
+    * Returns the current enabled/disabled UWB state.
+    *
+    * Possible values are:
+    * IUwbAdapterState#STATE_DISABLED
+    * IUwbAdapterState#STATE_ENABLED_ACTIVE
+    * IUwbAdapterState#STATE_ENABLED_INACTIVE
+    *
+    * @return value representing enabled/disabled UWB state.
+    */
+   int getAdapterState();
+
   /**
    * The maximum allowed time to open a ranging session.
    */
diff --git a/core/java/android/uwb/UwbManager.java b/core/java/android/uwb/UwbManager.java
index 9116c49..4edecda 100644
--- a/core/java/android/uwb/UwbManager.java
+++ b/core/java/android/uwb/UwbManager.java
@@ -175,7 +175,7 @@
      * <p>The provided callback will be invoked by the given {@link Executor}.
      *
      * <p>When first registering a callback, the callbacks's
-     * {@link AdapterStateCallback#onStateChanged(boolean, int)} is immediately invoked to indicate
+     * {@link AdapterStateCallback#onStateChanged(int, int)} is immediately invoked to indicate
      * the current state of the underlying UWB adapter with the most recent
      * {@link AdapterStateCallback.StateChangedReason} that caused the change.
      *
@@ -272,6 +272,21 @@
     }
 
     /**
+     * Returns the current enabled/disabled state for UWB.
+     *
+     * Possible values are:
+     * AdapterStateCallback#STATE_DISABLED
+     * AdapterStateCallback#STATE_ENABLED_INACTIVE
+     * AdapterStateCallback#STATE_ENABLED_ACTIVE
+     *
+     * @return value representing current enabled/disabled state for UWB.
+     * @hide
+     */
+    public @AdapterStateCallback.State int getAdapterState() {
+        return mAdapterStateListener.getAdapterState();
+    }
+
+    /**
      * Disables or enables UWB for a user
      *
      * @param enabled value representing intent to disable or enable UWB. If true any subsequent
diff --git a/core/java/com/android/internal/annotations/GuardedBy.java b/core/java/com/android/internal/annotations/GuardedBy.java
deleted file mode 100644
index 0e63214..0000000
--- a/core/java/com/android/internal/annotations/GuardedBy.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2012 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 com.android.internal.annotations;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Annotation type used to mark a method or field that can only be accessed when
- * holding the referenced locks.
- */
-@Target({ ElementType.FIELD, ElementType.METHOD })
-@Retention(RetentionPolicy.CLASS)
-public @interface GuardedBy {
-    String[] value();
-}
diff --git a/core/java/com/android/internal/annotations/Immutable.java b/core/java/com/android/internal/annotations/Immutable.java
deleted file mode 100644
index b424275..0000000
--- a/core/java/com/android/internal/annotations/Immutable.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2012 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 com.android.internal.annotations;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Annotation type used to mark a class which is immutable.
- */
-@Target(ElementType.TYPE)
-@Retention(RetentionPolicy.CLASS)
-public @interface Immutable {
-}
diff --git a/core/java/com/android/internal/annotations/VisibleForTesting.java b/core/java/com/android/internal/annotations/VisibleForTesting.java
deleted file mode 100644
index 99512ac6..0000000
--- a/core/java/com/android/internal/annotations/VisibleForTesting.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2012 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 com.android.internal.annotations;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Denotes that the class, method or field has its visibility relaxed so
- * that unit tests can access it.
- * <p/>
- * The <code>visibility</code> argument can be used to specific what the original
- * visibility should have been if it had not been made public or package-private for testing.
- * The default is to consider the element private.
- */
-@Retention(RetentionPolicy.CLASS)
-public @interface VisibleForTesting {
-    /**
-     * Intended visibility if the element had not been made public or package-private for
-     * testing.
-     */
-    enum Visibility {
-        /** The element should be considered protected. */
-        PROTECTED,
-        /** The element should be considered package-private. */
-        PACKAGE,
-        /** The element should be considered private. */
-        PRIVATE
-    }
-
-    /**
-     * Intended visibility if the element had not been made public or package-private for testing.
-     * If not specified, one should assume the element originally intended to be private.
-     */
-    Visibility visibility() default Visibility.PRIVATE;
-}
diff --git a/core/java/com/android/internal/colorextraction/OWNERS b/core/java/com/android/internal/colorextraction/OWNERS
new file mode 100644
index 0000000..ffade1e
--- /dev/null
+++ b/core/java/com/android/internal/colorextraction/OWNERS
@@ -0,0 +1,3 @@
+dupin@google.com
+cinek@google.com
+jamesoleary@google.com
diff --git a/core/java/com/android/internal/compat/CompatibilityChangeConfig.java b/core/java/com/android/internal/compat/CompatibilityChangeConfig.java
index 36bc229..182dba7 100644
--- a/core/java/com/android/internal/compat/CompatibilityChangeConfig.java
+++ b/core/java/com/android/internal/compat/CompatibilityChangeConfig.java
@@ -39,14 +39,14 @@
      * Changes forced to be enabled.
      */
     public Set<Long> enabledChanges() {
-        return mChangeConfig.forceEnabledSet();
+        return mChangeConfig.getEnabledSet();
     }
 
     /**
      * Changes forced to be disabled.
      */
     public Set<Long> disabledChanges() {
-        return mChangeConfig.forceDisabledSet();
+        return mChangeConfig.getDisabledSet();
     }
 
     /**
@@ -84,8 +84,8 @@
 
     @Override
     public void writeToParcel(Parcel dest, int flags) {
-        long[] enabled = mChangeConfig.forceEnabledChangesArray();
-        long[] disabled = mChangeConfig.forceDisabledChangesArray();
+        long[] enabled = mChangeConfig.getEnabledChangesArray();
+        long[] disabled = mChangeConfig.getDisabledChangesArray();
 
         dest.writeLongArray(enabled);
         dest.writeLongArray(disabled);
diff --git a/core/java/com/android/internal/annotations/VisibleForNative.java b/core/java/com/android/internal/compat/CompatibilityOverridesToRemoveConfig.aidl
similarity index 60%
rename from core/java/com/android/internal/annotations/VisibleForNative.java
rename to core/java/com/android/internal/compat/CompatibilityOverridesToRemoveConfig.aidl
index e6a3fc6..441e553 100644
--- a/core/java/com/android/internal/annotations/VisibleForNative.java
+++ b/core/java/com/android/internal/compat/CompatibilityOverridesToRemoveConfig.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 The Android Open Source Project
+ * 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.
@@ -14,15 +14,6 @@
  * limitations under the License.
  */
 
-package com.android.internal.annotations;
+package com.android.internal.compat;
 
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Denotes that the class, method or field has its visibility relaxed so
- * that native code can access it.
- */
-@Retention(RetentionPolicy.CLASS)
-public @interface VisibleForNative {
-}
+parcelable CompatibilityOverridesToRemoveConfig;
diff --git a/core/java/com/android/internal/compat/CompatibilityOverridesToRemoveConfig.java b/core/java/com/android/internal/compat/CompatibilityOverridesToRemoveConfig.java
new file mode 100644
index 0000000..642f79c
--- /dev/null
+++ b/core/java/com/android/internal/compat/CompatibilityOverridesToRemoveConfig.java
@@ -0,0 +1,72 @@
+/*
+ * 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 com.android.internal.compat;
+
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Parcelable containing compat config change IDs for which to remove overrides for a given
+ * application.
+ * @hide
+ */
+public final class CompatibilityOverridesToRemoveConfig implements Parcelable {
+    public final Set<Long> changeIds;
+
+    public CompatibilityOverridesToRemoveConfig(Set<Long> changeIds) {
+        this.changeIds = changeIds;
+    }
+
+    private CompatibilityOverridesToRemoveConfig(Parcel in) {
+        int keyCount = in.readInt();
+        changeIds = new HashSet<>();
+        for (int i = 0; i < keyCount; i++) {
+            changeIds.add(in.readLong());
+        }
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(changeIds.size());
+        for (Long changeId : changeIds) {
+            dest.writeLong(changeId);
+        }
+    }
+
+    public static final Creator<CompatibilityOverridesToRemoveConfig> CREATOR =
+            new Creator<CompatibilityOverridesToRemoveConfig>() {
+
+                @Override
+                public CompatibilityOverridesToRemoveConfig createFromParcel(Parcel in) {
+                    return new CompatibilityOverridesToRemoveConfig(in);
+                }
+
+                @Override
+                public CompatibilityOverridesToRemoveConfig[] newArray(int size) {
+                    return new CompatibilityOverridesToRemoveConfig[size];
+                }
+            };
+}
diff --git a/core/java/com/android/internal/compat/IPlatformCompat.aidl b/core/java/com/android/internal/compat/IPlatformCompat.aidl
index 78d1d22..c9f1704 100644
--- a/core/java/com/android/internal/compat/IPlatformCompat.aidl
+++ b/core/java/com/android/internal/compat/IPlatformCompat.aidl
@@ -22,6 +22,7 @@
 
 parcelable CompatibilityChangeConfig;
 parcelable CompatibilityOverrideConfig;
+parcelable CompatibilityOverridesToRemoveConfig;
 parcelable CompatibilityChangeInfo;
 /**
  * Platform private API for talking with the PlatformCompat service.
@@ -204,6 +205,27 @@
     void clearOverrideForTest(long changeId, String packageName);
 
     /**
+     * Restores the default behaviour for compatibility changes on release builds.
+     *
+     * <p>The caller to this API needs to hold
+     * {@code android.permission.OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD} and all change ids
+     * in {@code overridesToRemove} need to annotated with
+     * {@link android.compat.annotation.Overridable}.
+     *
+     * A release build in this definition means that {@link android.os.Build#IS_DEBUGGABLE} needs to
+     * be {@code false}.
+     *
+     * <p>Note that this does not kill the app, and therefore overrides read from the app process
+     * will not be updated. Overrides read from the system process do take effect.
+     *
+     * @param overridesToRemove   parcelable containing the compat change overrides to be removed
+     * @param packageName         the package name of the app whose changes will be restored to the
+     *                            default behaviour
+     * @throws SecurityException if overriding changes is not permitted
+     */
+    void removeOverridesOnReleaseBuilds(in CompatibilityOverridesToRemoveConfig overridesToRemove, in String packageName);
+
+    /**
      * Enables all compatibility changes that have enabledSinceTargetSdk ==
      * {@param targetSdkVersion} for an app, subject to the policy.
      *
diff --git a/core/java/com/android/internal/graphics/OWNERS b/core/java/com/android/internal/graphics/OWNERS
new file mode 100644
index 0000000..5851cbb
--- /dev/null
+++ b/core/java/com/android/internal/graphics/OWNERS
@@ -0,0 +1 @@
+include /graphics/java/android/graphics/OWNERS
\ No newline at end of file
diff --git a/core/java/com/android/internal/os/BinderCallsStats.java b/core/java/com/android/internal/os/BinderCallsStats.java
index 0fb2728..dbba469 100644
--- a/core/java/com/android/internal/os/BinderCallsStats.java
+++ b/core/java/com/android/internal/os/BinderCallsStats.java
@@ -54,6 +54,7 @@
     public static final int PERIODIC_SAMPLING_INTERVAL_DEFAULT = 1000;
     public static final boolean DEFAULT_TRACK_SCREEN_INTERACTIVE = false;
     public static final boolean DEFAULT_TRACK_DIRECT_CALLING_UID = true;
+    public static final boolean DEFAULT_COLLECT_LATENCY_DATA = false;
     public static final int MAX_BINDER_CALL_STATS_COUNT_DEFAULT = 1500;
     private static final String DEBUG_ENTRY_PREFIX = "__DEBUG_";
 
@@ -89,19 +90,27 @@
     private boolean mAddDebugEntries = false;
     private boolean mTrackDirectCallingUid = DEFAULT_TRACK_DIRECT_CALLING_UID;
     private boolean mTrackScreenInteractive = DEFAULT_TRACK_SCREEN_INTERACTIVE;
+    private boolean mCollectLatencyData = DEFAULT_COLLECT_LATENCY_DATA;
 
     private CachedDeviceState.Readonly mDeviceState;
     private CachedDeviceState.TimeInStateStopwatch mBatteryStopwatch;
 
+    private BinderLatencyObserver mLatencyObserver;
+
     /** Injector for {@link BinderCallsStats}. */
     public static class Injector {
         public Random getRandomGenerator() {
             return new Random();
         }
+
+        public BinderLatencyObserver getLatencyObserver() {
+            return new BinderLatencyObserver(new BinderLatencyObserver.Injector());
+        }
     }
 
     public BinderCallsStats(Injector injector) {
         this.mRandom = injector.getRandomGenerator();
+        this.mLatencyObserver = injector.getLatencyObserver();
     }
 
     public void setDeviceState(@NonNull CachedDeviceState.Readonly deviceState) {
@@ -128,7 +137,10 @@
         if (shouldRecordDetailedData()) {
             s.cpuTimeStarted = getThreadTimeMicro();
             s.timeStarted = getElapsedRealtimeMicro();
+        } else if (mCollectLatencyData) {
+            s.timeStarted = getElapsedRealtimeMicro();
         }
+
         return s;
     }
 
@@ -153,6 +165,10 @@
 
     private void processCallEnded(CallSession s,
             int parcelRequestSize, int parcelReplySize, int workSourceUid) {
+        if (mCollectLatencyData) {
+            mLatencyObserver.callEnded(s);
+        }
+
         // Non-negative time signals we need to record data for this call.
         final boolean recordCall = s.cpuTimeStarted >= 0;
         final long duration;
@@ -555,6 +571,17 @@
         }
     }
 
+    /** Whether to collect latency histograms. */
+    public void setCollectLatencyData(boolean collectLatencyData) {
+        mCollectLatencyData = collectLatencyData;
+    }
+
+    /** Whether to collect latency histograms. */
+    @VisibleForTesting
+    public boolean getCollectLatencyData() {
+        return mCollectLatencyData;
+    }
+
     public void reset() {
         synchronized (mLock) {
             mCallStatsCount = 0;
@@ -565,6 +592,8 @@
             if (mBatteryStopwatch != null) {
                 mBatteryStopwatch.reset();
             }
+            // Do not reset the latency observer as binder stats and latency will be pushed to
+            // statsd at different intervals so the resets should not be coupled.
         }
     }
 
@@ -767,6 +796,10 @@
         return mExceptionCounts;
     }
 
+    public BinderLatencyObserver getLatencyObserver() {
+        return mLatencyObserver;
+    }
+
     @VisibleForTesting
     public static <T> List<T> getHighestValues(List<T> list, ToDoubleFunction<T> toDouble,
             double percentile) {
diff --git a/core/java/com/android/internal/os/BinderLatencyBuckets.java b/core/java/com/android/internal/os/BinderLatencyBuckets.java
new file mode 100644
index 0000000..bdee4ca
--- /dev/null
+++ b/core/java/com/android/internal/os/BinderLatencyBuckets.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2017 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 com.android.internal.os;
+
+import android.util.Slog;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.ArrayList;
+import java.util.Collections;
+
+/**
+ * Generates the bucket thresholds (with a custom logarithmic scale) for a histogram to store
+ * latency samples in.
+ */
+public class BinderLatencyBuckets {
+    private static final String TAG = "BinderLatencyBuckets";
+    private ArrayList<Integer> mBuckets;
+
+    /**
+     * @param bucketCount      the number of buckets the histogram should have
+     * @param firstBucketSize  the size of the first bucket (used to avoid excessive small buckets)
+     * @param scaleFactor      the rate in which each consecutive bucket increases (before rounding)
+     */
+    public BinderLatencyBuckets(int bucketCount, int firstBucketSize, float scaleFactor) {
+        mBuckets = new ArrayList<>(bucketCount - 1);
+        mBuckets.add(firstBucketSize);
+
+        // Last value and the target are disjoint as we never want to create buckets smaller than 1.
+        double lastTarget = firstBucketSize;
+        int lastValue = firstBucketSize;
+
+        // First bucket is already created and the last bucket is anything greater than the final
+        // bucket in the list, so create 'bucketCount' - 2 buckets.
+        for (int i = 1; i < bucketCount - 1; i++) {
+            // Increase the target bucket limit value by the scale factor.
+            double nextTarget = lastTarget * scaleFactor;
+
+            if (nextTarget > Integer.MAX_VALUE || lastValue == Integer.MAX_VALUE) {
+                // Do not throw an exception here as this should not affect binder calls.
+                Slog.w(TAG, "Attempted to create a bucket larger than maxint");
+                return;
+            }
+
+            if ((int) nextTarget > lastValue) {
+                // Convert the target bucket limit value to an integer.
+                mBuckets.add((int) nextTarget);
+                lastValue = (int) nextTarget;
+            } else {
+                // Avoid creating redundant buckets, so bucket size should be 1 at a minimum.
+                mBuckets.add(lastValue + 1);
+                lastValue = lastValue + 1;
+            }
+            lastTarget = nextTarget;
+        }
+    }
+
+    /** Gets the bucket index to insert the provided sample in. */
+    public int sampleToBucket(int sample) {
+        if (sample > mBuckets.get(mBuckets.size() - 1)) {
+            return mBuckets.size();
+        }
+
+        // Binary search returns the element index if it is contained in the list - in this case the
+        // correct bucket is the index after as we use [minValue, maxValue) for bucket boundaries.
+        // Otherwise, it returns (-(insertion point) - 1), where insertion point is the point where
+        // to insert the element so that the array remains sorted - in this case the bucket index
+        // is the insertion point.
+        int searchResult = Collections.binarySearch(mBuckets, sample);
+        return searchResult < 0 ? -(1 + searchResult) : searchResult + 1;
+    }
+
+    @VisibleForTesting
+    public ArrayList<Integer> getBuckets() {
+        return mBuckets;
+    }
+}
diff --git a/core/java/com/android/internal/os/BinderLatencyObserver.java b/core/java/com/android/internal/os/BinderLatencyObserver.java
new file mode 100644
index 0000000..59cc66d
--- /dev/null
+++ b/core/java/com/android/internal/os/BinderLatencyObserver.java
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2017 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 com.android.internal.os;
+
+import android.annotation.Nullable;
+import android.os.Binder;
+import android.os.SystemClock;
+import android.util.ArrayMap;
+import android.util.Slog;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.os.BinderInternal.CallSession;
+
+import java.util.Random;
+
+/** Collects statistics about Binder call latency per calling API and method. */
+public class BinderLatencyObserver {
+    private static final String TAG = "BinderLatencyObserver";
+    public static final int PERIODIC_SAMPLING_INTERVAL_DEFAULT = 10;
+
+    // Histogram buckets parameters.
+    public static final int BUCKET_COUNT_DEFAULT = 100;
+    public static final int FIRST_BUCKET_SIZE_DEFAULT = 5;
+    public static final float BUCKET_SCALE_FACTOR_DEFAULT = 1.125f;
+
+    @GuardedBy("mLock")
+    private final ArrayMap<LatencyDims, int[]> mLatencyHistograms = new ArrayMap<>();
+    private final Object mLock = new Object();
+
+    // Sampling period to control how often to track CPU usage. 1 means all calls, 100 means ~1 out
+    // of 100 requests.
+    private int mPeriodicSamplingInterval = PERIODIC_SAMPLING_INTERVAL_DEFAULT;
+
+    private int mBucketCount = BUCKET_COUNT_DEFAULT;
+    private int mFirstBucketSize = FIRST_BUCKET_SIZE_DEFAULT;
+    private float mBucketScaleFactor = BUCKET_SCALE_FACTOR_DEFAULT;
+
+    private final Random mRandom;
+    private BinderLatencyBuckets mLatencyBuckets;
+
+    /** Injector for {@link BinderLatencyObserver}. */
+    public static class Injector {
+        public Random getRandomGenerator() {
+            return new Random();
+        }
+    }
+
+    public BinderLatencyObserver(Injector injector) {
+        mRandom = injector.getRandomGenerator();
+        mLatencyBuckets = new BinderLatencyBuckets(
+            mBucketCount, mFirstBucketSize, mBucketScaleFactor);
+    }
+
+    /** Should be called when a Binder call completes, will store latency data. */
+    public void callEnded(@Nullable CallSession s) {
+        if (s == null || s.exceptionThrown || !shouldKeepSample()) {
+            return;
+        }
+
+        LatencyDims dims = new LatencyDims(s.binderClass, s.transactionCode);
+        long callDuration = getElapsedRealtimeMicro() - s.timeStarted;
+
+        // Find the bucket this sample should go to.
+        int bucketIdx = mLatencyBuckets.sampleToBucket(
+                callDuration > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) callDuration);
+
+        synchronized (mLock) {
+            int[] buckets = mLatencyHistograms.get(dims);
+            if (buckets == null) {
+                buckets = new int[mBucketCount];
+                mLatencyHistograms.put(dims, buckets);
+            }
+
+            // Increment the correct bucket.
+            if (buckets[bucketIdx] < Integer.MAX_VALUE) {
+                buckets[bucketIdx] += 1;
+            }
+        }
+    }
+
+    protected long getElapsedRealtimeMicro() {
+        return SystemClock.elapsedRealtimeNanos() / 1000;
+    }
+
+    protected boolean shouldKeepSample() {
+        return mRandom.nextInt() % mPeriodicSamplingInterval == 0;
+    }
+
+    /** Updates the sampling interval. */
+    public void setSamplingInterval(int samplingInterval) {
+        if (samplingInterval <= 0) {
+            Slog.w(TAG, "Ignored invalid sampling interval (value must be positive): "
+                    + samplingInterval);
+            return;
+        }
+
+        synchronized (mLock) {
+            if (samplingInterval != mPeriodicSamplingInterval) {
+                mPeriodicSamplingInterval = samplingInterval;
+                reset();
+            }
+        }
+    }
+
+    /** Updates the histogram buckets parameters. */
+    public void setHistogramBucketsParams(
+            int bucketCount, int firstBucketSize, float bucketScaleFactor) {
+        synchronized (mLock) {
+            if (bucketCount != mBucketCount || firstBucketSize != mFirstBucketSize
+                    || bucketScaleFactor != mBucketScaleFactor) {
+                mBucketCount = bucketCount;
+                mFirstBucketSize = firstBucketSize;
+                mBucketScaleFactor = bucketScaleFactor;
+                mLatencyBuckets = new BinderLatencyBuckets(
+                    mBucketCount, mFirstBucketSize, mBucketScaleFactor);
+                reset();
+            }
+        }
+    }
+
+    /** Resets the sample collection. */
+    public void reset() {
+        synchronized (mLock) {
+            mLatencyHistograms.clear();
+        }
+    }
+
+    /** Container for binder latency information. */
+    public static class LatencyDims {
+        // Binder interface descriptor.
+        private Class<? extends Binder> mBinderClass;
+        // Binder transaction code.
+        private int mTransactionCode;
+        // Cached hash code, 0 if not set yet.
+        private int mHashCode = 0;
+
+        public LatencyDims(Class<? extends Binder> binderClass, int transactionCode) {
+            this.mBinderClass = binderClass;
+            this.mTransactionCode = transactionCode;
+        }
+
+        public Class<? extends Binder> getBinderClass() {
+            return mBinderClass;
+        }
+
+        public int getTransactionCode() {
+            return mTransactionCode;
+        }
+
+        @Override
+        public boolean equals(final Object other) {
+            if (other == null || !(other instanceof LatencyDims)) {
+                return false;
+            }
+            LatencyDims o = (LatencyDims) other;
+            return mTransactionCode == o.getTransactionCode() && mBinderClass == o.getBinderClass();
+        }
+
+        @Override
+        public int hashCode() {
+            if (mHashCode != 0) {
+                return mHashCode;
+            }
+            int hash = mTransactionCode;
+            hash = 31 * hash + mBinderClass.hashCode();
+            mHashCode = hash;
+            return hash;
+        }
+    }
+
+    @VisibleForTesting
+    public ArrayMap<LatencyDims, int[]> getLatencyHistograms() {
+        return mLatencyHistograms;
+    }
+}
diff --git a/core/java/com/android/internal/util/StringPool.java b/core/java/com/android/internal/util/StringPool.java
new file mode 100644
index 0000000..c5180a3
--- /dev/null
+++ b/core/java/com/android/internal/util/StringPool.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2010 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 com.android.internal.util;
+
+/**
+ * A pool of string instances. Unlike the {@link String#intern() VM's
+ * interned strings}, this pool provides no guarantee of reference equality.
+ * It is intended only to save allocations. This class is not thread safe.
+ *
+ * @hide
+ */
+public final class StringPool {
+
+    private final String[] mPool = new String[512];
+
+    /**
+     * Constructs string pool.
+     */
+    public StringPool() {
+    }
+
+    private static boolean contentEquals(String s, char[] chars, int start, int length) {
+        if (s.length() != length) {
+            return false;
+        }
+        for (int i = 0; i < length; i++) {
+            if (chars[start + i] != s.charAt(i)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Returns a string equal to {@code new String(array, start, length)}.
+     *
+     * @param array  buffer containing string chars
+     * @param start  offset in {@code array} where string starts
+     * @param length length of string
+     * @return string equal to {@code new String(array, start, length)}
+     */
+    public String get(char[] array, int start, int length) {
+        // Compute an arbitrary hash of the content
+        int hashCode = 0;
+        for (int i = start; i < start + length; i++) {
+            hashCode = (hashCode * 31) + array[i];
+        }
+
+        // Pick a bucket using Doug Lea's supplemental secondaryHash function (from HashMap)
+        hashCode ^= (hashCode >>> 20) ^ (hashCode >>> 12);
+        hashCode ^= (hashCode >>> 7) ^ (hashCode >>> 4);
+        int index = hashCode & (mPool.length - 1);
+
+        String pooled = mPool[index];
+        if (pooled != null && contentEquals(pooled, array, start, length)) {
+            return pooled;
+        }
+
+        String result = new String(array, start, length);
+        mPool[index] = result;
+        return result;
+    }
+}
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index afd19b6..382acc0 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -149,7 +149,6 @@
                 "android_os_VintfRuntimeInfo.cpp",
                 "android_os_incremental_IncrementalManager.cpp",
                 "android_net_LocalSocketImpl.cpp",
-                "android_net_NetworkUtils.cpp",
                 "android_service_DataLoaderService.cpp",
                 "android_util_AssetManager.cpp",
                 "android_util_Binder.cpp",
@@ -216,6 +215,7 @@
 
             static_libs: [
                 "libasync_safe",
+                "libconnectivityframeworkutils",
                 "libbinderthreadstateutils",
                 "libdmabufinfo",
                 "libgif",
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 855448b..114f395 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -630,6 +630,7 @@
     char hotstartupsamplesOptsBuf[sizeof("-Xps-hot-startup-method-samples:")-1 + PROPERTY_VALUE_MAX];
     char saveResolvedClassesDelayMsOptsBuf[
             sizeof("-Xps-save-resolved-classes-delay-ms:")-1 + PROPERTY_VALUE_MAX];
+    char profileMinSavePeriodOptsBuf[sizeof("-Xps-min-save-period-ms:")-1 + PROPERTY_VALUE_MAX];
     char madviseRandomOptsBuf[sizeof("-XX:MadviseRandomAccess:")-1 + PROPERTY_VALUE_MAX];
     char madviseWillNeedFileSizeVdex[
             sizeof("-XMadviseWillNeedVdexFileSize:")-1 + PROPERTY_VALUE_MAX];
@@ -662,6 +663,8 @@
     char extraOptsBuf[PROPERTY_VALUE_MAX];
     char voldDecryptBuf[PROPERTY_VALUE_MAX];
     char perfettoHprofOptBuf[sizeof("-XX:PerfettoHprof=") + PROPERTY_VALUE_MAX];
+    char perfettoJavaHeapStackOptBuf[
+            sizeof("-XX:PerfettoJavaHeapStackProf=") + PROPERTY_VALUE_MAX];
     enum {
       kEMDefault,
       kEMIntPortable,
@@ -776,6 +779,10 @@
     parseRuntimeOption("dalvik.vm.perfetto_hprof", perfettoHprofOptBuf, "-XX:PerfettoHprof=",
                        "true");
 
+    // Enable PerfettoJavaHeapStackProf in the zygote
+    parseRuntimeOption("dalvik.vm.perfetto_javaheap", perfettoJavaHeapStackOptBuf,
+                       "-XX:PerfettoJavaHeapStackProf=", "true");
+
     if (primary_zygote) {
         addOption("-Xprimaryzygote");
     }
@@ -859,6 +866,9 @@
     parseRuntimeOption("dalvik.vm.ps-resolved-classes-delay-ms", saveResolvedClassesDelayMsOptsBuf,
             "-Xps-save-resolved-classes-delay-ms:");
 
+    parseRuntimeOption("dalvik.vm.ps-min-save-period-ms", profileMinSavePeriodOptsBuf,
+            "-Xps-min-save-period-ms:");
+
     property_get("ro.config.low_ram", propBuf, "");
     if (strcmp(propBuf, "true") == 0) {
       addOption("-XX:LowMemoryMode");
diff --git a/core/jni/android_media_AudioFormat.h b/core/jni/android_media_AudioFormat.h
index b1b39f3..0e6b587 100644
--- a/core/jni/android_media_AudioFormat.h
+++ b/core/jni/android_media_AudioFormat.h
@@ -39,6 +39,14 @@
 #define ENCODING_E_AC3_JOC      18
 #define ENCODING_DOLBY_MAT      19
 #define ENCODING_OPUS           20
+#define ENCODING_PCM_24BIT_PACKED 21
+#define ENCODING_PCM_32BIT 22
+#define ENCODING_MPEGH_BL_L3 23
+#define ENCODING_MPEGH_BL_L4 24
+#define ENCODING_MPEGH_LC_L3 25
+#define ENCODING_MPEGH_LC_L4 26
+#define ENCODING_DTS_UHD 27
+#define ENCODING_DRA 28
 
 #define ENCODING_INVALID    0
 #define ENCODING_DEFAULT    1
@@ -92,6 +100,22 @@
         return AUDIO_FORMAT_MAT;
     case ENCODING_OPUS:
         return AUDIO_FORMAT_OPUS;
+    case ENCODING_PCM_24BIT_PACKED:
+        return AUDIO_FORMAT_PCM_24_BIT_PACKED;
+    case ENCODING_PCM_32BIT:
+        return AUDIO_FORMAT_PCM_32_BIT;
+    case ENCODING_MPEGH_BL_L3:
+        return AUDIO_FORMAT_MPEGH_BL_L3;
+    case ENCODING_MPEGH_BL_L4:
+        return AUDIO_FORMAT_MPEGH_BL_L4;
+    case ENCODING_MPEGH_LC_L3:
+        return AUDIO_FORMAT_MPEGH_LC_L3;
+    case ENCODING_MPEGH_LC_L4:
+        return AUDIO_FORMAT_MPEGH_LC_L4;
+    case ENCODING_DTS_UHD:
+        return AUDIO_FORMAT_DTS_UHD;
+    case ENCODING_DRA:
+        return AUDIO_FORMAT_DRA;
     default:
         return AUDIO_FORMAT_INVALID;
     }
@@ -107,10 +131,15 @@
     case AUDIO_FORMAT_PCM_FLOAT:
         return ENCODING_PCM_FLOAT;
 
-    // map these to ENCODING_PCM_FLOAT
-    case AUDIO_FORMAT_PCM_8_24_BIT:
+    // As of S, these extend integer precision formats now return more specific values
+    // than ENCODING_PCM_FLOAT.
     case AUDIO_FORMAT_PCM_24_BIT_PACKED:
+        return ENCODING_PCM_24BIT_PACKED;
     case AUDIO_FORMAT_PCM_32_BIT:
+        return ENCODING_PCM_32BIT;
+
+    // map this to ENCODING_PCM_FLOAT
+    case AUDIO_FORMAT_PCM_8_24_BIT:
         return ENCODING_PCM_FLOAT;
 
     case AUDIO_FORMAT_AC3:
@@ -148,6 +177,18 @@
         return ENCODING_DOLBY_MAT;
     case AUDIO_FORMAT_OPUS:
         return ENCODING_OPUS;
+    case AUDIO_FORMAT_MPEGH_BL_L3:
+        return ENCODING_MPEGH_BL_L3;
+    case AUDIO_FORMAT_MPEGH_BL_L4:
+        return ENCODING_MPEGH_BL_L4;
+    case AUDIO_FORMAT_MPEGH_LC_L3:
+        return ENCODING_MPEGH_LC_L3;
+    case AUDIO_FORMAT_MPEGH_LC_L4:
+        return ENCODING_MPEGH_LC_L4;
+    case AUDIO_FORMAT_DTS_UHD:
+        return ENCODING_DTS_UHD;
+    case AUDIO_FORMAT_DRA:
+        return ENCODING_DRA;
     case AUDIO_FORMAT_DEFAULT:
         return ENCODING_DEFAULT;
     default:
diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp
index feb8930..1a7f6e8 100644
--- a/core/jni/android_media_AudioSystem.cpp
+++ b/core/jni/android_media_AudioSystem.cpp
@@ -2273,10 +2273,19 @@
     return (jint)nativeToJavaStatus(status);
 }
 
-static jint android_media_AudioSystem_get_FCC_8(JNIEnv *env, jobject thiz) {
+static jint android_media_AudioSystem_getMaxChannelCount(JNIEnv *env, jobject thiz) {
     return FCC_8;
 }
 
+static jint android_media_AudioSystem_getMaxSampleRate(JNIEnv *env, jobject thiz) {
+    // see frameworks/av/services/audiopolicy/common/include/policy.h
+    return 192000; // SAMPLE_RATE_HZ_MAX (for API)
+}
+
+static jint android_media_AudioSystem_getMinSampleRate(JNIEnv *env, jobject thiz) {
+    return 4000; // SAMPLE_RATE_HZ_MIN  (for API)
+}
+
 static jint
 android_media_AudioSystem_setAssistantUid(JNIEnv *env, jobject thiz, jint uid)
 {
@@ -2672,14 +2681,18 @@
         (void *)android_media_AudioSystem_eventHandlerFinalize},
 };
 
-static const JNINativeMethod gGetFCC8Methods[] = {
-    {"native_get_FCC_8", "()I", (void *)android_media_AudioSystem_get_FCC_8},
+static const JNINativeMethod gFrameworkCapabilities[] = {
+        {"native_getMaxChannelCount", "()I", (void *)android_media_AudioSystem_getMaxChannelCount},
+        {"native_getMaxSampleRate", "()I", (void *)android_media_AudioSystem_getMaxSampleRate},
+        {"native_getMinSampleRate", "()I", (void *)android_media_AudioSystem_getMinSampleRate},
 };
 
 int register_android_media_AudioSystem(JNIEnv *env)
 {
     // This needs to be done before hooking up methods AudioTrackRoutingProxy (below)
-    RegisterMethodsOrDie(env, kClassPathName, gGetFCC8Methods, NELEM(gGetFCC8Methods));
+    // as the calls are performed in the static initializer of AudioSystem.
+    RegisterMethodsOrDie(env, kClassPathName, gFrameworkCapabilities,
+                         NELEM(gFrameworkCapabilities));
 
     jclass arrayListClass = FindClassOrDie(env, "java/util/ArrayList");
     gArrayListClass = MakeGlobalRefOrDie(env, arrayListClass);
diff --git a/core/jni/android_os_VintfObject.cpp b/core/jni/android_os_VintfObject.cpp
index 4bd33a9..1baea2a 100644
--- a/core/jni/android_os_VintfObject.cpp
+++ b/core/jni/android_os_VintfObject.cpp
@@ -37,11 +37,13 @@
 
 namespace android {
 
+using vintf::CompatibilityMatrix;
 using vintf::HalManifest;
 using vintf::Level;
 using vintf::SchemaType;
 using vintf::to_string;
 using vintf::toXml;
+using vintf::Version;
 using vintf::VintfObject;
 using vintf::Vndk;
 
@@ -119,6 +121,28 @@
     return env->NewStringUTF(cString.c_str());
 }
 
+static jstring android_os_VintfObject_getPlatformSepolicyVersion(JNIEnv* env, jclass) {
+    std::shared_ptr<const CompatibilityMatrix> matrix =
+            VintfObject::GetFrameworkCompatibilityMatrix();
+    if (matrix == nullptr || matrix->type() != SchemaType::FRAMEWORK) {
+        jniThrowRuntimeException(env, "Cannot get framework compatibility matrix");
+        return nullptr;
+    }
+
+    auto versions = matrix->getSepolicyVersions();
+    if (versions.empty()) {
+        jniThrowRuntimeException(env,
+                                 "sepolicy_version in framework compatibility matrix is empty");
+        return nullptr;
+    }
+
+    Version latest;
+    for (const auto& range : versions) {
+        latest = std::max(latest, range.maxVer());
+    }
+    return env->NewStringUTF(to_string(latest).c_str());
+}
+
 static jobject android_os_VintfObject_getVndkSnapshots(JNIEnv* env, jclass) {
     std::shared_ptr<const HalManifest> manifest = VintfObject::GetFrameworkHalManifest();
     if (manifest == nullptr || manifest->type() != SchemaType::FRAMEWORK) {
@@ -145,12 +169,17 @@
 // ----------------------------------------------------------------------------
 
 static const JNINativeMethod gVintfObjectMethods[] = {
-    {"report", "()[Ljava/lang/String;", (void*)android_os_VintfObject_report},
-    {"verifyWithoutAvb", "()I", (void*)android_os_VintfObject_verifyWithoutAvb},
-    {"getHalNamesAndVersions", "()[Ljava/lang/String;", (void*)android_os_VintfObject_getHalNamesAndVersions},
-    {"getSepolicyVersion", "()Ljava/lang/String;", (void*)android_os_VintfObject_getSepolicyVersion},
-    {"getVndkSnapshots", "()Ljava/util/Map;", (void*)android_os_VintfObject_getVndkSnapshots},
-    {"getTargetFrameworkCompatibilityMatrixVersion", "()Ljava/lang/Long;", (void*)android_os_VintfObject_getTargetFrameworkCompatibilityMatrixVersion},
+        {"report", "()[Ljava/lang/String;", (void*)android_os_VintfObject_report},
+        {"verifyWithoutAvb", "()I", (void*)android_os_VintfObject_verifyWithoutAvb},
+        {"getHalNamesAndVersions", "()[Ljava/lang/String;",
+         (void*)android_os_VintfObject_getHalNamesAndVersions},
+        {"getSepolicyVersion", "()Ljava/lang/String;",
+         (void*)android_os_VintfObject_getSepolicyVersion},
+        {"getPlatformSepolicyVersion", "()Ljava/lang/String;",
+         (void*)android_os_VintfObject_getPlatformSepolicyVersion},
+        {"getVndkSnapshots", "()Ljava/util/Map;", (void*)android_os_VintfObject_getVndkSnapshots},
+        {"getTargetFrameworkCompatibilityMatrixVersion", "()Ljava/lang/Long;",
+         (void*)android_os_VintfObject_getTargetFrameworkCompatibilityMatrixVersion},
 };
 
 const char* const kVintfObjectPathName = "android/os/VintfObject";
diff --git a/core/jni/include/android_runtime/AndroidRuntime.h b/core/jni/include/android_runtime/AndroidRuntime.h
index d86d934..bf2ba77 100644
--- a/core/jni/include/android_runtime/AndroidRuntime.h
+++ b/core/jni/include/android_runtime/AndroidRuntime.h
@@ -19,7 +19,6 @@
 #ifndef _RUNTIME_ANDROID_RUNTIME_H
 #define _RUNTIME_ANDROID_RUNTIME_H
 
-#include <binder/IBinder.h>
 #include <jni.h>
 #include <pthread.h>
 #include <utils/Errors.h>
diff --git a/core/proto/android/providers/OWNERS b/core/proto/android/providers/OWNERS
new file mode 100644
index 0000000..1f5cd9a
--- /dev/null
+++ b/core/proto/android/providers/OWNERS
@@ -0,0 +1 @@
+include /packages/SettingsProvider/OWNERS
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index cc4e2bb..4a57448 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -398,6 +398,8 @@
     <protected-broadcast android:name="android.net.wifi.p2p.action.WIFI_P2P_PERSISTENT_GROUPS_CHANGED" />
     <protected-broadcast android:name="android.net.conn.TETHER_STATE_CHANGED" />
     <protected-broadcast android:name="android.net.conn.INET_CONDITION_ACTION" />
+    <!-- This broadcast is no longer sent in S but it should stay protected to avoid third party
+         apps broadcasting this and confusing old system apps that may not have been updated. -->
     <protected-broadcast android:name="android.net.conn.NETWORK_CONDITIONS_MEASURED" />
     <protected-broadcast
             android:name="android.net.ConnectivityService.action.PKT_CNT_SAMPLE_INTERVAL_ELAPSED" />
@@ -3792,6 +3794,13 @@
     <permission android:name="com.android.permission.USE_INSTALLER_V2"
         android:protectionLevel="signature|verifier" />
 
+    <!-- @TestApi Allows a testOnly application to get installed.
+        <p>Not for use by third-party applications.
+        @hide
+    -->
+    <permission android:name="android.permission.INSTALL_TEST_ONLY_PACKAGE"
+                android:protectionLevel="signature" />
+
     <!-- @SystemApi @TestApi Allows an application to clear user data.
          <p>Not for use by third-party applications
          @hide
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index cbc08ba..6bdfe28 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -632,6 +632,13 @@
     <!-- The default minimal size of a PiP task, in both dimensions. -->
     <dimen name="default_minimal_size_pip_resizable_task">108dp</dimen>
 
+    <!--
+      The overridable minimal size of a PiP task, in both dimensions.
+      Different from default_minimal_size_pip_resizable_task, this is to limit the dimension
+      when the pinned stack size is overridden by app via minWidth/minHeight.
+    -->
+    <dimen name="overridable_minimal_size_pip_resizable_task">48dp</dimen>
+
     <!-- Height of a task when in minimized mode from the top when launcher is resizable. -->
     <dimen name="task_height_of_minimized_mode">80dp</dimen>
 
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index c06e7de..43f4300 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1941,6 +1941,7 @@
   <java-symbol type="fraction" name="config_dimBehindFadeDuration" />
   <java-symbol type="dimen" name="default_minimal_size_resizable_task" />
   <java-symbol type="dimen" name="default_minimal_size_pip_resizable_task" />
+  <java-symbol type="dimen" name="overridable_minimal_size_pip_resizable_task" />
   <java-symbol type="dimen" name="task_height_of_minimized_mode" />
   <java-symbol type="fraction" name="config_screenAutoBrightnessDozeScaleFactor" />
   <java-symbol type="bool" name="config_allowPriorityVibrationsInLowPowerMode" />
diff --git a/core/res/res/xml/sms_short_codes.xml b/core/res/res/xml/sms_short_codes.xml
index d5733e3..2650d9f 100644
--- a/core/res/res/xml/sms_short_codes.xml
+++ b/core/res/res/xml/sms_short_codes.xml
@@ -40,7 +40,7 @@
     <shortcode country="al" pattern="\\d{5}" premium="15191|55[56]00" />
 
     <!-- Argentina: 5 digits, known short codes listed -->
-    <shortcode country="ar" pattern="\\d{5}" free="11711|28291" />
+    <shortcode country="ar" pattern="\\d{5}" free="11711|28291|44077" />
 
     <!-- Armenia: 3-4 digits, emergency numbers 10[123] -->
     <shortcode country="am" pattern="\\d{3,4}" premium="11[2456]1|3024" free="10[123]" />
@@ -76,14 +76,14 @@
     <shortcode country="ch" pattern="[2-9]\\d{2,4}" premium="543|83111|30118" free="98765|30075|30047" />
 
     <!-- Chile: 4-5 digits (not confirmed), known premium codes listed -->
-    <shortcode country="cl" pattern="\\d{4,5}" free="9963|9240" />
+    <shortcode country="cl" pattern="\\d{4,5}" free="9963|9240|1038" />
 
     <!-- China: premium shortcodes start with "1066", free shortcodes start with "1065":
          http://clients.txtnation.com/entries/197192-china-premium-sms-short-code-requirements -->
     <shortcode country="cn" premium="1066.*" free="1065.*" />
 
     <!-- Colombia: 1-6 digits (not confirmed) -->
-    <shortcode country="co" pattern="\\d{1,6}" free="890350|908160|892255|898002|898880|899960" />
+    <shortcode country="co" pattern="\\d{1,6}" free="890350|908160|892255|898002|898880|899960|899948|87739" />
 
     <!-- Cyprus: 4-6 digits (not confirmed), known premium codes listed, plus EU -->
     <shortcode country="cy" pattern="\\d{4,6}" premium="7510" free="116\\d{3}" />
@@ -156,7 +156,7 @@
     <shortcode country="jp" pattern="\\d{1,5}" free="8083" />
 
     <!-- Kenya: 5 digits, known premium codes listed -->
-    <shortcode country="ke" pattern="\\d{5}" free="21725" />
+    <shortcode country="ke" pattern="\\d{5}" free="21725|21562|40520" />
 
     <!-- Kyrgyzstan: 4 digits, known premium codes listed -->
     <shortcode country="kg" pattern="\\d{4}" premium="415[2367]|444[69]" />
@@ -187,13 +187,13 @@
     <shortcode country="mx" pattern="\\d{4,5}" premium="53035|7766" free="26259|46645|50025|50052|5050|76551|88778|9963" />
 
     <!-- Malaysia: 5 digits: http://www.skmm.gov.my/attachment/Consumer_Regulation/Mobile_Content_Services_FAQs.pdf -->
-    <shortcode country="my" pattern="\\d{5}" premium="32298|33776" free="22099|28288" />
+    <shortcode country="my" pattern="\\d{5}" premium="32298|33776" free="22099|28288|66668" />
 
     <!-- The Netherlands, 4 digits, known premium codes listed, plus EU -->
     <shortcode country="nl" pattern="\\d{4}" premium="4466|5040" free="116\\d{3}|2223|6225|2223|1662" />
 
     <!-- Nigeria -->
-    <shortcode country="ng" pattern="\\d{1,5}" free="2441" />
+    <shortcode country="ng" pattern="\\d{1,5}" free="2441|55019" />
 
     <!-- Norway: 4-5 digits (not confirmed), known premium codes listed -->
     <shortcode country="no" pattern="\\d{4,5}" premium="2201|222[67]" free="2171" />
@@ -202,7 +202,7 @@
     <shortcode country="nz" pattern="\\d{3,4}" premium="3903|8995|4679" free="1737|176|2141|3067|3068|3110|4006|4053|4061|4062|4202|4300|4334|4412|4575|5626|8006|8681" />
 
     <!-- Peru: 4-5 digits (not confirmed), known premium codes listed -->
-    <shortcode country="pe" pattern="\\d{4,5}" free="9963" />
+    <shortcode country="pe" pattern="\\d{4,5}" free="9963|40777" />
 
     <!-- Philippines -->
     <shortcode country="ph" pattern="\\d{1,5}" free="2147|5495|5496" />
@@ -224,7 +224,7 @@
     <shortcode country="re" pattern="\\d{1,5}" free="38600,36300,36303,959" />
 
     <!-- Romania: 4 digits, plus EU: http://www.simplus.ro/en/resources/glossary-of-terms/ -->
-    <shortcode country="ro" pattern="\\d{4}" premium="12(?:63|66|88)|13(?:14|80)" free="116\\d{3}|3654|8360" />
+    <shortcode country="ro" pattern="\\d{4}" premium="12(?:63|66|88)|13(?:14|80)" free="116\\d{3}|3654|8360|3838" />
 
     <!-- Russia: 4 digits, known premium codes listed: http://smscoin.net/info/pricing-russia/ -->
     <shortcode country="ru" pattern="\\d{4}" premium="1(?:1[56]1|899)|2(?:09[57]|322|47[46]|880|990)|3[589]33|4161|44(?:4[3-9]|81)|77(?:33|81)|8424" free="6954|8501" standard="2037|2044"/>
@@ -252,7 +252,7 @@
     <shortcode country="tj" pattern="\\d{4}" premium="11[3-7]1|4161|4333|444[689]" />
 
     <!-- Turkey -->
-    <shortcode country="tr" pattern="\\d{1,5}" free="7529|5528|6493" />
+    <shortcode country="tr" pattern="\\d{1,5}" free="7529|5528|6493|3193" />
 
     <!-- Ukraine: 4 digits, known premium codes listed -->
     <shortcode country="ua" pattern="\\d{4}" premium="444[3-9]|70[579]4|7540" />
@@ -268,6 +268,6 @@
     <shortcode country="yt" pattern="\\d{1,5}" free="38600,36300,36303,959" />
 
     <!-- South Africa -->
-    <shortcode country="za" pattern="\d{1,5}" free="44136" />
+    <shortcode country="za" pattern="\d{1,5}" free="44136|30791|36056" />
 
 </shortcodes>
diff --git a/core/tests/bandwidthtests/src/com/android/bandwidthtest/util/ConnectionUtil.java b/core/tests/bandwidthtests/src/com/android/bandwidthtest/util/ConnectionUtil.java
index dd60dd4..1a63660 100644
--- a/core/tests/bandwidthtests/src/com/android/bandwidthtest/util/ConnectionUtil.java
+++ b/core/tests/bandwidthtests/src/com/android/bandwidthtest/util/ConnectionUtil.java
@@ -44,8 +44,6 @@
 import com.android.bandwidthtest.NetworkState.StateTransitionDirection;
 import com.android.internal.util.AsyncChannel;
 
-import junit.framework.Assert;
-
 import java.io.IOException;
 import java.net.UnknownHostException;
 import java.util.List;
@@ -76,7 +74,11 @@
     private WifiManager mWifiManager;
     private Context mContext;
     // Verify connectivity state
-    private static final int NUM_NETWORK_TYPES = ConnectivityManager.MAX_NETWORK_TYPE + 1;
+    // ConnectivityManager.TYPE_* is deprecated and no longer extended, so use the max public
+    // network type - TYPE_VPN should be enough.
+    // TODO: Replace registering CONNECTIVITY_ACTION with registering NetworkCallback and check
+    //  network by NetworkCapabilities.TRANSPORT_* and NetworkCapabilities.hasTransport() instead.
+    private static final int NUM_NETWORK_TYPES = ConnectivityManager.TYPE_VPN + 1;
     private NetworkState[] mConnectivityState = new NetworkState[NUM_NETWORK_TYPES];
 
     public ConnectionUtil(Context context) {
diff --git a/core/tests/benchmarks/src/android/net/NetworkStatsBenchmark.java b/core/tests/benchmarks/src/android/net/NetworkStatsBenchmark.java
index 3ebe103..0299832 100644
--- a/core/tests/benchmarks/src/android/net/NetworkStatsBenchmark.java
+++ b/core/tests/benchmarks/src/android/net/NetworkStatsBenchmark.java
@@ -91,7 +91,7 @@
     public void timeMigrateTun(int reps) {
         for (int i = 0; i < reps; i++) {
             NetworkStats stats = mNetworkStats.clone();
-            stats.migrateTun(TUN_UID, TUN_IFACE, getVpnUnderlyingIfaces());
+            stats.migrateTun(TUN_UID, TUN_IFACE, Arrays.asList(getVpnUnderlyingIfaces()));
         }
     }
 
diff --git a/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java b/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java
index eb9c7b6..cec6216 100644
--- a/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java
@@ -753,6 +753,34 @@
         assertEquals(1, callStats.recordedCallCount);
     }
 
+    @Test
+    public void testLatencyCollectionEnabled() {
+        TestBinderCallsStats bcs = new TestBinderCallsStats();
+        bcs.setCollectLatencyData(true);
+
+        Binder binder = new Binder();
+        CallSession callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
+        bcs.time += 10;
+        bcs.elapsedTime += 20;
+        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
+
+        assertEquals(1, bcs.getLatencyObserver().getLatencyHistograms().size());
+    }
+
+    @Test
+    public void testLatencyCollectionDisabledByDefault() {
+        TestBinderCallsStats bcs = new TestBinderCallsStats();
+        assertEquals(false, bcs.getCollectLatencyData());
+
+        Binder binder = new Binder();
+        CallSession callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
+        bcs.time += 10;
+        bcs.elapsedTime += 20;
+        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
+
+        assertEquals(0, bcs.getLatencyObserver().getLatencyHistograms().size());
+    }
+
     class TestBinderCallsStats extends BinderCallsStats {
         public int callingUid = CALLING_UID;
         public long time = 1234;
@@ -774,6 +802,10 @@
                         }
                     };
                 }
+
+                public BinderLatencyObserver getLatencyObserver() {
+                    return new BinderLatencyObserverTest.TestBinderLatencyObserver();
+                }
             });
             setSamplingInterval(1);
             setAddDebugEntries(false);
diff --git a/core/tests/coretests/src/com/android/internal/os/BinderLatencyBucketsTest.java b/core/tests/coretests/src/com/android/internal/os/BinderLatencyBucketsTest.java
new file mode 100644
index 0000000..00443a9
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/os/BinderLatencyBucketsTest.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2018 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 com.android.internal.os;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertEquals;
+
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+@Presubmit
+public class BinderLatencyBucketsTest {
+    @Test
+    public void testBucketThresholds() {
+        BinderLatencyBuckets latencyBuckets = new BinderLatencyBuckets(10, 2, 1.45f);
+        assertThat(latencyBuckets.getBuckets())
+            .containsExactly(2, 3, 4, 6, 8, 12, 18, 26, 39)
+            .inOrder();
+    }
+
+    @Test
+    public void testSampleAssignment() {
+        BinderLatencyBuckets latencyBuckets = new BinderLatencyBuckets(10, 2, 1.45f);
+        assertEquals(0, latencyBuckets.sampleToBucket(0));
+        assertEquals(0, latencyBuckets.sampleToBucket(1));
+        assertEquals(1, latencyBuckets.sampleToBucket(2));
+        assertEquals(2, latencyBuckets.sampleToBucket(3));
+        assertEquals(3, latencyBuckets.sampleToBucket(4));
+        assertEquals(5, latencyBuckets.sampleToBucket(9));
+        assertEquals(6, latencyBuckets.sampleToBucket(13));
+        assertEquals(7, latencyBuckets.sampleToBucket(25));
+        assertEquals(9, latencyBuckets.sampleToBucket(100));
+    }
+
+    @Test
+    public void testMaxIntBuckets() {
+        BinderLatencyBuckets latencyBuckets = new BinderLatencyBuckets(5, Integer.MAX_VALUE / 2, 2);
+        assertThat(latencyBuckets.getBuckets())
+            .containsExactly(Integer.MAX_VALUE / 2, Integer.MAX_VALUE - 1)
+            .inOrder();
+
+        assertEquals(0, latencyBuckets.sampleToBucket(0));
+        assertEquals(0, latencyBuckets.sampleToBucket(Integer.MAX_VALUE / 2 - 1));
+        assertEquals(1, latencyBuckets.sampleToBucket(Integer.MAX_VALUE - 2));
+        assertEquals(2, latencyBuckets.sampleToBucket(Integer.MAX_VALUE));
+    }
+}
diff --git a/core/tests/coretests/src/com/android/internal/os/BinderLatencyObserverTest.java b/core/tests/coretests/src/com/android/internal/os/BinderLatencyObserverTest.java
new file mode 100644
index 0000000..f65fb95
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/os/BinderLatencyObserverTest.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2018 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 com.android.internal.os;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertEquals;
+
+import android.os.Binder;
+import android.platform.test.annotations.Presubmit;
+import android.util.ArrayMap;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.internal.os.BinderInternal.CallSession;
+import com.android.internal.os.BinderLatencyObserver.LatencyDims;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Arrays;
+import java.util.Random;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+@Presubmit
+public class BinderLatencyObserverTest {
+    @Test
+    public void testLatencyCollectionWithMultipleClasses() {
+        TestBinderLatencyObserver blo = new TestBinderLatencyObserver();
+        blo.setHistogramBucketsParams(5, 5, 1.125f);
+
+        Binder binder = new Binder();
+        CallSession callSession = new CallSession();
+        callSession.binderClass = binder.getClass();
+        callSession.transactionCode = 1;
+        blo.callEnded(callSession);
+        blo.callEnded(callSession);
+        blo.callEnded(callSession);
+        callSession.transactionCode = 2;
+        blo.callEnded(callSession);
+        blo.callEnded(callSession);
+
+        ArrayMap<LatencyDims, int[]> latencyHistograms = blo.getLatencyHistograms();
+        assertEquals(2, latencyHistograms.keySet().size());
+        assertThat(latencyHistograms.get(new LatencyDims(binder.getClass(), 1)))
+            .asList().containsExactly(2, 0, 1, 0, 0).inOrder();
+        assertThat(latencyHistograms.get(new LatencyDims(binder.getClass(), 2)))
+            .asList().containsExactly(0, 0, 0, 0, 2).inOrder();
+    }
+
+    @Test
+    public void testSampling() {
+        TestBinderLatencyObserver blo = new TestBinderLatencyObserver();
+        blo.setSamplingInterval(2);
+        blo.setHistogramBucketsParams(5, 5, 1.125f);
+
+        Binder binder = new Binder();
+        CallSession callSession = new CallSession();
+        callSession.binderClass = binder.getClass();
+        callSession.transactionCode = 1;
+        blo.callEnded(callSession);
+        callSession.transactionCode = 2;
+        blo.callEnded(callSession);
+
+        ArrayMap<LatencyDims, int[]> latencyHistograms = blo.getLatencyHistograms();
+        assertEquals(1, latencyHistograms.size());
+        LatencyDims dims = latencyHistograms.keySet().iterator().next();
+        assertEquals(binder.getClass(), dims.getBinderClass());
+        assertEquals(1, dims.getTransactionCode());
+        assertThat(latencyHistograms.get(dims)).asList().containsExactly(1, 0, 0, 0, 0).inOrder();
+    }
+
+    @Test
+    public void testTooCallLengthOverflow() {
+        TestBinderLatencyObserver blo = new TestBinderLatencyObserver();
+        blo.setElapsedTime(2L + (long) Integer.MAX_VALUE);
+        blo.setHistogramBucketsParams(5, 5, 1.125f);
+
+        Binder binder = new Binder();
+        CallSession callSession = new CallSession();
+        callSession.binderClass = binder.getClass();
+        callSession.transactionCode = 1;
+        blo.callEnded(callSession);
+
+        // The long call should be capped to maxint (to not overflow) and placed in the last bucket.
+        assertThat(blo.getLatencyHistograms()
+            .get(new LatencyDims(binder.getClass(), 1)))
+            .asList().containsExactly(0, 0, 0, 0, 1)
+            .inOrder();
+    }
+
+    @Test
+    public void testHistogramBucketOverflow() {
+        TestBinderLatencyObserver blo = new TestBinderLatencyObserver();
+        blo.setHistogramBucketsParams(3, 5, 1.125f);
+
+        Binder binder = new Binder();
+        CallSession callSession = new CallSession();
+        callSession.binderClass = binder.getClass();
+        callSession.transactionCode = 1;
+        blo.callEnded(callSession);
+
+        LatencyDims dims = new LatencyDims(binder.getClass(), 1);
+        // Fill the buckets with maxint.
+        Arrays.fill(blo.getLatencyHistograms().get(dims), Integer.MAX_VALUE);
+        assertThat(blo.getLatencyHistograms().get(dims))
+            .asList().containsExactly(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE);
+        // Try to add another sample.
+        blo.callEnded(callSession);
+        // Make sure the buckets don't overflow.
+        assertThat(blo.getLatencyHistograms().get(dims))
+            .asList().containsExactly(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE);
+    }
+
+    public static class TestBinderLatencyObserver extends BinderLatencyObserver {
+        private long mElapsedTime = 0;
+
+        TestBinderLatencyObserver() {
+            // Make random generator not random.
+            super(new Injector() {
+                public Random getRandomGenerator() {
+                    return new Random() {
+                        int mCallCount = 0;
+
+                        public int nextInt() {
+                            return mCallCount++;
+                        }
+                    };
+                }
+            });
+            setSamplingInterval(1);
+        }
+
+        @Override
+        protected long getElapsedRealtimeMicro() {
+            mElapsedTime += 2;
+            return mElapsedTime;
+        }
+
+        public void setElapsedTime(long time) {
+            mElapsedTime = time;
+        }
+    }
+}
diff --git a/core/tests/nfctests/src/android/nfc/NfcControllerAlwaysOnListenerTest.java b/core/tests/nfctests/src/android/nfc/NfcControllerAlwaysOnListenerTest.java
index 43f9b6f..48f4288 100644
--- a/core/tests/nfctests/src/android/nfc/NfcControllerAlwaysOnListenerTest.java
+++ b/core/tests/nfctests/src/android/nfc/NfcControllerAlwaysOnListenerTest.java
@@ -19,6 +19,7 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
@@ -62,7 +63,36 @@
     }
 
     @Test
+    public void testRegister_RegisterUnregisterWhenNotSupported() throws RemoteException {
+        // isControllerAlwaysOnSupported() returns false, not supported.
+        doReturn(false).when(mNfcAdapter).isControllerAlwaysOnSupported();
+        NfcControllerAlwaysOnListener mListener =
+                new NfcControllerAlwaysOnListener(mNfcAdapter);
+        ControllerAlwaysOnListener mockListener1 = mock(ControllerAlwaysOnListener.class);
+        ControllerAlwaysOnListener mockListener2 = mock(ControllerAlwaysOnListener.class);
+
+        // Verify that the state listener will not registered with the NFC Adapter
+        mListener.register(getExecutor(), mockListener1);
+        verify(mNfcAdapter, times(0)).registerControllerAlwaysOnListener(any());
+
+        // Register a second client and no any call to NFC Adapter
+        mListener.register(getExecutor(), mockListener2);
+        verify(mNfcAdapter, times(0)).registerControllerAlwaysOnListener(any());
+
+        // Unregister first listener, and no any call to NFC Adapter
+        mListener.unregister(mockListener1);
+        verify(mNfcAdapter, times(0)).registerControllerAlwaysOnListener(any());
+        verify(mNfcAdapter, times(0)).unregisterControllerAlwaysOnListener(any());
+
+        // Unregister second listener, and no any call to NFC Adapter
+        mListener.unregister(mockListener2);
+        verify(mNfcAdapter, times(0)).registerControllerAlwaysOnListener(any());
+        verify(mNfcAdapter, times(0)).unregisterControllerAlwaysOnListener(any());
+    }
+
+    @Test
     public void testRegister_RegisterUnregister() throws RemoteException {
+        doReturn(true).when(mNfcAdapter).isControllerAlwaysOnSupported();
         NfcControllerAlwaysOnListener mListener =
                 new NfcControllerAlwaysOnListener(mNfcAdapter);
         ControllerAlwaysOnListener mockListener1 = mock(ControllerAlwaysOnListener.class);
@@ -89,6 +119,7 @@
 
     @Test
     public void testRegister_FirstRegisterFails() throws RemoteException {
+        doReturn(true).when(mNfcAdapter).isControllerAlwaysOnSupported();
         NfcControllerAlwaysOnListener mListener =
                 new NfcControllerAlwaysOnListener(mNfcAdapter);
         ControllerAlwaysOnListener mockListener1 = mock(ControllerAlwaysOnListener.class);
@@ -116,6 +147,7 @@
 
     @Test
     public void testRegister_RegisterSameListenerTwice() throws RemoteException {
+        doReturn(true).when(mNfcAdapter).isControllerAlwaysOnSupported();
         NfcControllerAlwaysOnListener mListener =
                 new NfcControllerAlwaysOnListener(mNfcAdapter);
         ControllerAlwaysOnListener mockListener = mock(ControllerAlwaysOnListener.class);
@@ -132,7 +164,7 @@
 
     @Test
     public void testNotify_AllListenersNotified() throws RemoteException {
-
+        doReturn(true).when(mNfcAdapter).isControllerAlwaysOnSupported();
         NfcControllerAlwaysOnListener listener = new NfcControllerAlwaysOnListener(mNfcAdapter);
         List<ControllerAlwaysOnListener> mockListeners = new ArrayList<>();
         for (int i = 0; i < 10; i++) {
@@ -149,7 +181,8 @@
     }
 
     @Test
-    public void testStateChange_CorrectValue() {
+    public void testStateChange_CorrectValue() throws RemoteException {
+        doReturn(true).when(mNfcAdapter).isControllerAlwaysOnSupported();
         runStateChangeValue(true, true);
         runStateChangeValue(false, false);
 
diff --git a/core/tests/utiltests/src/com/android/internal/util/StringPoolTest.java b/core/tests/utiltests/src/com/android/internal/util/StringPoolTest.java
new file mode 100644
index 0000000..f67fd51
--- /dev/null
+++ b/core/tests/utiltests/src/com/android/internal/util/StringPoolTest.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2010 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 com.android.internal.util;
+
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+@SmallTest
+public final class StringPoolTest extends AndroidTestCase {
+
+    public void testStringPool() {
+        StringPool stringPool = new StringPool();
+        String bcd = stringPool.get(new char[] { 'a', 'b', 'c', 'd', 'e' }, 1, 3);
+        assertEquals("bcd", bcd);
+        assertSame(bcd, stringPool.get(new char[] { 'a', 'b', 'c', 'd', 'e' }, 1, 3));
+    }
+
+    public void testHashCollision() {
+        StringPool stringPool = new StringPool();
+        char[] a = { (char) 1, (char) 0 };
+        char[] b = { (char) 0, (char) 31 };
+        assertEquals(new String(a).hashCode(), new String(b).hashCode());
+
+        String aString = stringPool.get(a, 0, 2);
+        assertEquals(new String(a), aString);
+        String bString = stringPool.get(b, 0, 2);
+        assertEquals(new String(b), bString);
+        assertSame(bString, stringPool.get(b, 0, 2));
+        assertNotSame(aString, stringPool.get(a, 0, 2));
+    }
+}
diff --git a/core/tests/uwbtests/src/android/uwb/AdapterStateListenerTest.java b/core/tests/uwbtests/src/android/uwb/AdapterStateListenerTest.java
index bdaf630..4cad535 100644
--- a/core/tests/uwbtests/src/android/uwb/AdapterStateListenerTest.java
+++ b/core/tests/uwbtests/src/android/uwb/AdapterStateListenerTest.java
@@ -19,7 +19,6 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -114,30 +113,6 @@
     }
 
     @Test
-    public void testRegister_FirstRegisterFails() throws RemoteException {
-        AdapterStateListener adapterStateListener = new AdapterStateListener(mUwbAdapter);
-        AdapterStateCallback callback1 = mock(AdapterStateCallback.class);
-        AdapterStateCallback callback2 = mock(AdapterStateCallback.class);
-
-        // Throw a remote exception whenever first registering
-        doThrow(mThrowRemoteException).when(mUwbAdapter).registerAdapterStateCallbacks(any());
-
-        adapterStateListener.register(getExecutor(), callback1);
-        verify(mUwbAdapter, times(1)).registerAdapterStateCallbacks(any());
-
-        // No longer throw an exception, instead succeed
-        doAnswer(mRegisterSuccessAnswer).when(mUwbAdapter).registerAdapterStateCallbacks(any());
-
-        // Register a different callback
-        adapterStateListener.register(getExecutor(), callback2);
-        verify(mUwbAdapter, times(2)).registerAdapterStateCallbacks(any());
-
-        // Ensure first callback was invoked again
-        verifyCallbackStateChangedInvoked(callback1, 2);
-        verifyCallbackStateChangedInvoked(callback2, 1);
-    }
-
-    @Test
     public void testRegister_RegisterSameCallbackTwice() throws RemoteException {
         AdapterStateListener adapterStateListener = new AdapterStateListener(mUwbAdapter);
         AdapterStateCallback callback = mock(AdapterStateCallback.class);
@@ -162,13 +137,6 @@
         runViaExecutor();
     }
 
-    @Test
-    public void testCallback_RunViaExecutor_Failure() throws RemoteException {
-        // Verify that the callbacks are invoked on the executor when there is a remote exception
-        doThrow(mThrowRemoteException).when(mUwbAdapter).registerAdapterStateCallbacks(any());
-        runViaExecutor();
-    }
-
     private void runViaExecutor() {
         AdapterStateListener adapterStateListener = new AdapterStateListener(mUwbAdapter);
         AdapterStateCallback callback = mock(AdapterStateCallback.class);
diff --git a/keystore/java/android/security/Authorization.java b/keystore/java/android/security/Authorization.java
index bd72d45..00219e7 100644
--- a/keystore/java/android/security/Authorization.java
+++ b/keystore/java/android/security/Authorization.java
@@ -74,16 +74,19 @@
      * @param locked            - whether it is a lock (true) or unlock (false) event
      * @param syntheticPassword - if it is an unlock event with the password, pass the synthetic
      *                            password provided by the LockSettingService
+     * @param unlockingSids     - KeyMint secure user IDs that should be permitted to unlock
+     *                            UNLOCKED_DEVICE_REQUIRED keys.
      *
      * @return 0 if successful or a {@code ResponseCode}.
      */
     public static int onLockScreenEvent(@NonNull boolean locked, @NonNull int userId,
-            @Nullable byte[] syntheticPassword) {
+            @Nullable byte[] syntheticPassword, @Nullable long[] unlockingSids) {
         try {
             if (locked) {
-                getService().onLockScreenEvent(LockScreenEvent.LOCK, userId, null);
+                getService().onLockScreenEvent(LockScreenEvent.LOCK, userId, null, unlockingSids);
             } else {
-                getService().onLockScreenEvent(LockScreenEvent.UNLOCK, userId, syntheticPassword);
+                getService().onLockScreenEvent(
+                        LockScreenEvent.UNLOCK, userId, syntheticPassword, unlockingSids);
             }
             return 0;
         } catch (RemoteException | NullPointerException e) {
diff --git a/keystore/java/android/security/keystore/AttestationUtils.java b/keystore/java/android/security/keystore/AttestationUtils.java
index be865a0..3980d3a 100644
--- a/keystore/java/android/security/keystore/AttestationUtils.java
+++ b/keystore/java/android/security/keystore/AttestationUtils.java
@@ -293,6 +293,11 @@
         } catch (SecurityException e) {
             throw e;
         } catch (Exception e) {
+            // If a DeviceIdAttestationException was previously wrapped with some other type,
+            // let's throw the original exception instead of wrapping it yet again.
+            if (e.getCause() instanceof DeviceIdAttestationException) {
+                throw (DeviceIdAttestationException) e.getCause();
+            }
             throw new DeviceIdAttestationException("Unable to perform attestation", e);
         }
     }
diff --git a/libs/androidfw/PosixUtils.cpp b/libs/androidfw/PosixUtils.cpp
index f1ab149..4ec525a 100644
--- a/libs/androidfw/PosixUtils.cpp
+++ b/libs/androidfw/PosixUtils.cpp
@@ -72,7 +72,8 @@
     argv0[i] = argv[i].c_str();
   }
   argv0[argv.size()] = nullptr;
-  switch (fork()) {
+  int pid = fork();
+  switch (pid) {
     case -1: // error
       free(argv0);
       PLOG(ERROR) << "fork";
@@ -104,8 +105,10 @@
       close(stdout[1]);
       close(stderr[1]);
       int status;
-      wait(&status);
+      waitpid(pid, &status, 0);
       if (!WIFEXITED(status)) {
+          close(stdout[0]);
+          close(stderr[0]);
           return nullptr;
       }
       std::unique_ptr<ProcResult> result(new ProcResult());
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index 6220abe..e74d3966a 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -528,6 +528,7 @@
         "libhwui_defaults",
         "android_graphics_apex",
         "android_graphics_jni",
+        "linker_hugepage_aligned",
     ],
     export_header_lib_headers: ["android_graphics_apex_headers"],
 }
diff --git a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
index 139474c..67a040d 100644
--- a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
+++ b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
@@ -28,6 +28,7 @@
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.UserHandle;
+import android.telephony.PhoneNumberUtils;
 import android.telephony.PhoneStateListener;
 import android.telephony.TelephonyManager;
 import android.util.Log;
@@ -160,7 +161,7 @@
                        be set to true when the phone is having emergency call, and then will
                        be set to false by mPhoneStateListener when the emergency call ends.
                 */
-                mIsInEmergencyCall = mTelephonyManager.isEmergencyNumber(phoneNumber);
+                mIsInEmergencyCall = PhoneNumberUtils.isEmergencyNumber(phoneNumber);
                 if (DEBUG) Log.v(TAG, "ACTION_NEW_OUTGOING_CALL - " + getInEmergency());
             } else if (action.equals(LocationManager.MODE_CHANGED_ACTION)) {
                 updateLocationMode();
diff --git a/media/java/android/media/AudioDeviceInfo.java b/media/java/android/media/AudioDeviceInfo.java
index f79fc92..270dffe 100644
--- a/media/java/android/media/AudioDeviceInfo.java
+++ b/media/java/android/media/AudioDeviceInfo.java
@@ -23,6 +23,7 @@
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.Arrays;
 import java.util.Objects;
 import java.util.TreeSet;
 
@@ -467,9 +468,32 @@
      * @see AudioFormat
      *
      * Note: an empty array indicates that the device supports arbitrary encodings.
+     * For forward compatibility, applications should ignore entries it does not recognize.
      */
     public @NonNull int[] getEncodings() {
-        return AudioFormat.filterPublicFormats(mPort.formats());
+        final int[] encodings = AudioFormat.filterPublicFormats(mPort.formats());
+        boolean hasFloat = false;
+        boolean hasExtendedIntegerPrecision = false;
+
+        for (int encoding : encodings) {
+            if (AudioFormat.isEncodingLinearPcm(encoding)) {
+                if (encoding == AudioFormat.ENCODING_PCM_FLOAT) {
+                    hasFloat = true;
+                } else if (AudioFormat.getBytesPerSample(encoding) > 2) {
+                    hasExtendedIntegerPrecision = true;
+                }
+            }
+        }
+        if (hasExtendedIntegerPrecision && !hasFloat) {
+            // R and earlier compatibility - add ENCODING_PCM_FLOAT to the end
+            // (replacing the zero pad). This ensures pre-S apps that look
+            // for ENCODING_PCM_FLOAT continue to see that encoding if the device supports
+            // extended precision integers.
+            int[] encodingsPlusFloat = Arrays.copyOf(encodings, encodings.length + 1);
+            encodingsPlusFloat[encodings.length] = AudioFormat.ENCODING_PCM_FLOAT;
+            return encodingsPlusFloat;
+        }
+        return encodings;
     }
 
     /**
diff --git a/media/java/android/media/AudioFormat.java b/media/java/android/media/AudioFormat.java
index 090812e..5885c7d 100644
--- a/media/java/android/media/AudioFormat.java
+++ b/media/java/android/media/AudioFormat.java
@@ -110,6 +110,24 @@
  * <code>AudioTrack</code> as of API {@link android.os.Build.VERSION_CODES#LOLLIPOP}
  * support <code>ENCODING_PCM_FLOAT</code>.
  * </li>
+ * <li> {@link #ENCODING_PCM_24BIT_PACKED}: Introduced in
+ * API {@link android.os.Build.VERSION_CODES#S},
+ * this encoding specifies the audio sample is an
+ * extended precision 24 bit signed integer
+ * stored as a 3 Java bytes in a {@code ByteBuffer} or byte array in native endian
+ * (see {@link java.nio.ByteOrder#nativeOrder()}).
+ * Each sample has full range from [-8388608, 8388607],
+ * and can be interpreted as fixed point Q.23 data.
+ * </li>
+ * <li> {@link #ENCODING_PCM_32BIT}: Introduced in
+ * API {@link android.os.Build.VERSION_CODES#S},
+ * this encoding specifies the audio sample is an
+ * extended precision 32 bit signed integer
+ * stored as a 4 Java bytes in a {@code ByteBuffer} or byte array in native endian
+ * (see {@link java.nio.ByteOrder#nativeOrder()}).
+ * Each sample has full range from [-2147483648, 2147483647],
+ * and can be interpreted as fixed point Q.31 data.
+ * </li>
  * </ul>
  * <p>For compressed audio, the encoding specifies the method of compression,
  * for example {@link #ENCODING_AC3} and {@link #ENCODING_DTS}. The compressed
@@ -285,6 +303,32 @@
     /** Audio data format: OPUS compressed. */
     public static final int ENCODING_OPUS = 20;
 
+    /** @hide
+     * We do not permit legacy short array reads or writes for encodings
+     * introduced after this threshold.
+     */
+    public static final int ENCODING_LEGACY_SHORT_ARRAY_THRESHOLD = ENCODING_OPUS;
+
+    /** Audio data format: PCM 24 bit per sample packed as 3 bytes.
+     * Not guaranteed to be supported by devices, may be emulated if not supported. */
+    public static final int ENCODING_PCM_24BIT_PACKED = 21;
+    /** Audio data format: PCM 32 bit per sample.
+     * Not guaranteed to be supported by devices, may be emulated if not supported. */
+    public static final int ENCODING_PCM_32BIT = 22;
+
+    /** Audio data format: MPEG-H baseline profile, level 3 */
+    public static final int ENCODING_MPEGH_BL_L3 = 23;
+    /** Audio data format: MPEG-H baseline profile, level 4 */
+    public static final int ENCODING_MPEGH_BL_L4 = 24;
+    /** Audio data format: MPEG-H low complexity profile, level 3 */
+    public static final int ENCODING_MPEGH_LC_L3 = 25;
+    /** Audio data format: MPEG-H low complexity profile, level 4 */
+    public static final int ENCODING_MPEGH_LC_L4 = 26;
+    /** Audio data format: DTS UHD compressed */
+    public static final int ENCODING_DTS_UHD = 27;
+    /** Audio data format: DRA compressed */
+    public static final int ENCODING_DRA = 28;
+
     /** @hide */
     public static String toLogFriendlyEncoding(int enc) {
         switch(enc) {
@@ -328,6 +372,22 @@
                 return "ENCODING_DOLBY_MAT";
             case ENCODING_OPUS:
                 return "ENCODING_OPUS";
+            case ENCODING_PCM_24BIT_PACKED:
+                return "ENCODING_PCM_24BIT_PACKED";
+            case ENCODING_PCM_32BIT:
+                return "ENCODING_PCM_32BIT";
+            case ENCODING_MPEGH_BL_L3:
+                return "ENCODING_MPEGH_BL_L3";
+            case ENCODING_MPEGH_BL_L4:
+                return "ENCODING_MPEGH_BL_L4";
+            case ENCODING_MPEGH_LC_L3:
+                return "ENCODING_MPEGH_LC_L3";
+            case ENCODING_MPEGH_LC_L4:
+                return "ENCODING_MPEGH_LC_L4";
+            case ENCODING_DTS_UHD:
+                return "ENCODING_DTS_UHD";
+            case ENCODING_DRA:
+                return "ENCODING_DRA";
             default :
                 return "invalid encoding " + enc;
         }
@@ -458,13 +518,13 @@
      * @hide
      */
     // never unhide
-    public static final int SAMPLE_RATE_HZ_MIN = 4000;
+    public static final int SAMPLE_RATE_HZ_MIN = AudioSystem.SAMPLE_RATE_HZ_MIN;
     /** Maximum value for sample rate,
      *  assuming AudioTrack and AudioRecord share the same limitations.
      * @hide
      */
     // never unhide
-    public static final int SAMPLE_RATE_HZ_MAX = 192000;
+    public static final int SAMPLE_RATE_HZ_MAX = AudioSystem.SAMPLE_RATE_HZ_MAX;
     /** Sample rate will be a route-dependent value.
      * For AudioTrack, it is usually the sink sample rate,
      * and for AudioRecord it is usually the source sample rate.
@@ -561,17 +621,20 @@
     public static int getBytesPerSample(int audioFormat)
     {
         switch (audioFormat) {
-        case ENCODING_PCM_8BIT:
-            return 1;
-        case ENCODING_PCM_16BIT:
-        case ENCODING_IEC61937:
-        case ENCODING_DEFAULT:
-            return 2;
-        case ENCODING_PCM_FLOAT:
-            return 4;
-        case ENCODING_INVALID:
-        default:
-            throw new IllegalArgumentException("Bad audio format " + audioFormat);
+            case ENCODING_PCM_8BIT:
+                return 1;
+            case ENCODING_PCM_16BIT:
+            case ENCODING_IEC61937:
+            case ENCODING_DEFAULT:
+                return 2;
+            case ENCODING_PCM_24BIT_PACKED:
+                return 3;
+            case ENCODING_PCM_FLOAT:
+            case ENCODING_PCM_32BIT:
+                return 4;
+            case ENCODING_INVALID:
+            default:
+                throw new IllegalArgumentException("Bad audio format " + audioFormat);
         }
     }
 
@@ -598,6 +661,14 @@
             case ENCODING_E_AC3_JOC:
             case ENCODING_DOLBY_MAT:
             case ENCODING_OPUS:
+            case ENCODING_PCM_24BIT_PACKED:
+            case ENCODING_PCM_32BIT:
+            case ENCODING_MPEGH_BL_L3:
+            case ENCODING_MPEGH_BL_L4:
+            case ENCODING_MPEGH_LC_L3:
+            case ENCODING_MPEGH_LC_L4:
+            case ENCODING_DTS_UHD:
+            case ENCODING_DRA:
                 return true;
             default:
                 return false;
@@ -627,6 +698,14 @@
             case ENCODING_E_AC3_JOC:
             case ENCODING_DOLBY_MAT:
             case ENCODING_OPUS:
+            case ENCODING_PCM_24BIT_PACKED:
+            case ENCODING_PCM_32BIT:
+            case ENCODING_MPEGH_BL_L3:
+            case ENCODING_MPEGH_BL_L4:
+            case ENCODING_MPEGH_LC_L3:
+            case ENCODING_MPEGH_LC_L4:
+            case ENCODING_DTS_UHD:
+            case ENCODING_DRA:
                 return true;
             default:
                 return false;
@@ -641,6 +720,8 @@
             case ENCODING_PCM_16BIT:
             case ENCODING_PCM_8BIT:
             case ENCODING_PCM_FLOAT:
+            case ENCODING_PCM_24BIT_PACKED:
+            case ENCODING_PCM_32BIT:
             case ENCODING_DEFAULT:
                 return true;
             case ENCODING_AC3:
@@ -659,6 +740,12 @@
             case ENCODING_E_AC3_JOC:
             case ENCODING_DOLBY_MAT:
             case ENCODING_OPUS:
+            case ENCODING_MPEGH_BL_L3:
+            case ENCODING_MPEGH_BL_L4:
+            case ENCODING_MPEGH_LC_L3:
+            case ENCODING_MPEGH_LC_L4:
+            case ENCODING_DTS_UHD:
+            case ENCODING_DRA:
                 return false;
             case ENCODING_INVALID:
             default:
@@ -674,6 +761,8 @@
             case ENCODING_PCM_8BIT:
             case ENCODING_PCM_FLOAT:
             case ENCODING_IEC61937: // same size as stereo PCM
+            case ENCODING_PCM_24BIT_PACKED:
+            case ENCODING_PCM_32BIT:
             case ENCODING_DEFAULT:
                 return true;
             case ENCODING_AC3:
@@ -691,6 +780,12 @@
             case ENCODING_E_AC3_JOC:
             case ENCODING_DOLBY_MAT:
             case ENCODING_OPUS:
+            case ENCODING_MPEGH_BL_L3:
+            case ENCODING_MPEGH_BL_L4:
+            case ENCODING_MPEGH_LC_L3:
+            case ENCODING_MPEGH_LC_L4:
+            case ENCODING_DTS_UHD:
+            case ENCODING_DRA:
                 return false;
             case ENCODING_INVALID:
             default:
@@ -971,6 +1066,14 @@
                 case ENCODING_E_AC3_JOC:
                 case ENCODING_DOLBY_MAT:
                 case ENCODING_OPUS:
+                case ENCODING_PCM_24BIT_PACKED:
+                case ENCODING_PCM_32BIT:
+                case ENCODING_MPEGH_BL_L3:
+                case ENCODING_MPEGH_BL_L4:
+                case ENCODING_MPEGH_LC_L3:
+                case ENCODING_MPEGH_LC_L4:
+                case ENCODING_DTS_UHD:
+                case ENCODING_DRA:
                     mEncoding = encoding;
                     break;
                 case ENCODING_INVALID:
@@ -1191,7 +1294,15 @@
         ENCODING_AC4,
         ENCODING_E_AC3_JOC,
         ENCODING_DOLBY_MAT,
-        ENCODING_OPUS }
+        ENCODING_OPUS,
+        ENCODING_PCM_24BIT_PACKED,
+        ENCODING_PCM_32BIT,
+        ENCODING_MPEGH_BL_L3,
+        ENCODING_MPEGH_BL_L4,
+        ENCODING_MPEGH_LC_L3,
+        ENCODING_MPEGH_LC_L4,
+        ENCODING_DTS_UHD,
+        ENCODING_DRA }
     )
     @Retention(RetentionPolicy.SOURCE)
     public @interface Encoding {}
@@ -1207,6 +1318,12 @@
             ENCODING_AC4,
             ENCODING_E_AC3_JOC,
             ENCODING_DOLBY_MAT,
+            ENCODING_MPEGH_BL_L3,
+            ENCODING_MPEGH_BL_L4,
+            ENCODING_MPEGH_LC_L3,
+            ENCODING_MPEGH_LC_L4,
+            ENCODING_DTS_UHD,
+            ENCODING_DRA
     };
 
     /** @hide */
@@ -1219,7 +1336,13 @@
             ENCODING_DOLBY_TRUEHD,
             ENCODING_AC4,
             ENCODING_E_AC3_JOC,
-            ENCODING_DOLBY_MAT }
+            ENCODING_DOLBY_MAT,
+            ENCODING_MPEGH_BL_L3,
+            ENCODING_MPEGH_BL_L4,
+            ENCODING_MPEGH_LC_L3,
+            ENCODING_MPEGH_LC_L4,
+            ENCODING_DTS_UHD,
+            ENCODING_DRA }
     )
     @Retention(RetentionPolicy.SOURCE)
     public @interface SurroundSoundEncoding {}
@@ -1253,6 +1376,18 @@
                 return "Dolby Atmos in Dolby Digital Plus";
             case ENCODING_DOLBY_MAT:
                 return "Dolby MAT";
+            case ENCODING_MPEGH_BL_L3:
+                return "MPEG-H 3D Audio baseline profile level 3";
+            case ENCODING_MPEGH_BL_L4:
+                return "MPEG-H 3D Audio baseline profile level 4";
+            case ENCODING_MPEGH_LC_L3:
+                return "MPEG-H 3D Audio low complexity profile level 3";
+            case ENCODING_MPEGH_LC_L4:
+                return "MPEG-H 3D Audio low complexity profile level 4";
+            case ENCODING_DTS_UHD:
+                return "DTS UHD";
+            case ENCODING_DRA:
+                return "DRA";
             default:
                 return "Unknown surround sound format";
         }
diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java
index d670f07..52233b6 100644
--- a/media/java/android/media/AudioRecord.java
+++ b/media/java/android/media/AudioRecord.java
@@ -845,17 +845,21 @@
         //--------------
         // audio format
         switch (audioFormat) {
-        case AudioFormat.ENCODING_DEFAULT:
-            mAudioFormat = AudioFormat.ENCODING_PCM_16BIT;
-            break;
-        case AudioFormat.ENCODING_PCM_FLOAT:
-        case AudioFormat.ENCODING_PCM_16BIT:
-        case AudioFormat.ENCODING_PCM_8BIT:
-            mAudioFormat = audioFormat;
-            break;
-        default:
-            throw new IllegalArgumentException("Unsupported sample encoding " + audioFormat
-                    + ". Should be ENCODING_PCM_8BIT, ENCODING_PCM_16BIT, or ENCODING_PCM_FLOAT.");
+            case AudioFormat.ENCODING_DEFAULT:
+                mAudioFormat = AudioFormat.ENCODING_PCM_16BIT;
+                break;
+            case AudioFormat.ENCODING_PCM_24BIT_PACKED:
+            case AudioFormat.ENCODING_PCM_32BIT:
+            case AudioFormat.ENCODING_PCM_FLOAT:
+            case AudioFormat.ENCODING_PCM_16BIT:
+            case AudioFormat.ENCODING_PCM_8BIT:
+                mAudioFormat = audioFormat;
+                break;
+            default:
+                throw new IllegalArgumentException("Unsupported sample encoding " + audioFormat
+                        + ". Should be ENCODING_PCM_8BIT, ENCODING_PCM_16BIT,"
+                        + " ENCODING_PCM_24BIT_PACKED, ENCODING_PCM_32BIT,"
+                        + " or ENCODING_PCM_FLOAT.");
         }
     }
 
@@ -1262,6 +1266,7 @@
      */
     public int read(@NonNull byte[] audioData, int offsetInBytes, int sizeInBytes,
             @ReadMode int readMode) {
+        // Note: we allow reads of extended integers into a byte array.
         if (mState != STATE_INITIALIZED  || mAudioFormat == AudioFormat.ENCODING_PCM_FLOAT) {
             return ERROR_INVALID_OPERATION;
         }
@@ -1334,7 +1339,10 @@
      */
     public int read(@NonNull short[] audioData, int offsetInShorts, int sizeInShorts,
             @ReadMode int readMode) {
-        if (mState != STATE_INITIALIZED || mAudioFormat == AudioFormat.ENCODING_PCM_FLOAT) {
+        if (mState != STATE_INITIALIZED
+                || mAudioFormat == AudioFormat.ENCODING_PCM_FLOAT
+                // use ByteBuffer instead for later encodings
+                || mAudioFormat > AudioFormat.ENCODING_LEGACY_SHORT_ARRAY_THRESHOLD) {
             return ERROR_INVALID_OPERATION;
         }
 
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index 18c8a72..3131965 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -101,11 +101,34 @@
      */
     public static final int NUM_STREAMS = 5;
 
-    /** Maximum value for AudioTrack channel count
-     * @hide public for MediaCode only, do not un-hide or change to a numeric literal
+    /*
+     * Framework static final constants that are primitives or Strings
+     * accessed by CTS tests or internal applications must be set from methods
+     * (or in a static block) to prevent Java compile-time replacement.
+     * We set them from methods so they are read from the device framework.
+     * Do not un-hide or change to a numeric literal.
      */
-    public static final int OUT_CHANNEL_COUNT_MAX = native_get_FCC_8();
-    private static native int native_get_FCC_8();
+
+    /** Maximum value for AudioTrack channel count
+     * @hide
+     */
+    public static final int OUT_CHANNEL_COUNT_MAX = native_getMaxChannelCount();
+    private static native int native_getMaxChannelCount();
+
+    /** Maximum value for sample rate, used by AudioFormat.
+     * @hide
+     */
+    public static final int SAMPLE_RATE_HZ_MAX = native_getMaxSampleRate();
+    private static native int native_getMaxSampleRate();
+
+    /** Minimum value for sample rate, used by AudioFormat.
+     * @hide
+     */
+    public static final int SAMPLE_RATE_HZ_MIN = native_getMinSampleRate();
+    private static native int native_getMinSampleRate();
+
+    /** @hide */
+    public static final int FCC_24 = 24; // fixed channel count 24; do not change.
 
     // Expose only the getter method publicly so we can change it in the future
     private static final int NUM_STREAM_TYPES = 12;
@@ -424,6 +447,10 @@
                 return "AUDIO_FORMAT_MAT_2_0"; // (MAT | MAT_SUB_2_0)
             case /* AUDIO_FORMAT_MAT_2_1           */ 0x24000003:
                 return "AUDIO_FORMAT_MAT_2_1"; // (MAT | MAT_SUB_2_1)
+            case /* AUDIO_FORMAT_DTS_UHD */           0x2E000000:
+                return "AUDIO_FORMAT_DTS_UHD";
+            case /* AUDIO_FORMAT_DRA */           0x2F000000:
+                return "AUDIO_FORMAT_DRA";
             default:
                 return "AUDIO_FORMAT_(" + audioFormat + ")";
         }
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index 67880a5..68ce5e7 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -1712,9 +1712,10 @@
                 mChannelCount = 0;
                 break; // channel index configuration only
             }
-            if (!isMultichannelConfigSupported(channelConfig)) {
-                // input channel configuration features unsupported channels
-                throw new IllegalArgumentException("Unsupported channel configuration.");
+            if (!isMultichannelConfigSupported(channelConfig, audioFormat)) {
+                throw new IllegalArgumentException(
+                        "Unsupported channel mask configuration " + channelConfig
+                        + " for encoding " + audioFormat);
             }
             mChannelMask = channelConfig;
             mChannelCount = AudioFormat.channelCountFromOutChannelMask(channelConfig);
@@ -1722,13 +1723,17 @@
         // check the channel index configuration (if present)
         mChannelIndexMask = channelIndexMask;
         if (mChannelIndexMask != 0) {
-            // restrictive: indexMask could allow up to AUDIO_CHANNEL_BITS_LOG2
-            final int indexMask = (1 << AudioSystem.OUT_CHANNEL_COUNT_MAX) - 1;
-            if ((channelIndexMask & ~indexMask) != 0) {
-                throw new IllegalArgumentException("Unsupported channel index configuration "
-                        + channelIndexMask);
+            // As of S, we accept up to 24 channel index mask.
+            final int fullIndexMask = (1 << AudioSystem.FCC_24) - 1;
+            final int channelIndexCount = Integer.bitCount(channelIndexMask);
+            final boolean accepted = (channelIndexMask & ~fullIndexMask) == 0
+                    && (!AudioFormat.isEncodingLinearFrames(audioFormat)  // compressed OK
+                            || channelIndexCount <= AudioSystem.OUT_CHANNEL_COUNT_MAX); // PCM
+            if (!accepted) {
+                throw new IllegalArgumentException(
+                        "Unsupported channel index mask configuration " + channelIndexMask
+                        + " for encoding " + audioFormat);
             }
-            int channelIndexCount = Integer.bitCount(channelIndexMask);
             if (mChannelCount == 0) {
                  mChannelCount = channelIndexCount;
             } else if (mChannelCount != channelIndexCount) {
@@ -1781,16 +1786,19 @@
      * @param channelConfig the mask to validate
      * @return false if the AudioTrack can't be used with such a mask
      */
-    private static boolean isMultichannelConfigSupported(int channelConfig) {
+    private static boolean isMultichannelConfigSupported(int channelConfig, int encoding) {
         // check for unsupported channels
         if ((channelConfig & SUPPORTED_OUT_CHANNELS) != channelConfig) {
             loge("Channel configuration features unsupported channels");
             return false;
         }
         final int channelCount = AudioFormat.channelCountFromOutChannelMask(channelConfig);
-        if (channelCount > AudioSystem.OUT_CHANNEL_COUNT_MAX) {
-            loge("Channel configuration contains too many channels " +
-                    channelCount + ">" + AudioSystem.OUT_CHANNEL_COUNT_MAX);
+        final int channelCountLimit = AudioFormat.isEncodingLinearFrames(encoding)
+                ? AudioSystem.OUT_CHANNEL_COUNT_MAX  // PCM limited to OUT_CHANNEL_COUNT_MAX
+                : AudioSystem.FCC_24;                // Compressed limited to 24 channels
+        if (channelCount > channelCountLimit) {
+            loge("Channel configuration contains too many channels for encoding "
+                    + encoding + "(" + channelCount + " > " + channelCountLimit + ")");
             return false;
         }
         // check for unsupported multichannel combinations:
@@ -2301,7 +2309,7 @@
             channelCount = 2;
             break;
         default:
-            if (!isMultichannelConfigSupported(channelConfig)) {
+            if (!isMultichannelConfigSupported(channelConfig, audioFormat)) {
                 loge("getMinBufferSize(): Invalid channel configuration.");
                 return ERROR_BAD_VALUE;
             } else {
@@ -2992,7 +3000,7 @@
      */
     public int write(@NonNull byte[] audioData, int offsetInBytes, int sizeInBytes,
             @WriteMode int writeMode) {
-
+        // Note: we allow writes of extended integers and compressed formats from a byte array.
         if (mState == STATE_UNINITIALIZED || mAudioFormat == AudioFormat.ENCODING_PCM_FLOAT) {
             return ERROR_INVALID_OPERATION;
         }
@@ -3106,7 +3114,10 @@
     public int write(@NonNull short[] audioData, int offsetInShorts, int sizeInShorts,
             @WriteMode int writeMode) {
 
-        if (mState == STATE_UNINITIALIZED || mAudioFormat == AudioFormat.ENCODING_PCM_FLOAT) {
+        if (mState == STATE_UNINITIALIZED
+                || mAudioFormat == AudioFormat.ENCODING_PCM_FLOAT
+                // use ByteBuffer or byte[] instead for later encodings
+                || mAudioFormat > AudioFormat.ENCODING_LEGACY_SHORT_ARRAY_THRESHOLD) {
             return ERROR_INVALID_OPERATION;
         }
 
diff --git a/media/java/android/media/MediaFormat.java b/media/java/android/media/MediaFormat.java
index 13c6907..17f3e96 100644
--- a/media/java/android/media/MediaFormat.java
+++ b/media/java/android/media/MediaFormat.java
@@ -169,6 +169,10 @@
     public static final String MIMETYPE_AUDIO_EAC3_JOC = "audio/eac3-joc";
     public static final String MIMETYPE_AUDIO_AC4 = "audio/ac4";
     public static final String MIMETYPE_AUDIO_SCRAMBLED = "audio/scrambled";
+    /** MIME type for MPEG-H Audio single stream */
+    public static final String MIMETYPE_AUDIO_MPEGH_MHA1 = "audio/mha1";
+    /** MIME type for MPEG-H Audio single stream, encapsulated in MHAS */
+    public static final String MIMETYPE_AUDIO_MPEGH_MHM1 = "audio/mhm1";
 
     /**
      * MIME type for HEIF still image data encoded in HEVC.
diff --git a/mime/java/android/content/type/DefaultMimeMapFactory.java b/mime/java/android/content/type/DefaultMimeMapFactory.java
index 11d20d4..bcd0eb0 100644
--- a/mime/java/android/content/type/DefaultMimeMapFactory.java
+++ b/mime/java/android/content/type/DefaultMimeMapFactory.java
@@ -96,7 +96,7 @@
                     specs.add(spec);
                     startIdx = endIdx + 1; // skip over the space
                 } while (startIdx < line.length());
-                builder.put(specs.get(0), specs.subList(1, specs.size()));
+                builder.addMimeMapping(specs.get(0), specs.subList(1, specs.size()));
             }
         } catch (IOException | RuntimeException e) {
             throw new RuntimeException("Failed to parse " + resourceName, e);
diff --git a/native/android/Android.bp b/native/android/Android.bp
index 2a2b08d..dda230d 100644
--- a/native/android/Android.bp
+++ b/native/android/Android.bp
@@ -115,7 +115,11 @@
 cc_library_shared {
     name: "libandroid_net",
     defaults: ["libandroid_defaults"],
-    llndk_stubs: "libandroid_net.llndk",
+    llndk: {
+        symbol_file: "libandroid_net.map.txt",
+        unversioned: true,
+        override_export_include_dirs: ["include"],
+    },
     srcs: ["net.c"],
 
     shared_libs: ["libnetd_client"],
@@ -123,13 +127,6 @@
     include_dirs: ["bionic/libc/dns/include"],
 }
 
-llndk_library {
-    name: "libandroid_net.llndk",
-    export_include_dirs: ["include"],
-    symbol_file: "libandroid_net.map.txt",
-    unversioned: true,
-}
-
 // Aidl library for platform compat.
 cc_library_shared {
     name: "lib-platform-compat-native-api",
diff --git a/packages/Connectivity/framework/Android.bp b/packages/Connectivity/framework/Android.bp
index 017ff51..657d5a3 100644
--- a/packages/Connectivity/framework/Android.bp
+++ b/packages/Connectivity/framework/Android.bp
@@ -25,6 +25,7 @@
 
 java_library {
     name: "framework-connectivity-protos",
+    sdk_version: "module_current",
     proto: {
         type: "nano",
     },
@@ -82,8 +83,7 @@
     name: "framework-connectivity",
     api_only: true,
     defaults: ["framework-module-defaults"],
-    // TODO: build against module API
-    platform_apis: true,
+    installable: true,
     srcs: [
         ":framework-connectivity-sources",
     ],
@@ -100,18 +100,56 @@
     libs: [
         "unsupportedappusage",
     ],
-    permitted_packages: ["android.net", "com.android.connectivity.aidl"],
+    permitted_packages: ["android.net"],
+}
+
+cc_defaults {
+    name: "libframework-connectivity-defaults",
+    cflags: [
+        "-Wall",
+        "-Werror",
+        "-Wno-unused-parameter",
+        "-Wthread-safety",
+    ],
+    shared_libs: [
+        "libbase",
+        "liblog",
+        "libnativehelper",
+        "libnetd_client",
+    ],
+    header_libs: [
+        "dnsproxyd_protocol_headers",
+    ],
+}
+
+cc_library_static {
+    name: "libconnectivityframeworkutils",
+    defaults: ["libframework-connectivity-defaults"],
+    srcs: [
+        "jni/android_net_NetworkUtils.cpp",
+    ],
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.tethering",
+    ],
+}
+
+cc_library_shared {
+    name: "libframework-connectivity-jni",
+    defaults: ["libframework-connectivity-defaults"],
+    srcs: [
+        "jni/onload.cpp",
+    ],
+    static_libs: ["libconnectivityframeworkutils"],
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.tethering",
+    ],
 }
 
 java_library {
     name: "framework-connectivity.impl",
-    // Instead of building against private API (framework.jar),
-    // build against core_platform + framework-minus-apex + module
-    // stub libs. This allows framework.jar to depend on this library,
-    // so it can be part of the private API until all clients have been migrated.
-    // TODO: just build against module_api, and remove this jar from
-    // the private API.
-    sdk_version: "core_platform",
+    sdk_version: "module_current",
     srcs: [
         ":framework-connectivity-sources",
     ],
@@ -122,12 +160,11 @@
         ],
     },
     libs: [
-        "framework-minus-apex",
-        // TODO: just framework-tethering, framework-wifi when building against module_api
-        "framework-tethering.stubs.module_lib",
-        "framework-wifi.stubs.module_lib",
+        // TODO (b/183097033) remove once module_current includes core_current
+        "stable.core.platform.api.stubs",
+        "framework-tethering",
+        "framework-wifi",
         "unsupportedappusage",
-        "ServiceConnectivityResources",
     ],
     static_libs: [
         "framework-connectivity-protos",
@@ -136,5 +173,5 @@
     jarjar_rules: "jarjar-rules.txt",
     apex_available: ["com.android.tethering"],
     installable: true,
-    permitted_packages: ["android.net", "com.android.connectivity.aidl"],
+    permitted_packages: ["android.net"],
 }
diff --git a/packages/Connectivity/framework/api/module-lib-current.txt b/packages/Connectivity/framework/api/module-lib-current.txt
index 9e2cd3e..78dff21 100644
--- a/packages/Connectivity/framework/api/module-lib-current.txt
+++ b/packages/Connectivity/framework/api/module-lib-current.txt
@@ -7,11 +7,10 @@
 
   public class ConnectivityManager {
     method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void factoryReset();
-    method @NonNull @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public java.util.List<android.net.NetworkStateSnapshot> getAllNetworkStateSnapshot();
+    method @NonNull @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public java.util.List<android.net.NetworkStateSnapshot> getAllNetworkStateSnapshots();
     method @Nullable public android.net.ProxyInfo getGlobalProxy();
     method @NonNull public static android.util.Range<java.lang.Integer> getIpSecNetIdRange();
-    method @NonNull public static String getPrivateDnsMode(@NonNull android.content.Context);
-    method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void registerDefaultNetworkCallbackAsUid(int, @NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler);
+    method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void registerDefaultNetworkCallbackForUid(int, @NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler);
     method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void registerSystemDefaultNetworkCallback(@NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler);
     method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void requestBackgroundNetwork(@NonNull android.net.NetworkRequest, @NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler);
     method @Deprecated public boolean requestRouteToHostAddress(int, java.net.InetAddress);
@@ -20,7 +19,6 @@
     method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void setAvoidUnvalidated(@NonNull android.net.Network);
     method @RequiresPermission(android.Manifest.permission.NETWORK_STACK) public void setGlobalProxy(@Nullable android.net.ProxyInfo);
     method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void setLegacyLockdownVpnEnabled(boolean);
-    method public static void setPrivateDnsMode(@NonNull android.content.Context, @NonNull String);
     method @RequiresPermission(android.Manifest.permission.NETWORK_STACK) public void setProfileNetworkPreference(@NonNull android.os.UserHandle, int, @Nullable java.util.concurrent.Executor, @Nullable Runnable);
     method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void setRequireVpnForUids(boolean, @NonNull java.util.Collection<android.util.Range<java.lang.Integer>>);
     method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_TEST_NETWORKS, android.Manifest.permission.NETWORK_STACK}) public void simulateDataStall(int, long, @NonNull android.net.Network, @NonNull android.os.PersistableBundle);
@@ -40,9 +38,6 @@
     field public static final int BLOCKED_REASON_LOCKDOWN_VPN = 16; // 0x10
     field public static final int BLOCKED_REASON_NONE = 0; // 0x0
     field public static final int BLOCKED_REASON_RESTRICTED_MODE = 8; // 0x8
-    field public static final String PRIVATE_DNS_MODE_OFF = "off";
-    field public static final String PRIVATE_DNS_MODE_OPPORTUNISTIC = "opportunistic";
-    field public static final String PRIVATE_DNS_MODE_PROVIDER_HOSTNAME = "hostname";
     field public static final int PROFILE_NETWORK_PREFERENCE_DEFAULT = 0; // 0x0
     field public static final int PROFILE_NETWORK_PREFERENCE_ENTERPRISE = 1; // 0x1
   }
@@ -69,6 +64,7 @@
     method @NonNull public static java.time.Duration getNetworkSwitchNotificationRateDuration(@NonNull android.content.Context, @NonNull java.time.Duration);
     method @NonNull public static String getPrivateDnsDefaultMode(@NonNull android.content.Context);
     method @Nullable public static String getPrivateDnsHostname(@NonNull android.content.Context);
+    method public static int getPrivateDnsMode(@NonNull android.content.Context);
     method public static boolean getWifiAlwaysRequested(@NonNull android.content.Context, boolean);
     method @NonNull public static java.time.Duration getWifiDataActivityTimeout(@NonNull android.content.Context, @NonNull java.time.Duration);
     method public static void setCaptivePortalHttpUrl(@NonNull android.content.Context, @Nullable String);
@@ -85,8 +81,9 @@
     method public static void setNetworkMeteredMultipathPreference(@NonNull android.content.Context, @NonNull String);
     method public static void setNetworkSwitchNotificationMaximumDailyCount(@NonNull android.content.Context, @IntRange(from=0) int);
     method public static void setNetworkSwitchNotificationRateDuration(@NonNull android.content.Context, @NonNull java.time.Duration);
-    method public static void setPrivateDnsDefaultMode(@NonNull android.content.Context, @NonNull String);
+    method public static void setPrivateDnsDefaultMode(@NonNull android.content.Context, @NonNull int);
     method public static void setPrivateDnsHostname(@NonNull android.content.Context, @Nullable String);
+    method public static void setPrivateDnsMode(@NonNull android.content.Context, int);
     method public static void setWifiAlwaysRequested(@NonNull android.content.Context, boolean);
     method public static void setWifiDataActivityTimeout(@NonNull android.content.Context, @NonNull java.time.Duration);
     field public static final int CAPTIVE_PORTAL_MODE_AVOID = 2; // 0x2
@@ -95,6 +92,9 @@
     field public static final int NETWORK_AVOID_BAD_WIFI_AVOID = 2; // 0x2
     field public static final int NETWORK_AVOID_BAD_WIFI_IGNORE = 0; // 0x0
     field public static final int NETWORK_AVOID_BAD_WIFI_PROMPT = 1; // 0x1
+    field public static final int PRIVATE_DNS_MODE_OFF = 1; // 0x1
+    field public static final int PRIVATE_DNS_MODE_OPPORTUNISTIC = 2; // 0x2
+    field public static final int PRIVATE_DNS_MODE_PROVIDER_HOSTNAME = 3; // 0x3
   }
 
   public final class NetworkAgentConfig implements android.os.Parcelable {
@@ -109,7 +109,7 @@
 
   public final class NetworkCapabilities implements android.os.Parcelable {
     method @Nullable public java.util.Set<android.util.Range<java.lang.Integer>> getUids();
-    method public boolean hasUnwantedCapability(int);
+    method public boolean hasForbiddenCapability(int);
     field public static final long REDACT_ALL = -1L; // 0xffffffffffffffffL
     field public static final long REDACT_FOR_ACCESS_FINE_LOCATION = 1L; // 0x1L
     field public static final long REDACT_FOR_LOCAL_MAC_ADDRESS = 2L; // 0x2L
@@ -123,13 +123,13 @@
   }
 
   public class NetworkRequest implements android.os.Parcelable {
-    method @NonNull public int[] getUnwantedCapabilities();
-    method public boolean hasUnwantedCapability(int);
+    method @NonNull public int[] getForbiddenCapabilities();
+    method public boolean hasForbiddenCapability(int);
   }
 
   public static class NetworkRequest.Builder {
-    method @NonNull public android.net.NetworkRequest.Builder addUnwantedCapability(int);
-    method @NonNull public android.net.NetworkRequest.Builder removeUnwantedCapability(int);
+    method @NonNull public android.net.NetworkRequest.Builder addForbiddenCapability(int);
+    method @NonNull public android.net.NetworkRequest.Builder removeForbiddenCapability(int);
     method @NonNull public android.net.NetworkRequest.Builder setUids(@Nullable java.util.Set<android.util.Range<java.lang.Integer>>);
   }
 
@@ -166,11 +166,11 @@
   public final class VpnTransportInfo implements android.os.Parcelable android.net.TransportInfo {
     ctor public VpnTransportInfo(int, @Nullable String);
     method public int describeContents();
+    method @Nullable public String getSessionId();
+    method public int getType();
     method @NonNull public android.net.VpnTransportInfo makeCopy(long);
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.net.VpnTransportInfo> CREATOR;
-    field @Nullable public final String sessionId;
-    field public final int type;
   }
 
 }
diff --git a/packages/Connectivity/framework/api/system-current.txt b/packages/Connectivity/framework/api/system-current.txt
index 935b093..5750845 100644
--- a/packages/Connectivity/framework/api/system-current.txt
+++ b/packages/Connectivity/framework/api/system-current.txt
@@ -238,7 +238,7 @@
     method public final void sendQosSessionLost(int, int, int);
     method public final void sendSocketKeepaliveEvent(int, int);
     method @Deprecated public void setLegacySubtype(int, @NonNull String);
-    method public void setTeardownDelayMs(@IntRange(from=0, to=0x1388) int);
+    method public void setTeardownDelayMillis(@IntRange(from=0, to=0x1388) int);
     method public final void setUnderlyingNetworks(@Nullable java.util.List<android.net.Network>);
     method public void unregister();
     field public static final int VALIDATION_STATUS_NOT_VALID = 2; // 0x2
diff --git a/core/jni/android_net_NetworkUtils.cpp b/packages/Connectivity/framework/jni/android_net_NetworkUtils.cpp
similarity index 93%
rename from core/jni/android_net_NetworkUtils.cpp
rename to packages/Connectivity/framework/jni/android_net_NetworkUtils.cpp
index 1cee895..48e262a 100644
--- a/core/jni/android_net_NetworkUtils.cpp
+++ b/packages/Connectivity/framework/jni/android_net_NetworkUtils.cpp
@@ -30,13 +30,13 @@
 
 #include <DnsProxydProtocol.h> // NETID_USE_LOCAL_NAMESERVERS
 #include <cutils/properties.h>
+#include <nativehelper/JNIHelp.h>
 #include <nativehelper/JNIPlatformHelp.h>
 #include <nativehelper/ScopedLocalRef.h>
 #include <utils/Log.h>
 #include <utils/misc.h>
 
 #include "NetdClient.h"
-#include "core_jni_helpers.h"
 #include "jni.h"
 
 extern "C" {
@@ -52,6 +52,19 @@
 // FrameworkListener limits the size of commands to 4096 bytes.
 constexpr int MAXCMDSIZE = 4096;
 
+static inline jclass FindClassOrDie(JNIEnv* env, const char* class_name) {
+    jclass clazz = env->FindClass(class_name);
+    LOG_ALWAYS_FATAL_IF(clazz == NULL, "Unable to find class %s", class_name);
+    return clazz;
+}
+
+template <typename T>
+static inline T MakeGlobalRefOrDie(JNIEnv* env, T in) {
+    jobject res = env->NewGlobalRef(in);
+    LOG_ALWAYS_FATAL_IF(res == NULL, "Unable to create global reference.");
+    return static_cast<T>(res);
+}
+
 static void android_net_utils_attachDropAllBPFFilter(JNIEnv *env, jobject clazz, jobject javaFd)
 {
     struct sock_filter filter_code[] = {
@@ -254,8 +267,8 @@
 
 int register_android_net_NetworkUtils(JNIEnv* env)
 {
-    return RegisterMethodsOrDie(env, NETUTILS_PKG_NAME, gNetworkUtilMethods,
-                                NELEM(gNetworkUtilMethods));
+    return jniRegisterNativeMethods(env, NETUTILS_PKG_NAME, gNetworkUtilMethods,
+                                    NELEM(gNetworkUtilMethods));
 }
 
 }; // namespace android
diff --git a/packages/Connectivity/framework/jni/onload.cpp b/packages/Connectivity/framework/jni/onload.cpp
new file mode 100644
index 0000000..435f434
--- /dev/null
+++ b/packages/Connectivity/framework/jni/onload.cpp
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+#include <nativehelper/JNIHelp.h>
+#include <log/log.h>
+
+namespace android {
+
+int register_android_net_NetworkUtils(JNIEnv* env);
+
+extern "C" jint JNI_OnLoad(JavaVM* vm, void*) {
+    JNIEnv *env;
+    if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
+        ALOGE("GetEnv failed");
+        return JNI_ERR;
+    }
+
+    if (register_android_net_NetworkUtils(env) < 0) {
+        return JNI_ERR;
+    }
+
+    return JNI_VERSION_1_6;
+}
+
+};
\ No newline at end of file
diff --git a/packages/Connectivity/framework/src/android/net/ConnectivityManager.java b/packages/Connectivity/framework/src/android/net/ConnectivityManager.java
index 4dd0984c..0a3e231 100644
--- a/packages/Connectivity/framework/src/android/net/ConnectivityManager.java
+++ b/packages/Connectivity/framework/src/android/net/ConnectivityManager.java
@@ -16,8 +16,6 @@
 package android.net;
 
 import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
-import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_DEFAULT_MODE;
-import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE;
 import static android.net.NetworkRequest.Type.BACKGROUND_REQUEST;
 import static android.net.NetworkRequest.Type.LISTEN;
 import static android.net.NetworkRequest.Type.LISTEN_FOR_BEST;
@@ -33,7 +31,6 @@
 import android.annotation.RequiresPermission;
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
-import android.annotation.StringDef;
 import android.annotation.SuppressLint;
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
@@ -41,7 +38,6 @@
 import android.app.admin.DevicePolicyManager;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.ComponentName;
-import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.net.ConnectivityDiagnosticsManager.DataStallReport.DetectionMethod;
@@ -70,7 +66,6 @@
 import android.provider.Settings;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
-import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.Log;
 import android.util.Range;
@@ -821,38 +816,6 @@
     public static final int NETID_UNSET = 0;
 
     /**
-     * Private DNS Mode values.
-     *
-     * The "private_dns_mode" global setting stores a String value which is
-     * expected to be one of the following.
-     */
-
-    /**
-     * @hide
-     */
-    @SystemApi(client = MODULE_LIBRARIES)
-    public static final String PRIVATE_DNS_MODE_OFF = "off";
-    /**
-     * @hide
-     */
-    @SystemApi(client = MODULE_LIBRARIES)
-    public static final String PRIVATE_DNS_MODE_OPPORTUNISTIC = "opportunistic";
-    /**
-     * @hide
-     */
-    @SystemApi(client = MODULE_LIBRARIES)
-    public static final String PRIVATE_DNS_MODE_PROVIDER_HOSTNAME = "hostname";
-
-    /** @hide */
-    @Retention(RetentionPolicy.SOURCE)
-    @StringDef(value = {
-            PRIVATE_DNS_MODE_OFF,
-            PRIVATE_DNS_MODE_OPPORTUNISTIC,
-            PRIVATE_DNS_MODE_PROVIDER_HOSTNAME,
-    })
-    public @interface PrivateDnsMode {}
-
-    /**
      * Flag to indicate that an app is not subject to any restrictions that could result in its
      * network access blocked.
      *
@@ -1435,9 +1398,9 @@
             android.Manifest.permission.NETWORK_STACK,
             android.Manifest.permission.NETWORK_SETTINGS})
     @NonNull
-    public List<NetworkStateSnapshot> getAllNetworkStateSnapshot() {
+    public List<NetworkStateSnapshot> getAllNetworkStateSnapshots() {
         try {
-            return mService.getAllNetworkStateSnapshot();
+            return mService.getAllNetworkStateSnapshots();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -1561,7 +1524,7 @@
 
     /**
      * Get the {@link NetworkCapabilities} for the given {@link Network}.  This
-     * will return {@code null} if the network is unknown.
+     * will return {@code null} if the network is unknown or if the |network| argument is null.
      *
      * This will remove any location sensitive data in {@link TransportInfo} embedded in
      * {@link NetworkCapabilities#getTransportInfo()}. Some transport info instances like
@@ -4418,7 +4381,7 @@
     @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
     public void registerDefaultNetworkCallback(@NonNull NetworkCallback networkCallback,
             @NonNull Handler handler) {
-        registerDefaultNetworkCallbackAsUid(Process.INVALID_UID, networkCallback, handler);
+        registerDefaultNetworkCallbackForUid(Process.INVALID_UID, networkCallback, handler);
     }
 
     /**
@@ -4448,7 +4411,7 @@
     @RequiresPermission(anyOf = {
             NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
             android.Manifest.permission.NETWORK_SETTINGS})
-    public void registerDefaultNetworkCallbackAsUid(int uid,
+    public void registerDefaultNetworkCallbackForUid(int uid,
             @NonNull NetworkCallback networkCallback, @NonNull Handler handler) {
         CallbackHandler cbHandler = new CallbackHandler(handler);
         sendRequestForNetwork(uid, null /* need */, networkCallback, 0 /* timeoutMs */,
@@ -5448,44 +5411,4 @@
     public static Range<Integer> getIpSecNetIdRange() {
         return new Range(TUN_INTF_NETID_START, TUN_INTF_NETID_START + TUN_INTF_NETID_RANGE - 1);
     }
-
-    /**
-     * Get private DNS mode from settings.
-     *
-     * @param context The Context to query the private DNS mode from settings.
-     * @return A string of private DNS mode as one of the PRIVATE_DNS_MODE_* constants.
-     *
-     * @hide
-     */
-    @SystemApi(client = MODULE_LIBRARIES)
-    @NonNull
-    @PrivateDnsMode
-    public static String getPrivateDnsMode(@NonNull Context context) {
-        final ContentResolver cr = context.getContentResolver();
-        String mode = Settings.Global.getString(cr, PRIVATE_DNS_MODE);
-        if (TextUtils.isEmpty(mode)) mode = Settings.Global.getString(cr, PRIVATE_DNS_DEFAULT_MODE);
-        // If both PRIVATE_DNS_MODE and PRIVATE_DNS_DEFAULT_MODE are not set, choose
-        // PRIVATE_DNS_MODE_OPPORTUNISTIC as default mode.
-        if (TextUtils.isEmpty(mode)) mode = PRIVATE_DNS_MODE_OPPORTUNISTIC;
-        return mode;
-    }
-
-    /**
-     * Set private DNS mode to settings.
-     *
-     * @param context The {@link Context} to set the private DNS mode.
-     * @param mode The private dns mode. This should be one of the PRIVATE_DNS_MODE_* constants.
-     *
-     * @hide
-     */
-    @SystemApi(client = MODULE_LIBRARIES)
-    public static void setPrivateDnsMode(@NonNull Context context,
-            @NonNull @PrivateDnsMode String mode) {
-        if (!(mode == PRIVATE_DNS_MODE_OFF
-                || mode == PRIVATE_DNS_MODE_OPPORTUNISTIC
-                || mode == PRIVATE_DNS_MODE_PROVIDER_HOSTNAME)) {
-            throw new IllegalArgumentException("Invalid private dns mode");
-        }
-        Settings.Global.putString(context.getContentResolver(), PRIVATE_DNS_MODE, mode);
-    }
 }
diff --git a/packages/Connectivity/framework/src/android/net/ConnectivitySettingsManager.java b/packages/Connectivity/framework/src/android/net/ConnectivitySettingsManager.java
index 9a00055..31e1fb0 100644
--- a/packages/Connectivity/framework/src/android/net/ConnectivitySettingsManager.java
+++ b/packages/Connectivity/framework/src/android/net/ConnectivitySettingsManager.java
@@ -19,18 +19,15 @@
 import static android.net.ConnectivityManager.MULTIPATH_PREFERENCE_HANDOVER;
 import static android.net.ConnectivityManager.MULTIPATH_PREFERENCE_PERFORMANCE;
 import static android.net.ConnectivityManager.MULTIPATH_PREFERENCE_RELIABILITY;
-import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OFF;
-import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC;
-import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME;
 
 import android.annotation.IntDef;
 import android.annotation.IntRange;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
+import android.content.ContentResolver;
 import android.content.Context;
 import android.net.ConnectivityManager.MultipathPreference;
-import android.net.ConnectivityManager.PrivateDnsMode;
 import android.provider.Settings;
 import android.text.TextUtils;
 import android.util.Range;
@@ -341,6 +338,37 @@
     public static final String MOBILE_DATA_PREFERRED_APPS = "mobile_data_preferred_apps";
 
     /**
+     * One of the private DNS modes that indicates the private DNS mode is off.
+     */
+    public static final int PRIVATE_DNS_MODE_OFF = 1;
+
+    /**
+     * One of the private DNS modes that indicates the private DNS mode is automatic, which
+     * will try to use the current DNS as private DNS.
+     */
+    public static final int PRIVATE_DNS_MODE_OPPORTUNISTIC = 2;
+
+    /**
+     * One of the private DNS modes that indicates the private DNS mode is strict and the
+     * {@link #PRIVATE_DNS_SPECIFIER} is required, which will try to use the value of
+     * {@link #PRIVATE_DNS_SPECIFIER} as private DNS.
+     */
+    public static final int PRIVATE_DNS_MODE_PROVIDER_HOSTNAME = 3;
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(value = {
+            PRIVATE_DNS_MODE_OFF,
+            PRIVATE_DNS_MODE_OPPORTUNISTIC,
+            PRIVATE_DNS_MODE_PROVIDER_HOSTNAME,
+    })
+    public @interface PrivateDnsMode {}
+
+    private static final String PRIVATE_DNS_MODE_OFF_STRING = "off";
+    private static final String PRIVATE_DNS_MODE_OPPORTUNISTIC_STRING = "opportunistic";
+    private static final String PRIVATE_DNS_MODE_PROVIDER_HOSTNAME_STRING = "hostname";
+
+    /**
      * Get mobile data activity timeout from {@link Settings}.
      *
      * @param context The {@link Context} to query the setting.
@@ -689,6 +717,65 @@
                 context.getContentResolver(), GLOBAL_HTTP_PROXY_PAC, "" /* value */);
     }
 
+    private static String getPrivateDnsModeAsString(@PrivateDnsMode int mode) {
+        switch (mode) {
+            case PRIVATE_DNS_MODE_OFF:
+                return PRIVATE_DNS_MODE_OFF_STRING;
+            case PRIVATE_DNS_MODE_OPPORTUNISTIC:
+                return PRIVATE_DNS_MODE_OPPORTUNISTIC_STRING;
+            case PRIVATE_DNS_MODE_PROVIDER_HOSTNAME:
+                return PRIVATE_DNS_MODE_PROVIDER_HOSTNAME_STRING;
+            default:
+                throw new IllegalArgumentException("Invalid private dns mode: " + mode);
+        }
+    }
+
+    private static int getPrivateDnsModeAsInt(String mode) {
+        switch (mode) {
+            case "off":
+                return PRIVATE_DNS_MODE_OFF;
+            case "hostname":
+                return PRIVATE_DNS_MODE_PROVIDER_HOSTNAME;
+            case "opportunistic":
+                return PRIVATE_DNS_MODE_OPPORTUNISTIC;
+            default:
+                throw new IllegalArgumentException("Invalid private dns mode: " + mode);
+        }
+    }
+
+    /**
+     * Get private DNS mode from settings.
+     *
+     * @param context The Context to query the private DNS mode from settings.
+     * @return A string of private DNS mode.
+     */
+    @PrivateDnsMode
+    public static int getPrivateDnsMode(@NonNull Context context) {
+        final ContentResolver cr = context.getContentResolver();
+        String mode = Settings.Global.getString(cr, PRIVATE_DNS_MODE);
+        if (TextUtils.isEmpty(mode)) mode = Settings.Global.getString(cr, PRIVATE_DNS_DEFAULT_MODE);
+        // If both PRIVATE_DNS_MODE and PRIVATE_DNS_DEFAULT_MODE are not set, choose
+        // PRIVATE_DNS_MODE_OPPORTUNISTIC as default mode.
+        if (TextUtils.isEmpty(mode)) return PRIVATE_DNS_MODE_OPPORTUNISTIC;
+        return getPrivateDnsModeAsInt(mode);
+    }
+
+    /**
+     * Set private DNS mode to settings.
+     *
+     * @param context The {@link Context} to set the private DNS mode.
+     * @param mode The private dns mode. This should be one of the PRIVATE_DNS_MODE_* constants.
+     */
+    public static void setPrivateDnsMode(@NonNull Context context, @PrivateDnsMode int mode) {
+        if (!(mode == PRIVATE_DNS_MODE_OFF
+                || mode == PRIVATE_DNS_MODE_OPPORTUNISTIC
+                || mode == PRIVATE_DNS_MODE_PROVIDER_HOSTNAME)) {
+            throw new IllegalArgumentException("Invalid private dns mode: " + mode);
+        }
+        Settings.Global.putString(context.getContentResolver(), PRIVATE_DNS_MODE,
+                getPrivateDnsModeAsString(mode));
+    }
+
     /**
      * Get specific private dns provider name from {@link Settings}.
      *
@@ -731,13 +818,14 @@
      *             constants.
      */
     public static void setPrivateDnsDefaultMode(@NonNull Context context,
-            @NonNull @PrivateDnsMode String mode) {
+            @NonNull @PrivateDnsMode int mode) {
         if (!(mode == PRIVATE_DNS_MODE_OFF
                 || mode == PRIVATE_DNS_MODE_OPPORTUNISTIC
                 || mode == PRIVATE_DNS_MODE_PROVIDER_HOSTNAME)) {
             throw new IllegalArgumentException("Invalid private dns mode");
         }
-        Settings.Global.putString(context.getContentResolver(), PRIVATE_DNS_DEFAULT_MODE, mode);
+        Settings.Global.putString(context.getContentResolver(), PRIVATE_DNS_DEFAULT_MODE,
+                getPrivateDnsModeAsString(mode));
     }
 
     /**
diff --git a/packages/Connectivity/framework/src/android/net/IConnectivityManager.aidl b/packages/Connectivity/framework/src/android/net/IConnectivityManager.aidl
index 0826922..a7cb618f 100644
--- a/packages/Connectivity/framework/src/android/net/IConnectivityManager.aidl
+++ b/packages/Connectivity/framework/src/android/net/IConnectivityManager.aidl
@@ -81,7 +81,7 @@
     @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     NetworkState[] getAllNetworkState();
 
-    List<NetworkStateSnapshot> getAllNetworkStateSnapshot();
+    List<NetworkStateSnapshot> getAllNetworkStateSnapshots();
 
     boolean isActiveNetworkMetered();
 
diff --git a/packages/Connectivity/framework/src/android/net/NetworkAgent.java b/packages/Connectivity/framework/src/android/net/NetworkAgent.java
index c57da53..f65acdd 100644
--- a/packages/Connectivity/framework/src/android/net/NetworkAgent.java
+++ b/packages/Connectivity/framework/src/android/net/NetworkAgent.java
@@ -879,11 +879,11 @@
      * This method may be called at any time while the network is connected. It has no effect if
      * the network is already disconnected and the teardown delay timer is running.
      *
-     * @param teardownDelayMs the teardown delay to set, or 0 to disable teardown delay.
+     * @param teardownDelayMillis the teardown delay to set, or 0 to disable teardown delay.
      */
-    public void setTeardownDelayMs(
-            @IntRange(from = 0, to = MAX_TEARDOWN_DELAY_MS) int teardownDelayMs) {
-        queueOrSendMessage(reg -> reg.sendTeardownDelayMs(teardownDelayMs));
+    public void setTeardownDelayMillis(
+            @IntRange(from = 0, to = MAX_TEARDOWN_DELAY_MS) int teardownDelayMillis) {
+        queueOrSendMessage(reg -> reg.sendTeardownDelayMs(teardownDelayMillis));
     }
 
     /**
diff --git a/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java b/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java
index 937a9d2..4a99d29 100644
--- a/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java
+++ b/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java
@@ -183,7 +183,7 @@
             throw new UnsupportedOperationException(
                     "Cannot clear NetworkCapabilities when mRedactions is set");
         }
-        mNetworkCapabilities = mTransportTypes = mUnwantedNetworkCapabilities = 0;
+        mNetworkCapabilities = mTransportTypes = mForbiddenNetworkCapabilities = 0;
         mLinkUpBandwidthKbps = mLinkDownBandwidthKbps = LINK_BANDWIDTH_UNSPECIFIED;
         mNetworkSpecifier = null;
         mTransportInfo = null;
@@ -219,7 +219,7 @@
         mUids = (nc.mUids == null) ? null : new ArraySet<>(nc.mUids);
         setAdministratorUids(nc.getAdministratorUids());
         mOwnerUid = nc.mOwnerUid;
-        mUnwantedNetworkCapabilities = nc.mUnwantedNetworkCapabilities;
+        mForbiddenNetworkCapabilities = nc.mForbiddenNetworkCapabilities;
         mSSID = nc.mSSID;
         mPrivateDnsBroken = nc.mPrivateDnsBroken;
         mRequestorUid = nc.mRequestorUid;
@@ -237,7 +237,7 @@
     /**
      * If any capabilities specified here they must not exist in the matching Network.
      */
-    private long mUnwantedNetworkCapabilities;
+    private long mForbiddenNetworkCapabilities;
 
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
@@ -586,21 +586,21 @@
      * @hide
      */
     public @NonNull NetworkCapabilities addCapability(@NetCapability int capability) {
-        // If the given capability was previously added to the list of unwanted capabilities
-        // then the capability will also be removed from the list of unwanted capabilities.
-        // TODO: Consider adding unwanted capabilities to the public API and mention this
+        // If the given capability was previously added to the list of forbidden capabilities
+        // then the capability will also be removed from the list of forbidden capabilities.
+        // TODO: Consider adding forbidden capabilities to the public API and mention this
         // in the documentation.
         checkValidCapability(capability);
         mNetworkCapabilities |= 1L << capability;
-        // remove from unwanted capability list
-        mUnwantedNetworkCapabilities &= ~(1L << capability);
+        // remove from forbidden capability list
+        mForbiddenNetworkCapabilities &= ~(1L << capability);
         return this;
     }
 
     /**
-     * Adds the given capability to the list of unwanted capabilities of this
+     * Adds the given capability to the list of forbidden capabilities of this
      * {@code NetworkCapability} instance. Note that when searching for a network to
-     * satisfy a request, the network must not contain any capability from unwanted capability
+     * satisfy a request, the network must not contain any capability from forbidden capability
      * list.
      * <p>
      * If the capability was previously added to the list of required capabilities (for
@@ -610,9 +610,9 @@
      * @see #addCapability(int)
      * @hide
      */
-    public void addUnwantedCapability(@NetCapability int capability) {
+    public void addForbiddenCapability(@NetCapability int capability) {
         checkValidCapability(capability);
-        mUnwantedNetworkCapabilities |= 1L << capability;
+        mForbiddenNetworkCapabilities |= 1L << capability;
         mNetworkCapabilities &= ~(1L << capability);  // remove from requested capabilities
     }
 
@@ -632,16 +632,16 @@
     }
 
     /**
-     * Removes (if found) the given unwanted capability from this {@code NetworkCapability}
-     * instance that were added via addUnwantedCapability(int) or setCapabilities(int[], int[]).
+     * Removes (if found) the given forbidden capability from this {@code NetworkCapability}
+     * instance that were added via addForbiddenCapability(int) or setCapabilities(int[], int[]).
      *
      * @param capability the capability to be removed.
      * @return This NetworkCapabilities instance, to facilitate chaining.
      * @hide
      */
-    public @NonNull NetworkCapabilities removeUnwantedCapability(@NetCapability int capability) {
+    public @NonNull NetworkCapabilities removeForbiddenCapability(@NetCapability int capability) {
         checkValidCapability(capability);
-        mUnwantedNetworkCapabilities &= ~(1L << capability);
+        mForbiddenNetworkCapabilities &= ~(1L << capability);
         return this;
     }
 
@@ -670,13 +670,13 @@
     }
 
     /**
-     * Gets all the unwanted capabilities set on this {@code NetworkCapability} instance.
+     * Gets all the forbidden capabilities set on this {@code NetworkCapability} instance.
      *
-     * @return an array of unwanted capability values for this instance.
+     * @return an array of forbidden capability values for this instance.
      * @hide
      */
-    public @NetCapability int[] getUnwantedCapabilities() {
-        return NetworkCapabilitiesUtils.unpackBits(mUnwantedNetworkCapabilities);
+    public @NetCapability int[] getForbiddenCapabilities() {
+        return NetworkCapabilitiesUtils.unpackBits(mForbiddenNetworkCapabilities);
     }
 
 
@@ -687,9 +687,9 @@
      * @hide
      */
     public void setCapabilities(@NetCapability int[] capabilities,
-            @NetCapability int[] unwantedCapabilities) {
+            @NetCapability int[] forbiddenCapabilities) {
         mNetworkCapabilities = NetworkCapabilitiesUtils.packBits(capabilities);
-        mUnwantedNetworkCapabilities = NetworkCapabilitiesUtils.packBits(unwantedCapabilities);
+        mForbiddenNetworkCapabilities = NetworkCapabilitiesUtils.packBits(forbiddenCapabilities);
     }
 
     /**
@@ -714,9 +714,9 @@
 
     /** @hide */
     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
-    public boolean hasUnwantedCapability(@NetCapability int capability) {
+    public boolean hasForbiddenCapability(@NetCapability int capability) {
         return isValidCapability(capability)
-                && ((mUnwantedNetworkCapabilities & (1L << capability)) != 0);
+                && ((mForbiddenNetworkCapabilities & (1L << capability)) != 0);
     }
 
     /**
@@ -746,14 +746,14 @@
 
     private void combineNetCapabilities(@NonNull NetworkCapabilities nc) {
         final long wantedCaps = this.mNetworkCapabilities | nc.mNetworkCapabilities;
-        final long unwantedCaps =
-                this.mUnwantedNetworkCapabilities | nc.mUnwantedNetworkCapabilities;
-        if ((wantedCaps & unwantedCaps) != 0) {
+        final long forbiddenCaps =
+                this.mForbiddenNetworkCapabilities | nc.mForbiddenNetworkCapabilities;
+        if ((wantedCaps & forbiddenCaps) != 0) {
             throw new IllegalArgumentException(
-                    "Cannot have the same capability in wanted and unwanted lists.");
+                    "Cannot have the same capability in wanted and forbidden lists.");
         }
         this.mNetworkCapabilities = wantedCaps;
-        this.mUnwantedNetworkCapabilities = unwantedCaps;
+        this.mForbiddenNetworkCapabilities = forbiddenCaps;
     }
 
     /**
@@ -764,7 +764,7 @@
      * @hide
      */
     public @Nullable String describeFirstNonRequestableCapability() {
-        final long nonRequestable = (mNetworkCapabilities | mUnwantedNetworkCapabilities)
+        final long nonRequestable = (mNetworkCapabilities | mForbiddenNetworkCapabilities)
                 & NON_REQUESTABLE_CAPABILITIES;
 
         if (nonRequestable != 0) {
@@ -781,28 +781,28 @@
     private boolean satisfiedByNetCapabilities(@NonNull NetworkCapabilities nc,
             boolean onlyImmutable) {
         long requestedCapabilities = mNetworkCapabilities;
-        long requestedUnwantedCapabilities = mUnwantedNetworkCapabilities;
+        long requestedForbiddenCapabilities = mForbiddenNetworkCapabilities;
         long providedCapabilities = nc.mNetworkCapabilities;
 
         if (onlyImmutable) {
             requestedCapabilities &= ~MUTABLE_CAPABILITIES;
-            requestedUnwantedCapabilities &= ~MUTABLE_CAPABILITIES;
+            requestedForbiddenCapabilities &= ~MUTABLE_CAPABILITIES;
         }
         return ((providedCapabilities & requestedCapabilities) == requestedCapabilities)
-                && ((requestedUnwantedCapabilities & providedCapabilities) == 0);
+                && ((requestedForbiddenCapabilities & providedCapabilities) == 0);
     }
 
     /** @hide */
     public boolean equalsNetCapabilities(@NonNull NetworkCapabilities nc) {
         return (nc.mNetworkCapabilities == this.mNetworkCapabilities)
-                && (nc.mUnwantedNetworkCapabilities == this.mUnwantedNetworkCapabilities);
+                && (nc.mForbiddenNetworkCapabilities == this.mForbiddenNetworkCapabilities);
     }
 
     private boolean equalsNetCapabilitiesRequestable(@NonNull NetworkCapabilities that) {
-        return ((this.mNetworkCapabilities & ~NON_REQUESTABLE_CAPABILITIES) ==
-                (that.mNetworkCapabilities & ~NON_REQUESTABLE_CAPABILITIES))
-                && ((this.mUnwantedNetworkCapabilities & ~NON_REQUESTABLE_CAPABILITIES) ==
-                (that.mUnwantedNetworkCapabilities & ~NON_REQUESTABLE_CAPABILITIES));
+        return ((this.mNetworkCapabilities & ~NON_REQUESTABLE_CAPABILITIES)
+                == (that.mNetworkCapabilities & ~NON_REQUESTABLE_CAPABILITIES))
+                && ((this.mForbiddenNetworkCapabilities & ~NON_REQUESTABLE_CAPABILITIES)
+                == (that.mForbiddenNetworkCapabilities & ~NON_REQUESTABLE_CAPABILITIES));
     }
 
     /**
@@ -830,8 +830,17 @@
         final int[] originalAdministratorUids = getAdministratorUids();
         final TransportInfo originalTransportInfo = getTransportInfo();
         clearAll();
-        mTransportTypes = (originalTransportTypes & TEST_NETWORKS_ALLOWED_TRANSPORTS)
-                | (1 << TRANSPORT_TEST);
+        if (0 != (originalCapabilities & NET_CAPABILITY_NOT_RESTRICTED)) {
+            // If the test network is not restricted, then it is only allowed to declare some
+            // specific transports. This is to minimize impact on running apps in case an app
+            // run from the shell creates a test a network.
+            mTransportTypes =
+                    (originalTransportTypes & UNRESTRICTED_TEST_NETWORKS_ALLOWED_TRANSPORTS)
+                            | (1 << TRANSPORT_TEST);
+        } else {
+            // If the test transport is restricted, then it may declare any transport.
+            mTransportTypes = (originalTransportTypes | (1 << TRANSPORT_TEST));
+        }
         mNetworkCapabilities = originalCapabilities & TEST_NETWORKS_ALLOWED_CAPABILITIES;
         mNetworkSpecifier = originalSpecifier;
         mSignalStrength = originalSignalStrength;
@@ -935,9 +944,10 @@
     };
 
     /**
-     * Allowed transports on a test network, in addition to TRANSPORT_TEST.
+     * Allowed transports on an unrestricted test network (in addition to TRANSPORT_TEST).
      */
-    private static final int TEST_NETWORKS_ALLOWED_TRANSPORTS = 1 << TRANSPORT_TEST
+    private static final int UNRESTRICTED_TEST_NETWORKS_ALLOWED_TRANSPORTS =
+            1 << TRANSPORT_TEST
             // Test ethernet networks can be created with EthernetManager#setIncludeTestInterfaces
             | 1 << TRANSPORT_ETHERNET
             // Test VPN networks can be created but their UID ranges must be empty.
@@ -1718,7 +1728,7 @@
      * Combine a set of Capabilities to this one.  Useful for coming up with the complete set.
      * <p>
      * Note that this method may break an invariant of having a particular capability in either
-     * wanted or unwanted lists but never in both.  Requests that have the same capability in
+     * wanted or forbidden lists but never in both.  Requests that have the same capability in
      * both lists will never be satisfied.
      * @hide
      */
@@ -1859,8 +1869,8 @@
     public int hashCode() {
         return (int) (mNetworkCapabilities & 0xFFFFFFFF)
                 + ((int) (mNetworkCapabilities >> 32) * 3)
-                + ((int) (mUnwantedNetworkCapabilities & 0xFFFFFFFF) * 5)
-                + ((int) (mUnwantedNetworkCapabilities >> 32) * 7)
+                + ((int) (mForbiddenNetworkCapabilities & 0xFFFFFFFF) * 5)
+                + ((int) (mForbiddenNetworkCapabilities >> 32) * 7)
                 + ((int) (mTransportTypes & 0xFFFFFFFF) * 11)
                 + ((int) (mTransportTypes >> 32) * 13)
                 + mLinkUpBandwidthKbps * 17
@@ -1895,7 +1905,7 @@
     @Override
     public void writeToParcel(Parcel dest, int flags) {
         dest.writeLong(mNetworkCapabilities);
-        dest.writeLong(mUnwantedNetworkCapabilities);
+        dest.writeLong(mForbiddenNetworkCapabilities);
         dest.writeLong(mTransportTypes);
         dest.writeInt(mLinkUpBandwidthKbps);
         dest.writeInt(mLinkDownBandwidthKbps);
@@ -1919,7 +1929,7 @@
                 NetworkCapabilities netCap = new NetworkCapabilities();
 
                 netCap.mNetworkCapabilities = in.readLong();
-                netCap.mUnwantedNetworkCapabilities = in.readLong();
+                netCap.mForbiddenNetworkCapabilities = in.readLong();
                 netCap.mTransportTypes = in.readLong();
                 netCap.mLinkUpBandwidthKbps = in.readInt();
                 netCap.mLinkDownBandwidthKbps = in.readInt();
@@ -1973,9 +1983,9 @@
             appendStringRepresentationOfBitMaskToStringBuilder(sb, mNetworkCapabilities,
                     NetworkCapabilities::capabilityNameOf, "&");
         }
-        if (0 != mUnwantedNetworkCapabilities) {
-            sb.append(" Unwanted: ");
-            appendStringRepresentationOfBitMaskToStringBuilder(sb, mUnwantedNetworkCapabilities,
+        if (0 != mForbiddenNetworkCapabilities) {
+            sb.append(" Forbidden: ");
+            appendStringRepresentationOfBitMaskToStringBuilder(sb, mForbiddenNetworkCapabilities,
                     NetworkCapabilities::capabilityNameOf, "&");
         }
         if (mLinkUpBandwidthKbps > 0) {
@@ -2444,7 +2454,8 @@
          * For example {@code TRANSPORT_WIFI} and {@code TRANSPORT_ETHERNET} added to a
          * {@code NetworkCapabilities} would cause either a Wi-Fi network or an Ethernet network
          * to be selected. This is logically different than
-         * {@code NetworkCapabilities.NET_CAPABILITY_*}.
+         * {@code NetworkCapabilities.NET_CAPABILITY_*}. Also note that multiple networks with the
+         * same transport type may be active concurrently.
          *
          * @param transportType the transport type to be added or removed.
          * @return this builder
diff --git a/packages/Connectivity/framework/src/android/net/NetworkRequest.java b/packages/Connectivity/framework/src/android/net/NetworkRequest.java
index 8c4f419..dd88c5a 100644
--- a/packages/Connectivity/framework/src/android/net/NetworkRequest.java
+++ b/packages/Connectivity/framework/src/android/net/NetworkRequest.java
@@ -311,7 +311,7 @@
          *
          * @see #addCapability(int)
          *
-         * @param capability The capability to add to unwanted capability list.
+         * @param capability The capability to add to forbidden capability list.
          * @return The builder to facilitate chaining.
          *
          * @hide
@@ -319,15 +319,15 @@
         @NonNull
         @SuppressLint("MissingGetterMatchingBuilder")
         @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
-        public Builder addUnwantedCapability(@NetworkCapabilities.NetCapability int capability) {
-            mNetworkCapabilities.addUnwantedCapability(capability);
+        public Builder addForbiddenCapability(@NetworkCapabilities.NetCapability int capability) {
+            mNetworkCapabilities.addForbiddenCapability(capability);
             return this;
         }
 
         /**
-         * Removes (if found) the given unwanted capability from this builder instance.
+         * Removes (if found) the given forbidden capability from this builder instance.
          *
-         * @param capability The unwanted capability to remove.
+         * @param capability The forbidden capability to remove.
          * @return The builder to facilitate chaining.
          *
          * @hide
@@ -335,8 +335,9 @@
         @NonNull
         @SuppressLint("BuilderSetStyle")
         @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
-        public Builder removeUnwantedCapability(@NetworkCapabilities.NetCapability int capability) {
-            mNetworkCapabilities.removeUnwantedCapability(capability);
+        public Builder removeForbiddenCapability(
+                @NetworkCapabilities.NetCapability int capability) {
+            mNetworkCapabilities.removeForbiddenCapability(capability);
             return this;
         }
 
@@ -598,13 +599,13 @@
     }
 
     /**
-     * @see Builder#addUnwantedCapability(int)
+     * @see Builder#addForbiddenCapability(int)
      *
      * @hide
      */
     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
-    public boolean hasUnwantedCapability(@NetCapability int capability) {
-        return networkCapabilities.hasUnwantedCapability(capability);
+    public boolean hasForbiddenCapability(@NetCapability int capability) {
+        return networkCapabilities.hasForbiddenCapability(capability);
     }
 
     /**
@@ -709,18 +710,18 @@
     }
 
     /**
-     * Gets all the unwanted capabilities set on this {@code NetworkRequest} instance.
+     * Gets all the forbidden capabilities set on this {@code NetworkRequest} instance.
      *
-     * @return an array of unwanted capability values for this instance.
+     * @return an array of forbidden capability values for this instance.
      *
      * @hide
      */
     @NonNull
     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
-    public @NetCapability int[] getUnwantedCapabilities() {
-        // No need to make a defensive copy here as NC#getUnwantedCapabilities() already returns
+    public @NetCapability int[] getForbiddenCapabilities() {
+        // No need to make a defensive copy here as NC#getForbiddenCapabilities() already returns
         // a new array.
-        return networkCapabilities.getUnwantedCapabilities();
+        return networkCapabilities.getForbiddenCapabilities();
     }
 
     /**
diff --git a/packages/Connectivity/framework/src/android/net/VpnTransportInfo.java b/packages/Connectivity/framework/src/android/net/VpnTransportInfo.java
index efd3363..4071c9a 100644
--- a/packages/Connectivity/framework/src/android/net/VpnTransportInfo.java
+++ b/packages/Connectivity/framework/src/android/net/VpnTransportInfo.java
@@ -40,10 +40,10 @@
 @SystemApi(client = MODULE_LIBRARIES)
 public final class VpnTransportInfo implements TransportInfo, Parcelable {
     /** Type of this VPN. */
-    public final int type;
+    private final int mType;
 
     @Nullable
-    public final String sessionId;
+    private final String mSessionId;
 
     @Override
     public @RedactionType long getApplicableRedactions() {
@@ -55,13 +55,28 @@
      */
     @NonNull
     public VpnTransportInfo makeCopy(@RedactionType long redactions) {
-        return new VpnTransportInfo(type,
-            ((redactions & REDACT_FOR_NETWORK_SETTINGS) != 0) ? null : sessionId);
+        return new VpnTransportInfo(mType,
+            ((redactions & REDACT_FOR_NETWORK_SETTINGS) != 0) ? null : mSessionId);
     }
 
     public VpnTransportInfo(int type, @Nullable String sessionId) {
-        this.type = type;
-        this.sessionId = sessionId;
+        this.mType = type;
+        this.mSessionId = sessionId;
+    }
+
+    /**
+     * Returns the session Id of this VpnTransportInfo.
+     */
+    @Nullable
+    public String getSessionId() {
+        return mSessionId;
+    }
+
+    /**
+     * Returns the type of this VPN.
+     */
+    public int getType() {
+        return mType;
     }
 
     @Override
@@ -69,17 +84,17 @@
         if (!(o instanceof VpnTransportInfo)) return false;
 
         VpnTransportInfo that = (VpnTransportInfo) o;
-        return (this.type == that.type) && TextUtils.equals(this.sessionId, that.sessionId);
+        return (this.mType == that.mType) && TextUtils.equals(this.mSessionId, that.mSessionId);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(type, sessionId);
+        return Objects.hash(mType, mSessionId);
     }
 
     @Override
     public String toString() {
-        return String.format("VpnTransportInfo{type=%d, sessionId=%s}", type, sessionId);
+        return String.format("VpnTransportInfo{type=%d, sessionId=%s}", mType, mSessionId);
     }
 
     @Override
@@ -89,8 +104,8 @@
 
     @Override
     public void writeToParcel(@NonNull Parcel dest, int flags) {
-        dest.writeInt(type);
-        dest.writeString(sessionId);
+        dest.writeInt(mType);
+        dest.writeString(mSessionId);
     }
 
     public static final @NonNull Creator<VpnTransportInfo> CREATOR =
diff --git a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java
index 16a946d..f8cb5d3 100644
--- a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java
+++ b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java
@@ -561,7 +561,20 @@
                 break;
         }
 
-        Log.d(TAG, "status=" + statusString + ", cause=" + causeString + ", detail=" + detail);
+        StringBuilder msg = new StringBuilder();
+        msg.append("status: " + statusString + ", cause: " + causeString);
+        if (status == STATUS_IN_PROGRESS) {
+            msg.append(
+                    String.format(
+                            ", partition name: %s, progress: %d/%d",
+                            mCurrentPartitionName,
+                            mCurrentPartitionInstalledSize,
+                            mCurrentPartitionSize));
+        }
+        if (detail != null) {
+            msg.append(", detail: " + detail);
+        }
+        Log.d(TAG, msg.toString());
 
         if (notifyOnNotificationBar) {
             mNM.notify(NOTIFICATION_ID, buildNotification(status, cause, detail));
diff --git a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java
index 59ea9f0..f18d426 100644
--- a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java
+++ b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java
@@ -320,20 +320,21 @@
         }
     }
 
-    private void installScratch() throws IOException {
-        final long scratchSize = mDynSystem.suggestScratchSize();
+    private void installWritablePartition(final String partitionName, final long partitionSize)
+            throws IOException {
+        Log.d(TAG, "Creating writable partition: " + partitionName + ", size: " + partitionSize);
+
         Thread thread = new Thread() {
             @Override
             public void run() {
                 mInstallationSession =
-                        mDynSystem.createPartition("scratch", scratchSize, /* readOnly= */ false);
+                        mDynSystem.createPartition(
+                                partitionName, partitionSize, /* readOnly= */ false);
             }
         };
 
-        Log.d(TAG, "Creating partition: scratch, size = " + scratchSize);
         thread.start();
-
-        Progress progress = new Progress("scratch", scratchSize, mNumInstalledPartitions++);
+        Progress progress = new Progress(partitionName, partitionSize, mNumInstalledPartitions++);
 
         while (thread.isAlive()) {
             if (isCancelled()) {
@@ -356,53 +357,22 @@
 
         if (mInstallationSession == null) {
             throw new IOException(
-                    "Failed to start installation with requested size: " + scratchSize);
+                    "Failed to start installation with requested size: " + partitionSize);
         }
+
         // Reset installation session and verify that installation completes successfully.
         mInstallationSession = null;
         if (!mDynSystem.closePartition()) {
-            throw new IOException("Failed to complete partition installation: scratch");
+            throw new IOException("Failed to complete partition installation: " + partitionName);
         }
     }
 
+    private void installScratch() throws IOException {
+        installWritablePartition("scratch", mDynSystem.suggestScratchSize());
+    }
+
     private void installUserdata() throws IOException {
-        Thread thread = new Thread(() -> {
-            mInstallationSession = mDynSystem.createPartition("userdata", mUserdataSize, false);
-        });
-
-        Log.d(TAG, "Creating partition: userdata, size = " + mUserdataSize);
-        thread.start();
-
-        Progress progress = new Progress("userdata", mUserdataSize, mNumInstalledPartitions++);
-
-        while (thread.isAlive()) {
-            if (isCancelled()) {
-                return;
-            }
-
-            final long installedSize = mDynSystem.getInstallationProgress().bytes_processed;
-
-            if (installedSize > progress.installedSize + MIN_PROGRESS_TO_PUBLISH) {
-                progress.installedSize = installedSize;
-                publishProgress(progress);
-            }
-
-            try {
-                Thread.sleep(100);
-            } catch (InterruptedException e) {
-                // Ignore the error.
-            }
-        }
-
-        if (mInstallationSession == null) {
-            throw new IOException(
-                    "Failed to start installation with requested size: " + mUserdataSize);
-        }
-        // Reset installation session and verify that installation completes successfully.
-        mInstallationSession = null;
-        if (!mDynSystem.closePartition()) {
-            throw new IOException("Failed to complete partition installation: userdata");
-        }
+        installWritablePartition("userdata", mUserdataSize);
     }
 
     private void installImages() throws IOException, ImageValidationException {
diff --git a/packages/InputDevices/res/raw/keyboard_layout_arabic.kcm b/packages/InputDevices/res/raw/keyboard_layout_arabic.kcm
index 2a95cfe..1614188 100644
--- a/packages/InputDevices/res/raw/keyboard_layout_arabic.kcm
+++ b/packages/InputDevices/res/raw/keyboard_layout_arabic.kcm
@@ -85,14 +85,14 @@
 key 9 {
     label:                              '9'
     base:                               '\u0669'
-    shift:                              '('
+    shift:                              ')'
     capslock:                           '9'
 }
 
 key 0 {
     label:                              '0'
     base:                               '\u0660'
-    shift:                              ')'
+    shift:                              '('
     capslock:                           '0'
 }
 
@@ -171,15 +171,15 @@
 }
 
 key LEFT_BRACKET {
-    label:                              '['
+    label:                              ']'
     base, capslock:                     '\u062c'
-    shift:                              '<'
+    shift:                              '>'
 }
 
 key RIGHT_BRACKET {
-    label:                              ']'
+    label:                              '['
     base, capslock:                     '\u062f'
-    shift:                              '>'
+    shift:                              '<'
 }
 
 key BACKSLASH {
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java
index 60bcf37..18c38c5 100644
--- a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java
+++ b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java
@@ -113,7 +113,8 @@
     }
 
     public DataUsageInfo getWifiDataUsageInfo() {
-        NetworkTemplate template = NetworkTemplate.buildTemplateWifiWildcard();
+        NetworkTemplate template = NetworkTemplate.buildTemplateWifi(
+                NetworkTemplate.WIFI_NETWORKID_ALL, null);
         return getDataUsageInfo(template);
     }
 
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java
index bcabec8..2c1d3e2 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java
@@ -683,6 +683,16 @@
         assertThat(ap.getTitle()).isEqualTo(providerFriendlyName);
     }
 
+    // This method doesn't copy mIsFailover, mIsAvailable and mIsRoaming because NetworkInfo
+    // doesn't expose those three set methods. But that's fine since the tests don't use those three
+    // variables.
+    private NetworkInfo copyNetworkInfo(NetworkInfo ni) {
+        final NetworkInfo copy = new NetworkInfo(ni.getType(), ni.getSubtype(), ni.getTypeName(),
+                ni.getSubtypeName());
+        copy.setDetailedState(ni.getDetailedState(), ni.getReason(), ni.getExtraInfo());
+        return copy;
+    }
+
     @Test
     public void testUpdateNetworkInfo_returnsTrue() {
         int networkId = 123;
@@ -704,7 +714,7 @@
                 .setWifiInfo(wifiInfo)
                 .build();
 
-        NetworkInfo newInfo = new NetworkInfo(networkInfo);
+        NetworkInfo newInfo = copyNetworkInfo(networkInfo);
         newInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, "", "");
         assertThat(ap.update(config, wifiInfo, newInfo)).isTrue();
     }
@@ -730,7 +740,7 @@
                 .setWifiInfo(wifiInfo)
                 .build();
 
-        NetworkInfo newInfo = new NetworkInfo(networkInfo); // same values
+        NetworkInfo newInfo = copyNetworkInfo(networkInfo); // same values
         assertThat(ap.update(config, wifiInfo, newInfo)).isFalse();
     }
 
@@ -755,7 +765,7 @@
                 .setWifiInfo(wifiInfo)
                 .build();
 
-        NetworkInfo newInfo = new NetworkInfo(networkInfo); // same values
+        NetworkInfo newInfo = copyNetworkInfo(networkInfo); // same values
         wifiInfo.setRssi(rssi + 1);
         assertThat(ap.update(config, wifiInfo, newInfo)).isTrue();
     }
@@ -781,7 +791,7 @@
                 .setWifiInfo(wifiInfo)
                 .build();
 
-        NetworkInfo newInfo = new NetworkInfo(networkInfo); // same values
+        NetworkInfo newInfo = copyNetworkInfo(networkInfo); // same values
         wifiInfo.setRssi(WifiInfo.INVALID_RSSI);
         assertThat(ap.update(config, wifiInfo, newInfo)).isFalse();
     }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageControllerTest.java
index f7bee30..27d877d 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageControllerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageControllerTest.java
@@ -89,7 +89,8 @@
 
         mNetworkTemplate = NetworkTemplate.buildTemplateMobileAll(SUB_ID);
         mNetworkTemplate2 = NetworkTemplate.buildTemplateMobileAll(SUB_ID_2);
-        mWifiNetworkTemplate = NetworkTemplate.buildTemplateWifiWildcard();
+        mWifiNetworkTemplate = NetworkTemplate.buildTemplateWifi(
+                NetworkTemplate.WIFI_NETWORKID_ALL, null);
     }
 
     @Test
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
index 44864a6..9cd7083 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
@@ -24,6 +24,7 @@
 import android.content.ContentResolver;
 import android.content.ContentValues;
 import android.content.Context;
+import android.content.pm.PackageManager;
 import android.database.Cursor;
 import android.net.NetworkPolicy;
 import android.net.NetworkPolicyManager;
@@ -42,6 +43,7 @@
 import android.provider.settings.validators.SecureSettingsValidators;
 import android.provider.settings.validators.SystemSettingsValidators;
 import android.provider.settings.validators.Validator;
+import android.telephony.SubscriptionManager;
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.BackupUtils;
@@ -95,10 +97,11 @@
     private static final String KEY_NETWORK_POLICIES = "network_policies";
     private static final String KEY_WIFI_NEW_CONFIG = "wifi_new_config";
     private static final String KEY_DEVICE_SPECIFIC_CONFIG = "device_specific_config";
+    private static final String KEY_SIM_SPECIFIC_SETTINGS = "sim_specific_settings";
 
     // Versioning of the state file.  Increment this version
     // number any time the set of state items is altered.
-    private static final int STATE_VERSION = 8;
+    private static final int STATE_VERSION = 9;
 
     // Versioning of the Network Policies backup payload.
     private static final int NETWORK_POLICIES_BACKUP_VERSION = 1;
@@ -106,19 +109,20 @@
 
     // Slots in the checksum array.  Never insert new items in the middle
     // of this array; new slots must be appended.
-    private static final int STATE_SYSTEM           = 0;
-    private static final int STATE_SECURE           = 1;
-    private static final int STATE_LOCALE           = 2;
-    private static final int STATE_WIFI_SUPPLICANT  = 3;
-    private static final int STATE_WIFI_CONFIG      = 4;
-    private static final int STATE_GLOBAL           = 5;
-    private static final int STATE_LOCK_SETTINGS    = 6;
-    private static final int STATE_SOFTAP_CONFIG    = 7;
-    private static final int STATE_NETWORK_POLICIES = 8;
-    private static final int STATE_WIFI_NEW_CONFIG  = 9;
-    private static final int STATE_DEVICE_CONFIG    = 10;
+    private static final int STATE_SYSTEM                = 0;
+    private static final int STATE_SECURE                = 1;
+    private static final int STATE_LOCALE                = 2;
+    private static final int STATE_WIFI_SUPPLICANT       = 3;
+    private static final int STATE_WIFI_CONFIG           = 4;
+    private static final int STATE_GLOBAL                = 5;
+    private static final int STATE_LOCK_SETTINGS         = 6;
+    private static final int STATE_SOFTAP_CONFIG         = 7;
+    private static final int STATE_NETWORK_POLICIES      = 8;
+    private static final int STATE_WIFI_NEW_CONFIG       = 9;
+    private static final int STATE_DEVICE_CONFIG         = 10;
+    private static final int STATE_SIM_SPECIFIC_SETTINGS = 11;
 
-    private static final int STATE_SIZE             = 11; // The current number of state items
+    private static final int STATE_SIZE                  = 12; // The current number of state items
 
     // Number of entries in the checksum array at various version numbers
     private static final int STATE_SIZES[] = {
@@ -130,7 +134,8 @@
             8,              // version 5 added STATE_SOFTAP_CONFIG
             9,              // version 6 added STATE_NETWORK_POLICIES
             10,             // version 7 added STATE_WIFI_NEW_CONFIG
-            STATE_SIZE      // version 8 added STATE_DEVICE_CONFIG
+            11,             // version 8 added STATE_DEVICE_CONFIG
+            STATE_SIZE      // version 9 added STATE_SIM_SPECIFIC_SETTINGS
     };
 
     private static final int FULL_BACKUP_ADDED_GLOBAL = 2;  // added the "global" entry
@@ -208,7 +213,6 @@
     @Override
     public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
             ParcelFileDescriptor newState) throws IOException {
-
         byte[] systemSettingsData = getSystemSettings();
         byte[] secureSettingsData = getSecureSettings();
         byte[] globalSettingsData = getGlobalSettings();
@@ -218,6 +222,7 @@
         byte[] netPoliciesData = getNetworkPolicies();
         byte[] wifiFullConfigData = getNewWifiConfigData();
         byte[] deviceSpecificInformation = getDeviceSpecificConfiguration();
+        byte[] simSpecificSettingsData = getSimSpecificSettingsData();
 
         long[] stateChecksums = readOldChecksums(oldState);
 
@@ -246,6 +251,9 @@
         stateChecksums[STATE_DEVICE_CONFIG] =
                 writeIfChanged(stateChecksums[STATE_DEVICE_CONFIG], KEY_DEVICE_SPECIFIC_CONFIG,
                         deviceSpecificInformation, data);
+        stateChecksums[STATE_SIM_SPECIFIC_SETTINGS] =
+                writeIfChanged(stateChecksums[STATE_SIM_SPECIFIC_SETTINGS],
+                        KEY_SIM_SPECIFIC_SETTINGS, simSpecificSettingsData, data);
 
         writeNewChecksums(stateChecksums, newState);
     }
@@ -386,6 +394,12 @@
                             preservedSettings);
                     break;
 
+                case KEY_SIM_SPECIFIC_SETTINGS:
+                    byte[] restoredSimSpecificSettings = new byte[size];
+                    data.readEntityData(restoredSimSpecificSettings, 0, size);
+                    restoreSimSpecificSettings(restoredSimSpecificSettings);
+                    break;
+
                 default :
                     data.skipEntityData();
 
@@ -1189,6 +1203,28 @@
         return true;
     }
 
+    private byte[] getSimSpecificSettingsData() {
+        byte[] simSpecificData = new byte[0];
+        PackageManager packageManager = getBaseContext().getPackageManager();
+        if (packageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+            SubscriptionManager subManager = SubscriptionManager.from(getBaseContext());
+            simSpecificData = subManager.getAllSimSpecificSettingsForBackup();
+            Log.i(TAG, "sim specific data of length + " + simSpecificData.length
+                + " successfully retrieved");
+        }
+
+        return simSpecificData;
+    }
+
+    private void restoreSimSpecificSettings(byte[] data) {
+        PackageManager packageManager = getBaseContext().getPackageManager();
+        boolean hasTelephony = packageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
+        if (hasTelephony) {
+            SubscriptionManager subManager = SubscriptionManager.from(getBaseContext());
+            subManager.restoreAllSimSpecificSettingsFromBackup(data);
+        }
+    }
+
     private void updateWindowManagerIfNeeded(Integer previousDensity) {
         int newDensity;
         try {
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 4a64d6b..27df92f 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -155,6 +155,7 @@
     <uses-permission android:name="android.permission.INSTALL_PACKAGES" />
     <!--  TODO(b/152310230): remove once APIs are confirmed to be sufficient -->
     <uses-permission android:name="com.android.permission.USE_INSTALLER_V2" />
+    <uses-permission android:name="android.permission.INSTALL_TEST_ONLY_PACKAGE" />
     <uses-permission android:name="android.permission.MOVE_PACKAGE" />
     <uses-permission android:name="android.permission.KEEP_UNINSTALLED_PACKAGES" />
     <uses-permission android:name="android.permission.CLEAR_APP_USER_DATA" />
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/OWNERS b/packages/SystemUI/src/com/android/systemui/biometrics/OWNERS
index 8765c9a..947466f 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/OWNERS
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/OWNERS
@@ -1,7 +1,3 @@
 set noparent
 
-kchyn@google.com
-jaggies@google.com
-curtislb@google.com
-ilyamaty@google.com
-joshmccloskey@google.com
+include /services/core/java/com/android/server/biometrics/OWNERS
diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java b/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java
index 583953c..5043724 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java
@@ -80,6 +80,7 @@
     private int mImeHeight;
     private boolean mIsShelfShowing;
     private int mShelfHeight;
+    private boolean mDefaultLandscape;
 
     private final DisplayController.OnDisplaysChangedListener mDisplaysChangedListener =
             new DisplayController.OnDisplaysChangedListener() {
@@ -87,6 +88,7 @@
         public void onDisplayAdded(int displayId) {
             if (displayId == mContext.getDisplayId()) {
                 mDisplayLayout.set(mDisplayController.getDisplayLayout(displayId));
+                mDefaultLandscape = (mDisplayInfo.logicalWidth > mDisplayInfo.logicalHeight);
             }
         }
     };
@@ -362,9 +364,17 @@
     private void updateDisplayInfoIfNeeded() {
         final boolean updateNeeded;
         if ((mDisplayInfo.rotation == ROTATION_0) || (mDisplayInfo.rotation == ROTATION_180)) {
-            updateNeeded = (mDisplayInfo.logicalWidth > mDisplayInfo.logicalHeight);
+            if (!mDefaultLandscape) {
+                updateNeeded = (mDisplayInfo.logicalWidth > mDisplayInfo.logicalHeight);
+            } else {
+                updateNeeded = (mDisplayInfo.logicalWidth < mDisplayInfo.logicalHeight);
+            }
         } else {
-            updateNeeded = (mDisplayInfo.logicalWidth < mDisplayInfo.logicalHeight);
+            if (!mDefaultLandscape) {
+                updateNeeded = (mDisplayInfo.logicalWidth < mDisplayInfo.logicalHeight);
+            } else {
+                updateNeeded = (mDisplayInfo.logicalWidth > mDisplayInfo.logicalHeight);
+            }
         }
         if (updateNeeded) {
             final int newLogicalHeight = mDisplayInfo.logicalWidth;
diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java
index 54df53d..29d77a7 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java
@@ -45,6 +45,7 @@
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.RemoteException;
+import android.util.EventLog;
 import android.util.Log;
 import android.util.Size;
 import android.view.SurfaceControl;
@@ -223,6 +224,7 @@
     private PipSurfaceTransactionHelper.SurfaceControlTransactionFactory
             mSurfaceControlTransactionFactory;
     private PictureInPictureParams mPictureInPictureParams;
+    private int mOverridableMinSize;
 
     /**
      * If set to {@code true}, the entering animation will be skipped and we will wait for
@@ -244,6 +246,8 @@
         mPipBoundsHandler = boundsHandler;
         mEnterExitAnimationDuration = context.getResources()
                 .getInteger(R.integer.config_pipResizeAnimationDuration);
+        mOverridableMinSize = context.getResources().getDimensionPixelSize(
+                com.android.internal.R.dimen.overridable_minimal_size_pip_resizable_task);
         mSurfaceTransactionHelper = surfaceTransactionHelper;
         mPipAnimationController = pipAnimationController;
         mPipUiEventLoggerLogger = pipUiEventLogger;
@@ -949,7 +953,14 @@
         // -1 will be populated if an activity specifies defaultWidth/defaultHeight in <layout>
         // without minWidth/minHeight
         if (windowLayout.minWidth > 0 && windowLayout.minHeight > 0) {
-            return new Size(windowLayout.minWidth, windowLayout.minHeight);
+            // If either dimension is smaller than the allowed minimum, adjust them
+            // according to mOverridableMinSize and log to SafeNet
+            if (windowLayout.minWidth < mOverridableMinSize
+                    || windowLayout.minHeight < mOverridableMinSize) {
+                EventLog.writeEvent(0x534e4554, "174302616", -1, "");
+            }
+            return new Size(Math.max(windowLayout.minWidth, mOverridableMinSize),
+                    Math.max(windowLayout.minHeight, mOverridableMinSize));
         }
         return null;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotNotificationsController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotNotificationsController.java
index 42dde40..b8a468e 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotNotificationsController.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotNotificationsController.java
@@ -252,7 +252,7 @@
                 dpm.createAdminSupportIntent(DevicePolicyManager.POLICY_DISABLE_SCREEN_CAPTURE);
         if (intent != null) {
             final PendingIntent pendingIntent = PendingIntent.getActivityAsUser(
-                    mContext, 0, intent, 0, null, UserHandle.CURRENT);
+                    mContext, 0, intent, PendingIntent.FLAG_IMMUTABLE, null, UserHandle.CURRENT);
             b.setContentIntent(pendingIntent);
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
index 60ee75b..f6f8d6c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
@@ -193,7 +193,8 @@
         if (enabled) {
             mWaitingForTerminalState = true;
             if (DEBUG) Log.d(TAG, "Starting tethering");
-            mTetheringManager.startTethering(new TetheringRequest.Builder(TETHERING_WIFI).build(),
+            mTetheringManager.startTethering(new TetheringRequest.Builder(
+                    TETHERING_WIFI).setShouldShowEntitlementUi(false).build(),
                     ConcurrentUtils.DIRECT_EXECUTOR,
                     new TetheringManager.StartTetheringCallback() {
                         @Override
diff --git a/services/Android.bp b/services/Android.bp
index 0a01c95..1f4258d 100644
--- a/services/Android.bp
+++ b/services/Android.bp
@@ -146,79 +146,23 @@
         " --hide-package com.google.android.startop.iorap" +
         " --hide DeprecationMismatch" +
         " --hide HiddenTypedefConstant",
-    visibility: ["//visibility:private"],
+    visibility: ["//frameworks/base:__subpackages__"],
     filter_packages: ["com.android."],
 }
 
 droidstubs {
-    name: "services-stubs.sources",
-    srcs: [":services-all-sources"],
+    name: "services-non-updatable-stubs",
+    srcs: [":services-non-updatable-sources"],
     defaults: ["services-stubs-default"],
     check_api: {
         current: {
             api_file: "api/current.txt",
             removed_api_file: "api/removed.txt",
         },
-        last_released: {
-            api_file: ":android.api.system-server.latest",
-            removed_api_file: ":removed.api.system-server.latest",
-            baseline_file: ":android-incompatibilities.api.system-server.latest",
-        },
-        api_lint: {
-            enabled: true,
-            new_since: ":android.api.system-server.latest",
-            baseline_file: "api/lint-baseline.txt",
-        },
-    },
-    dists: [
-        {
-            targets: [
-                "sdk",
-                "win_sdk",
-            ],
-            dir: "apistubs/android/system-server/api",
-            dest: "android.txt",
-            tag: ".api.txt",
-        },
-        {
-            targets: [
-                "sdk",
-                "win_sdk",
-            ],
-            dir: "apistubs/android/system-server/api",
-            dest: "removed.txt",
-            tag: ".removed-api.txt",
-        },
-    ],
-}
-
-java_library {
-    name: "android_system_server_stubs_current",
-    defaults: ["android_stubs_dists_default"],
-    srcs: [":services-stubs.sources"],
-    installable: false,
-    static_libs: ["android_module_lib_stubs_current"],
-    sdk_version: "none",
-    system_modules: "none",
-    java_version: "1.8",
-    dist: {
-        dir: "apistubs/android/system-server",
-    },
-}
-
-droidstubs {
-    name: "services-non-updatable-stubs.sources",
-    srcs: [":services-non-updatable-sources"],
-    defaults: ["services-stubs-default"],
-    check_api: {
-        current: {
-            api_file: "api/non-updatable-current.txt",
-            removed_api_file: "api/non-updatable-removed.txt",
-        },
         api_lint: {
             enabled: true,
             new_since: ":android-non-updatable.api.system-server.latest",
-            baseline_file: "api/non-updatable-lint-baseline.txt",
+            baseline_file: "api/lint-baseline.txt",
         },
     },
     dists: [
diff --git a/services/api/Android.bp b/services/api/Android.bp
index bbc8c72..ee7d49f 100644
--- a/services/api/Android.bp
+++ b/services/api/Android.bp
@@ -24,12 +24,12 @@
 
 filegroup {
     name: "non-updatable-system-server-current.txt",
-    srcs: ["non-updatable-current.txt"],
+    srcs: ["current.txt"],
     visibility: ["//frameworks/base/api"],
 }
 
 filegroup {
     name: "non-updatable-system-server-removed.txt",
-    srcs: ["non-updatable-removed.txt"],
+    srcs: ["removed.txt"],
     visibility: ["//frameworks/base/api"],
 }
diff --git a/services/api/current.txt b/services/api/current.txt
index 7c5c01e..6419b70 100644
--- a/services/api/current.txt
+++ b/services/api/current.txt
@@ -1,49 +1,4 @@
 // Signature format: 2.0
-package com.android.permission.persistence {
-
-  public interface RuntimePermissionsPersistence {
-    method @NonNull public static com.android.permission.persistence.RuntimePermissionsPersistence createInstance();
-    method public void deleteForUser(@NonNull android.os.UserHandle);
-    method @Nullable public com.android.permission.persistence.RuntimePermissionsState readForUser(@NonNull android.os.UserHandle);
-    method public void writeForUser(@NonNull com.android.permission.persistence.RuntimePermissionsState, @NonNull android.os.UserHandle);
-  }
-
-  public final class RuntimePermissionsState {
-    ctor public RuntimePermissionsState(int, @Nullable String, @NonNull java.util.Map<java.lang.String,java.util.List<com.android.permission.persistence.RuntimePermissionsState.PermissionState>>, @NonNull java.util.Map<java.lang.String,java.util.List<com.android.permission.persistence.RuntimePermissionsState.PermissionState>>);
-    method @Nullable public String getFingerprint();
-    method @NonNull public java.util.Map<java.lang.String,java.util.List<com.android.permission.persistence.RuntimePermissionsState.PermissionState>> getPackagePermissions();
-    method @NonNull public java.util.Map<java.lang.String,java.util.List<com.android.permission.persistence.RuntimePermissionsState.PermissionState>> getSharedUserPermissions();
-    method public int getVersion();
-    field public static final int NO_VERSION = -1; // 0xffffffff
-  }
-
-  public static final class RuntimePermissionsState.PermissionState {
-    ctor public RuntimePermissionsState.PermissionState(@NonNull String, boolean, int);
-    method public int getFlags();
-    method @NonNull public String getName();
-    method public boolean isGranted();
-  }
-
-}
-
-package com.android.role.persistence {
-
-  public interface RolesPersistence {
-    method @NonNull public static com.android.role.persistence.RolesPersistence createInstance();
-    method public void deleteForUser(@NonNull android.os.UserHandle);
-    method @Nullable public com.android.role.persistence.RolesState readForUser(@NonNull android.os.UserHandle);
-    method public void writeForUser(@NonNull com.android.role.persistence.RolesState, @NonNull android.os.UserHandle);
-  }
-
-  public final class RolesState {
-    ctor public RolesState(int, @Nullable String, @NonNull java.util.Map<java.lang.String,java.util.Set<java.lang.String>>);
-    method @Nullable public String getPackagesHash();
-    method @NonNull public java.util.Map<java.lang.String,java.util.Set<java.lang.String>> getRoles();
-    method public int getVersion();
-  }
-
-}
-
 package com.android.server {
 
   public final class LocalManagerRegistry {
diff --git a/services/api/lint-baseline.txt b/services/api/lint-baseline.txt
index e985ddb..b46d21e 100644
--- a/services/api/lint-baseline.txt
+++ b/services/api/lint-baseline.txt
@@ -1,4 +1,8 @@
 // Baseline format: 1.0
+NotCloseable: com.android.server.wifi.SupplicantManager:
+    Classes that release resources (stop()) should implement AutoClosable and CloseGuard: class com.android.server.wifi.SupplicantManager
+
+
 ProtectedMember: com.android.server.SystemService#publishBinderService(String, android.os.IBinder):
     Protected methods not allowed; must be public: method com.android.server.SystemService.publishBinderService(String,android.os.IBinder)}
 ProtectedMember: com.android.server.SystemService#publishBinderService(String, android.os.IBinder, boolean):
diff --git a/services/api/non-updatable-current.txt b/services/api/non-updatable-current.txt
deleted file mode 100644
index 6419b70..0000000
--- a/services/api/non-updatable-current.txt
+++ /dev/null
@@ -1,54 +0,0 @@
-// Signature format: 2.0
-package com.android.server {
-
-  public final class LocalManagerRegistry {
-    method public static <T> void addManager(@NonNull Class<T>, @NonNull T);
-    method @Nullable public static <T> T getManager(@NonNull Class<T>);
-  }
-
-  public abstract class SystemService {
-    ctor public SystemService(@NonNull android.content.Context);
-    method @NonNull public final android.content.Context getContext();
-    method public boolean isUserSupported(@NonNull com.android.server.SystemService.TargetUser);
-    method public void onBootPhase(int);
-    method public abstract void onStart();
-    method public void onUserStarting(@NonNull com.android.server.SystemService.TargetUser);
-    method public void onUserStopped(@NonNull com.android.server.SystemService.TargetUser);
-    method public void onUserStopping(@NonNull com.android.server.SystemService.TargetUser);
-    method public void onUserSwitching(@Nullable com.android.server.SystemService.TargetUser, @NonNull com.android.server.SystemService.TargetUser);
-    method public void onUserUnlocked(@NonNull com.android.server.SystemService.TargetUser);
-    method public void onUserUnlocking(@NonNull com.android.server.SystemService.TargetUser);
-    method protected final void publishBinderService(@NonNull String, @NonNull android.os.IBinder);
-    method protected final void publishBinderService(@NonNull String, @NonNull android.os.IBinder, boolean);
-    field public static final int PHASE_ACTIVITY_MANAGER_READY = 550; // 0x226
-    field public static final int PHASE_BOOT_COMPLETED = 1000; // 0x3e8
-    field public static final int PHASE_DEVICE_SPECIFIC_SERVICES_READY = 520; // 0x208
-    field public static final int PHASE_LOCK_SETTINGS_READY = 480; // 0x1e0
-    field public static final int PHASE_SYSTEM_SERVICES_READY = 500; // 0x1f4
-    field public static final int PHASE_THIRD_PARTY_APPS_CAN_START = 600; // 0x258
-    field public static final int PHASE_WAIT_FOR_DEFAULT_DISPLAY = 100; // 0x64
-  }
-
-  public static final class SystemService.TargetUser {
-    method @NonNull public android.os.UserHandle getUserHandle();
-  }
-
-}
-
-package com.android.server.stats {
-
-  public final class StatsHelper {
-    method public static void sendStatsdReadyBroadcast(@NonNull android.content.Context);
-  }
-
-}
-
-package com.android.server.wifi {
-
-  public class SupplicantManager {
-    method public static void start();
-    method public static void stop();
-  }
-
-}
-
diff --git a/services/api/non-updatable-lint-baseline.txt b/services/api/non-updatable-lint-baseline.txt
deleted file mode 100644
index b46d21e..0000000
--- a/services/api/non-updatable-lint-baseline.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-// Baseline format: 1.0
-NotCloseable: com.android.server.wifi.SupplicantManager:
-    Classes that release resources (stop()) should implement AutoClosable and CloseGuard: class com.android.server.wifi.SupplicantManager
-
-
-ProtectedMember: com.android.server.SystemService#publishBinderService(String, android.os.IBinder):
-    Protected methods not allowed; must be public: method com.android.server.SystemService.publishBinderService(String,android.os.IBinder)}
-ProtectedMember: com.android.server.SystemService#publishBinderService(String, android.os.IBinder, boolean):
-    Protected methods not allowed; must be public: method com.android.server.SystemService.publishBinderService(String,android.os.IBinder,boolean)}
diff --git a/services/api/non-updatable-removed.txt b/services/api/non-updatable-removed.txt
deleted file mode 100644
index d802177..0000000
--- a/services/api/non-updatable-removed.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/services/core/java/com/android/server/BinderCallsStatsService.java b/services/core/java/com/android/server/BinderCallsStatsService.java
index c771eb7..f4a8f37 100644
--- a/services/core/java/com/android/server/BinderCallsStatsService.java
+++ b/services/core/java/com/android/server/BinderCallsStatsService.java
@@ -40,6 +40,7 @@
 import com.android.internal.os.BackgroundThread;
 import com.android.internal.os.BinderCallsStats;
 import com.android.internal.os.BinderInternal;
+import com.android.internal.os.BinderLatencyObserver;
 import com.android.internal.os.CachedDeviceState;
 import com.android.internal.util.DumpUtils;
 
@@ -120,6 +121,7 @@
 
     /** Listens for flag changes. */
     private static class SettingsObserver extends ContentObserver {
+        // Settings for BinderCallsStats.
         private static final String SETTINGS_ENABLED_KEY = "enabled";
         private static final String SETTINGS_DETAILED_TRACKING_KEY = "detailed_tracking";
         private static final String SETTINGS_UPLOAD_DATA_KEY = "upload_data";
@@ -127,6 +129,16 @@
         private static final String SETTINGS_TRACK_SCREEN_INTERACTIVE_KEY = "track_screen_state";
         private static final String SETTINGS_TRACK_DIRECT_CALLING_UID_KEY = "track_calling_uid";
         private static final String SETTINGS_MAX_CALL_STATS_KEY = "max_call_stats_count";
+        // Settings for BinderLatencyObserver.
+        private static final String SETTINGS_COLLECT_LATENCY_DATA_KEY = "collect_Latency_data";
+        private static final String SETTINGS_LATENCY_OBSERVER_SAMPLING_INTERVAL_KEY =
+                "latency_observer_sampling_interval";
+        private static final String SETTINGS_LATENCY_HISTOGRAM_BUCKET_COUNT_KEY =
+                "latency_histogram_bucket_count";
+        private static final String SETTINGS_LATENCY_HISTOGRAM_FIRST_BUCKET_SIZE_KEY =
+                "latency_histogram_first_bucket_size";
+        private static final String SETTINGS_LATENCY_HISTOGRAM_BUCKET_SCALE_FACTOR_KEY =
+                "latency_histogram_bucket_scale_factor";
 
         private boolean mEnabled;
         private final Uri mUri = Settings.Global.getUriFor(Settings.Global.BINDER_CALLS_STATS);
@@ -180,6 +192,24 @@
             mBinderCallsStats.setTrackDirectCallerUid(
                     mParser.getBoolean(SETTINGS_TRACK_DIRECT_CALLING_UID_KEY,
                     BinderCallsStats.DEFAULT_TRACK_DIRECT_CALLING_UID));
+            mBinderCallsStats.setCollectLatencyData(
+                    mParser.getBoolean(SETTINGS_COLLECT_LATENCY_DATA_KEY,
+                    BinderCallsStats.DEFAULT_COLLECT_LATENCY_DATA));
+            // Binder latency observer settings.
+            BinderLatencyObserver binderLatencyObserver = mBinderCallsStats.getLatencyObserver();
+            binderLatencyObserver.setSamplingInterval(mParser.getInt(
+                    SETTINGS_LATENCY_OBSERVER_SAMPLING_INTERVAL_KEY,
+                    BinderLatencyObserver.PERIODIC_SAMPLING_INTERVAL_DEFAULT));
+            binderLatencyObserver.setHistogramBucketsParams(
+                    mParser.getInt(
+                        SETTINGS_LATENCY_HISTOGRAM_BUCKET_COUNT_KEY,
+                        BinderLatencyObserver.BUCKET_COUNT_DEFAULT),
+                    mParser.getInt(
+                        SETTINGS_LATENCY_HISTOGRAM_FIRST_BUCKET_SIZE_KEY,
+                        BinderLatencyObserver.FIRST_BUCKET_SIZE_DEFAULT),
+                    mParser.getFloat(
+                        SETTINGS_LATENCY_HISTOGRAM_BUCKET_SCALE_FACTOR_KEY,
+                        BinderLatencyObserver.BUCKET_SCALE_FACTOR_DEFAULT));
 
 
             final boolean enabled =
@@ -198,6 +228,7 @@
                 mEnabled = enabled;
                 mBinderCallsStats.reset();
                 mBinderCallsStats.setAddDebugEntries(enabled);
+                mBinderCallsStats.getLatencyObserver().reset();
             }
         }
     }
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 2fcb95c..75fbb9f 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -34,7 +34,6 @@
 import static android.net.ConnectivityManager.BLOCKED_REASON_LOCKDOWN_VPN;
 import static android.net.ConnectivityManager.BLOCKED_REASON_NONE;
 import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
-import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC;
 import static android.net.ConnectivityManager.TYPE_BLUETOOTH;
 import static android.net.ConnectivityManager.TYPE_ETHERNET;
 import static android.net.ConnectivityManager.TYPE_MOBILE;
@@ -54,6 +53,7 @@
 import static android.net.ConnectivityManager.TYPE_WIFI_P2P;
 import static android.net.ConnectivityManager.getNetworkTypeName;
 import static android.net.ConnectivityManager.isNetworkTypeValid;
+import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_OPPORTUNISTIC;
 import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_PRIVDNS;
 import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_PARTIAL;
 import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_VALID;
@@ -2178,14 +2178,14 @@
         PermissionUtils.enforceNetworkStackPermission(mContext);
 
         final ArrayList<NetworkState> result = new ArrayList<>();
-        for (NetworkStateSnapshot snapshot : getAllNetworkStateSnapshot()) {
+        for (NetworkStateSnapshot snapshot : getAllNetworkStateSnapshots()) {
             // NetworkStateSnapshot doesn't contain NetworkInfo, so need to fetch it from the
             // NetworkAgentInfo.
-            final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(snapshot.network);
+            final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(snapshot.getNetwork());
             if (nai != null && nai.networkInfo.isConnected()) {
                 result.add(new NetworkState(new NetworkInfo(nai.networkInfo),
-                        snapshot.linkProperties, snapshot.networkCapabilities, snapshot.network,
-                        snapshot.subscriberId));
+                        snapshot.getLinkProperties(), snapshot.getNetworkCapabilities(),
+                        snapshot.getNetwork(), snapshot.getSubscriberId()));
             }
         }
         return result.toArray(new NetworkState[result.size()]);
@@ -2193,7 +2193,7 @@
 
     @Override
     @NonNull
-    public List<NetworkStateSnapshot> getAllNetworkStateSnapshot() {
+    public List<NetworkStateSnapshot> getAllNetworkStateSnapshots() {
         // This contains IMSI details, so make sure the caller is privileged.
         PermissionUtils.enforceNetworkStackPermission(mContext);
 
@@ -4778,6 +4778,7 @@
                             (Pair<ProfileNetworkPreferences.Preference, IOnCompleteListener>)
                                     msg.obj;
                     handleSetProfileNetworkPreference(arg.first, arg.second);
+                    break;
                 }
                 case EVENT_REPORT_NETWORK_ACTIVITY:
                     mNetworkActivityTracker.handleReportNetworkActivity();
@@ -8580,8 +8581,7 @@
 
         // restore private DNS settings to default mode (opportunistic)
         if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_PRIVATE_DNS)) {
-            Settings.Global.putString(mContext.getContentResolver(),
-                    ConnectivitySettingsManager.PRIVATE_DNS_MODE, PRIVATE_DNS_MODE_OPPORTUNISTIC);
+            ConnectivitySettingsManager.setPrivateDnsMode(mContext, PRIVATE_DNS_MODE_OPPORTUNISTIC);
         }
 
         Settings.Global.putString(mContext.getContentResolver(),
@@ -8673,7 +8673,7 @@
         if (vpn == null) return VpnManager.TYPE_VPN_NONE;
         final TransportInfo ti = vpn.networkCapabilities.getTransportInfo();
         if (!(ti instanceof VpnTransportInfo)) return VpnManager.TYPE_VPN_NONE;
-        return ((VpnTransportInfo) ti).type;
+        return ((VpnTransportInfo) ti).getType();
     }
 
     /**
@@ -9602,7 +9602,8 @@
             // request.
             final ArrayList<NetworkRequest> nrs = new ArrayList<>();
             nrs.add(createNetworkRequest(NetworkRequest.Type.REQUEST, pref.capabilities));
-            nrs.add(createDefaultRequest());
+            nrs.add(createDefaultInternetRequestForTransport(
+                    TYPE_NONE, NetworkRequest.Type.TRACK_DEFAULT));
             setNetworkRequestUids(nrs, UidRange.fromIntRanges(pref.capabilities.getUids()));
             final NetworkRequestInfo nri = new NetworkRequestInfo(Process.myUid(), nrs);
             result.add(nri);
@@ -9907,7 +9908,8 @@
                 case OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID:
                     requests.add(createUnmeteredNetworkRequest());
                     requests.add(createOemPaidNetworkRequest());
-                    requests.add(createDefaultRequest());
+                    requests.add(createDefaultInternetRequestForTransport(
+                            TYPE_NONE, NetworkRequest.Type.TRACK_DEFAULT));
                     break;
                 case OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK:
                     requests.add(createUnmeteredNetworkRequest());
diff --git a/services/core/java/com/android/server/IpSecService.java b/services/core/java/com/android/server/IpSecService.java
index 794cb93..d6ee951 100644
--- a/services/core/java/com/android/server/IpSecService.java
+++ b/services/core/java/com/android/server/IpSecService.java
@@ -49,6 +49,7 @@
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.ParcelFileDescriptor;
+import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceSpecificException;
 import android.system.ErrnoException;
@@ -65,6 +66,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.Preconditions;
 import com.android.net.module.util.NetdUtils;
+import com.android.net.module.util.PermissionUtils;
 
 import libcore.io.IoUtils;
 
@@ -466,8 +468,7 @@
 
         /** Safety method; guards against access of other user's UserRecords */
         private void checkCallerUid(int uid) {
-            if (uid != Binder.getCallingUid()
-                    && android.os.Process.SYSTEM_UID != Binder.getCallingUid()) {
+            if (uid != Binder.getCallingUid() && Process.SYSTEM_UID != Binder.getCallingUid()) {
                 throw new SecurityException("Attempted access of unowned resources");
             }
         }
@@ -1105,11 +1106,15 @@
      * Checks the user-provided direction field and throws an IllegalArgumentException if it is not
      * DIRECTION_IN or DIRECTION_OUT
      */
-    private static void checkDirection(int direction) {
+    private void checkDirection(int direction) {
         switch (direction) {
             case IpSecManager.DIRECTION_OUT:
             case IpSecManager.DIRECTION_IN:
                 return;
+            case IpSecManager.DIRECTION_FWD:
+                // Only NETWORK_STACK or MAINLINE_NETWORK_STACK allowed to use forward policies
+                PermissionUtils.enforceNetworkStackPermission(mContext);
+                return;
         }
         throw new IllegalArgumentException("Invalid Direction: " + direction);
     }
@@ -1353,6 +1358,26 @@
                         ikey,
                         0xffffffff,
                         resourceId);
+
+                // Add a forwarding policy on the tunnel interface. In order to support forwarding
+                // the IpSecTunnelInterface must have a forwarding policy matching the incoming SA.
+                //
+                // Unless a IpSecTransform is also applied against this interface in DIRECTION_FWD,
+                // forwarding will be blocked by default (as would be the case if this policy was
+                // absent).
+                //
+                // This is necessary only on the tunnel interface, and not any the interface to
+                // which traffic will be forwarded to.
+                netd.ipSecAddSecurityPolicy(
+                        callerUid,
+                        selAddrFamily,
+                        IpSecManager.DIRECTION_FWD,
+                        remoteAddr,
+                        localAddr,
+                        0,
+                        ikey,
+                        0xffffffff,
+                        resourceId);
             }
 
             userRecord.mTunnelInterfaceRecords.put(
@@ -1820,7 +1845,7 @@
         int mark =
                 (direction == IpSecManager.DIRECTION_OUT)
                         ? tunnelInterfaceInfo.getOkey()
-                        : tunnelInterfaceInfo.getIkey();
+                        : tunnelInterfaceInfo.getIkey(); // Ikey also used for FWD policies
 
         try {
             // Default to using the invalid SPI of 0 for inbound SAs. This allows policies to skip
diff --git a/services/core/java/com/android/server/OWNERS b/services/core/java/com/android/server/OWNERS
index 55e1b46..4ab947d 100644
--- a/services/core/java/com/android/server/OWNERS
+++ b/services/core/java/com/android/server/OWNERS
@@ -32,8 +32,9 @@
 per-file IpSecService.java = file:/services/core/java/com/android/server/net/OWNERS
 per-file MmsServiceBroker.java = file:/telephony/OWNERS
 per-file NetIdManager.java = file:/services/core/java/com/android/server/net/OWNERS
-per-file PackageWatchdog.java = file:/services/core/java/com/android/server/rollback/OWNERS
+per-file PackageWatchdog.java, RescueParty.java = file:/services/core/java/com/android/server/rollback/OWNERS
 per-file PinnerService.java = file:/apct-tests/perftests/OWNERS
+per-file RescueParty.java = fdunlap@google.com, shuc@google.com
 per-file TelephonyRegistry.java = file:/telephony/OWNERS
 per-file UiModeManagerService.java = file:/packages/SystemUI/OWNERS
 per-file VcnManagementService.java = file:/services/core/java/com/android/server/vcn/OWNERS
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index d9ecdda..8084de8 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -2873,6 +2873,8 @@
             // If we're enforcing fine starting in Q, we also want to enforce coarse even for
             // older SDK versions.
             locationQueryBuilder.setMinSdkVersionForCoarse(0);
+            locationQueryBuilder.setMinSdkVersionForCoarse(0);
+            locationQueryBuilder.setMinSdkVersionForEnforcement(0);
             shouldCheckLocationPermissions = true;
         }
 
@@ -3001,6 +3003,14 @@
         }
     }
 
+    private boolean checkFineLocationAccess(Record r) {
+        return checkFineLocationAccess(r, Build.VERSION_CODES.BASE);
+    }
+
+    private boolean checkCoarseLocationAccess(Record r) {
+        return checkCoarseLocationAccess(r, Build.VERSION_CODES.BASE);
+    }
+
     /**
      * Note -- this method should only be used at the site of a permission check if you need to
      * explicitly allow apps below a certain SDK level access regardless of location permissions.
@@ -3016,6 +3026,8 @@
                         .setMethod("TelephonyRegistry push")
                         .setLogAsInfo(true) // we don't need to log an error every time we push
                         .setMinSdkVersionForFine(minSdk)
+                        .setMinSdkVersionForCoarse(minSdk)
+                        .setMinSdkVersionForEnforcement(minSdk)
                         .build();
 
         return Binder.withCleanCallingIdentity(() -> {
@@ -3040,6 +3052,8 @@
                         .setMethod("TelephonyRegistry push")
                         .setLogAsInfo(true) // we don't need to log an error every time we push
                         .setMinSdkVersionForCoarse(minSdk)
+                        .setMinSdkVersionForFine(Integer.MAX_VALUE)
+                        .setMinSdkVersionForEnforcement(minSdk)
                         .build();
 
         return Binder.withCleanCallingIdentity(() -> {
diff --git a/services/core/java/com/android/server/VcnManagementService.java b/services/core/java/com/android/server/VcnManagementService.java
index 45eb774..bcbd692 100644
--- a/services/core/java/com/android/server/VcnManagementService.java
+++ b/services/core/java/com/android/server/VcnManagementService.java
@@ -87,6 +87,7 @@
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Objects;
+import java.util.Set;
 import java.util.concurrent.TimeUnit;
 
 /**
@@ -166,7 +167,6 @@
     @NonNull private final VcnNetworkProvider mNetworkProvider;
     @NonNull private final TelephonySubscriptionTrackerCallback mTelephonySubscriptionTrackerCb;
     @NonNull private final TelephonySubscriptionTracker mTelephonySubscriptionTracker;
-    @NonNull private final VcnContext mVcnContext;
     @NonNull private final BroadcastReceiver mPkgChangeReceiver;
 
     @NonNull
@@ -211,7 +211,6 @@
                 mContext, mLooper, mTelephonySubscriptionTrackerCb);
 
         mConfigDiskRwHelper = mDeps.newPersistableBundleLockingReadWriteHelper(VCN_CONFIG_FILE);
-        mVcnContext = mDeps.newVcnContext(mContext, mLooper, mNetworkProvider);
 
         mPkgChangeReceiver = new BroadcastReceiver() {
             @Override
@@ -335,8 +334,9 @@
         public VcnContext newVcnContext(
                 @NonNull Context context,
                 @NonNull Looper looper,
-                @NonNull VcnNetworkProvider vcnNetworkProvider) {
-            return new VcnContext(context, looper, vcnNetworkProvider);
+                @NonNull VcnNetworkProvider vcnNetworkProvider,
+                boolean isInTestMode) {
+            return new VcnContext(context, looper, vcnNetworkProvider, isInTestMode);
         }
 
         /** Creates a new Vcn instance using the provided configuration */
@@ -420,6 +420,14 @@
                 "Carrier privilege required for subscription group to set VCN Config");
     }
 
+    private void enforceManageTestNetworksForTestMode(@NonNull VcnConfig vcnConfig) {
+        if (vcnConfig.isTestModeProfile()) {
+            mContext.enforceCallingPermission(
+                    android.Manifest.permission.MANAGE_TEST_NETWORKS,
+                    "Test-mode require the MANAGE_TEST_NETWORKS permission");
+        }
+    }
+
     private class VcnSubscriptionTrackerCallback implements TelephonySubscriptionTrackerCallback {
         /**
          * Handles subscription group changes, as notified by {@link TelephonySubscriptionTracker}
@@ -431,7 +439,9 @@
         public void onNewSnapshot(@NonNull TelephonySubscriptionSnapshot snapshot) {
             // Startup VCN instances
             synchronized (mLock) {
+                final TelephonySubscriptionSnapshot oldSnapshot = mLastSnapshot;
                 mLastSnapshot = snapshot;
+                Slog.d(TAG, "new snapshot: " + mLastSnapshot);
 
                 // Start any VCN instances as necessary
                 for (Entry<ParcelUuid, VcnConfig> entry : mConfigs.entrySet()) {
@@ -478,11 +488,29 @@
                         entry.getValue().updateSubscriptionSnapshot(mLastSnapshot);
                     }
                 }
+
+                final Map<ParcelUuid, Set<Integer>> oldSubGrpMappings =
+                        getSubGroupToSubIdMappings(oldSnapshot);
+                final Map<ParcelUuid, Set<Integer>> currSubGrpMappings =
+                        getSubGroupToSubIdMappings(mLastSnapshot);
+                if (!currSubGrpMappings.equals(oldSubGrpMappings)) {
+                    notifyAllPolicyListenersLocked();
+                }
             }
         }
     }
 
     @GuardedBy("mLock")
+    private Map<ParcelUuid, Set<Integer>> getSubGroupToSubIdMappings(
+            @NonNull TelephonySubscriptionSnapshot snapshot) {
+        final Map<ParcelUuid, Set<Integer>> subGrpMappings = new ArrayMap<>();
+        for (ParcelUuid subGrp : mVcns.keySet()) {
+            subGrpMappings.put(subGrp, snapshot.getAllSubIdsInGroup(subGrp));
+        }
+        return subGrpMappings;
+    }
+
+    @GuardedBy("mLock")
     private void stopVcnLocked(@NonNull ParcelUuid uuidToTeardown) {
         final Vcn vcnToTeardown = mVcns.remove(uuidToTeardown);
         if (vcnToTeardown == null) {
@@ -516,15 +544,18 @@
 
     @GuardedBy("mLock")
     private void startVcnLocked(@NonNull ParcelUuid subscriptionGroup, @NonNull VcnConfig config) {
-        Slog.v(TAG, "Starting VCN config for subGrp: " + subscriptionGroup);
+        Slog.d(TAG, "Starting VCN config for subGrp: " + subscriptionGroup);
 
         // TODO(b/176939047): Support multiple VCNs active at the same time, or limit to one active
         //                    VCN.
 
         final VcnCallbackImpl vcnCallback = new VcnCallbackImpl(subscriptionGroup);
 
+        final VcnContext vcnContext =
+                mDeps.newVcnContext(
+                        mContext, mLooper, mNetworkProvider, config.isTestModeProfile());
         final Vcn newInstance =
-                mDeps.newVcn(mVcnContext, subscriptionGroup, config, mLastSnapshot, vcnCallback);
+                mDeps.newVcn(vcnContext, subscriptionGroup, config, mLastSnapshot, vcnCallback);
         mVcns.put(subscriptionGroup, newInstance);
 
         // Now that a new VCN has started, notify all registered listeners to refresh their
@@ -538,7 +569,7 @@
     @GuardedBy("mLock")
     private void startOrUpdateVcnLocked(
             @NonNull ParcelUuid subscriptionGroup, @NonNull VcnConfig config) {
-        Slog.v(TAG, "Starting or updating VCN config for subGrp: " + subscriptionGroup);
+        Slog.d(TAG, "Starting or updating VCN config for subGrp: " + subscriptionGroup);
 
         if (mVcns.containsKey(subscriptionGroup)) {
             final Vcn vcn = mVcns.get(subscriptionGroup);
@@ -564,10 +595,11 @@
         if (!config.getProvisioningPackageName().equals(opPkgName)) {
             throw new IllegalArgumentException("Mismatched caller and VcnConfig creator");
         }
-        Slog.v(TAG, "VCN config updated for subGrp: " + subscriptionGroup);
+        Slog.d(TAG, "VCN config updated for subGrp: " + subscriptionGroup);
 
         mContext.getSystemService(AppOpsManager.class)
                 .checkPackage(mDeps.getBinderCallingUid(), config.getProvisioningPackageName());
+        enforceManageTestNetworksForTestMode(config);
         enforceCallingUserAndCarrierPrivilege(subscriptionGroup, opPkgName);
 
         Binder.withCleanCallingIdentity(() -> {
@@ -589,7 +621,7 @@
     public void clearVcnConfig(@NonNull ParcelUuid subscriptionGroup, @NonNull String opPkgName) {
         requireNonNull(subscriptionGroup, "subscriptionGroup was null");
         requireNonNull(opPkgName, "opPkgName was null");
-        Slog.v(TAG, "VCN config cleared for subGrp: " + subscriptionGroup);
+        Slog.d(TAG, "VCN config cleared for subGrp: " + subscriptionGroup);
 
         mContext.getSystemService(AppOpsManager.class)
                 .checkPackage(mDeps.getBinderCallingUid(), opPkgName);
@@ -815,6 +847,8 @@
             if (isVcnManagedNetwork) {
                 ncBuilder.removeCapability(
                         NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
+            } else {
+                ncBuilder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
             }
 
             if (isRestrictedCarrierWifi) {
@@ -823,8 +857,14 @@
             }
 
             final NetworkCapabilities result = ncBuilder.build();
-            return new VcnUnderlyingNetworkPolicy(
+            final VcnUnderlyingNetworkPolicy policy = new VcnUnderlyingNetworkPolicy(
                     mTrackingNetworkCallback.requiresRestartForCarrierWifi(result), result);
+
+            if (VDBG) {
+                Slog.d(TAG, "getUnderlyingNetworkPolicy() called for caps: " + networkCapabilities
+                        + "; and lp: " + linkProperties + "; result = " + policy);
+            }
+            return policy;
         });
     }
 
diff --git a/services/core/java/com/android/server/VpnManagerService.java b/services/core/java/com/android/server/VpnManagerService.java
index d756c1f..26ecee8 100644
--- a/services/core/java/com/android/server/VpnManagerService.java
+++ b/services/core/java/com/android/server/VpnManagerService.java
@@ -605,7 +605,7 @@
             return null;
         } else {
             final UnderlyingNetworkInfo info = vpn.getUnderlyingNetworkInfo();
-            return (info == null || info.ownerUid != uid) ? null : vpn;
+            return (info == null || info.getOwnerUid() != uid) ? null : vpn;
         }
     }
 
diff --git a/services/core/java/com/android/server/Watchdog.java b/services/core/java/com/android/server/Watchdog.java
index a37115d..2e38278 100644
--- a/services/core/java/com/android/server/Watchdog.java
+++ b/services/core/java/com/android/server/Watchdog.java
@@ -96,6 +96,7 @@
         "/system/bin/audioserver",
         "/system/bin/cameraserver",
         "/system/bin/drmserver",
+        "/system/bin/keystore2",
         "/system/bin/mediadrmserver",
         "/system/bin/mediaserver",
         "/system/bin/netd",
diff --git a/services/core/java/com/android/server/am/LmkdConnection.java b/services/core/java/com/android/server/am/LmkdConnection.java
index f41c364..1ecb9eb 100644
--- a/services/core/java/com/android/server/am/LmkdConnection.java
+++ b/services/core/java/com/android/server/am/LmkdConnection.java
@@ -31,6 +31,8 @@
 
 import libcore.io.IoUtils;
 
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
 import java.io.FileDescriptor;
 import java.io.IOException;
 import java.io.InputStream;
@@ -43,8 +45,12 @@
 public class LmkdConnection {
     private static final String TAG = TAG_WITH_CLASS_NAME ? "LmkdConnection" : TAG_AM;
 
-    // lmkd reply max size in bytes
-    private static final int LMKD_REPLY_MAX_SIZE = 12;
+    /**
+     * Max LMKD reply packet length in bytes
+     * Used to hold the data for the statsd atoms logging
+     * Must be in sync with statslog.h
+     */
+    private static final int LMKD_REPLY_MAX_SIZE = 214;
 
     // connection listener interface
     interface LmkdConnectionListener {
@@ -70,7 +76,7 @@
          * @param receivedLen Size of the data received
          * @return True if the message has been handled correctly, false otherwise.
          */
-        boolean handleUnsolicitedMessage(ByteBuffer dataReceived, int receivedLen);
+        boolean handleUnsolicitedMessage(DataInputStream inputData, int receivedLen);
     }
 
     private final MessageQueue mMsgQueue;
@@ -95,6 +101,10 @@
     private final ByteBuffer mInputBuf =
             ByteBuffer.allocate(LMKD_REPLY_MAX_SIZE);
 
+    // Input stream to parse the incoming data
+    private final DataInputStream mInputData = new DataInputStream(
+            new ByteArrayInputStream(mInputBuf.array()));
+
     // object to protect mReplyBuf and to wait/notify when reply is received
     private final Object mReplyBufLock = new Object();
 
@@ -186,26 +196,32 @@
     private void processIncomingData() {
         int len = read(mInputBuf);
         if (len > 0) {
-            synchronized (mReplyBufLock) {
-                if (mReplyBuf != null) {
-                    if (mListener.isReplyExpected(mReplyBuf, mInputBuf, len)) {
-                        // copy into reply buffer
-                        mReplyBuf.put(mInputBuf.array(), 0, len);
-                        mReplyBuf.rewind();
-                        // wakeup the waiting thread
-                        mReplyBufLock.notifyAll();
-                    } else if (!mListener.handleUnsolicitedMessage(mInputBuf, len)) {
-                        // received unexpected packet
-                        // treat this as an error
-                        mReplyBuf = null;
-                        mReplyBufLock.notifyAll();
-                        Slog.e(TAG, "Received an unexpected packet from lmkd");
+            try {
+                // reset InputStream to point into mInputBuf.array() begin
+                mInputData.reset();
+                synchronized (mReplyBufLock) {
+                    if (mReplyBuf != null) {
+                        if (mListener.isReplyExpected(mReplyBuf, mInputBuf, len)) {
+                            // copy into reply buffer
+                            mReplyBuf.put(mInputBuf.array(), 0, len);
+                            mReplyBuf.rewind();
+                            // wakeup the waiting thread
+                            mReplyBufLock.notifyAll();
+                        } else if (!mListener.handleUnsolicitedMessage(mInputData, len)) {
+                            // received unexpected packet
+                            // treat this as an error
+                            mReplyBuf = null;
+                            mReplyBufLock.notifyAll();
+                            Slog.e(TAG, "Received an unexpected packet from lmkd");
+                        }
+                    } else if (!mListener.handleUnsolicitedMessage(mInputData, len)) {
+                        // received asynchronous communication from lmkd
+                        // but we don't recognize it.
+                        Slog.w(TAG, "Received an unexpected packet from lmkd");
                     }
-                } else if (!mListener.handleUnsolicitedMessage(mInputBuf, len)) {
-                    // received asynchronous communication from lmkd
-                    // but we don't recognize it.
-                    Slog.w(TAG, "Received an unexpected packet from lmkd");
                 }
+            } catch (IOException e) {
+                Slog.e(TAG, "Failed to parse lmkd data buffer. Size = " + len);
             }
         }
     }
diff --git a/services/core/java/com/android/server/am/LmkdStatsReporter.java b/services/core/java/com/android/server/am/LmkdStatsReporter.java
new file mode 100644
index 0000000..c702d78
--- /dev/null
+++ b/services/core/java/com/android/server/am/LmkdStatsReporter.java
@@ -0,0 +1,107 @@
+/*
+ * 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 com.android.server.am;
+
+import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
+import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
+
+import android.util.Slog;
+
+import com.android.internal.util.FrameworkStatsLog;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+
+/**
+ * Activity manager communication with lmkd data handling and statsd atom logging
+ */
+public final class LmkdStatsReporter {
+
+    static final String TAG = TAG_WITH_CLASS_NAME ? "LmkdStatsReporter" : TAG_AM;
+
+    public static final int KILL_OCCURRED_MSG_SIZE = 80;
+    public static final int STATE_CHANGED_MSG_SIZE = 8;
+
+    private static final int PRESSURE_AFTER_KILL = 0;
+    private static final int NOT_RESPONDING = 1;
+    private static final int LOW_SWAP_AND_THRASHING = 2;
+    private static final int LOW_MEM_AND_SWAP = 3;
+    private static final int LOW_MEM_AND_THRASHING = 4;
+    private static final int DIRECT_RECL_AND_THRASHING = 5;
+    private static final int LOW_MEM_AND_SWAP_UTIL = 6;
+
+    /**
+     * Processes the LMK_KILL_OCCURRED packet data
+     * Logs the event when LMKD kills a process to reduce memory pressure.
+     * Code: LMK_KILL_OCCURRED = 51
+     */
+    public static void logKillOccurred(DataInputStream inputData) {
+        try {
+            final long pgFault = inputData.readLong();
+            final long pgMajFault = inputData.readLong();
+            final long rssInBytes = inputData.readLong();
+            final long cacheInBytes = inputData.readLong();
+            final long swapInBytes = inputData.readLong();
+            final long processStartTimeNS = inputData.readLong();
+            final int uid = inputData.readInt();
+            final int oomScore = inputData.readInt();
+            final int minOomScore = inputData.readInt();
+            final int freeMemKb = inputData.readInt();
+            final int freeSwapKb = inputData.readInt();
+            final int killReason = inputData.readInt();
+            final String procName = inputData.readUTF();
+
+            FrameworkStatsLog.write(FrameworkStatsLog.LMK_KILL_OCCURRED, uid, procName, oomScore,
+                    pgFault, pgMajFault, rssInBytes, cacheInBytes, swapInBytes, processStartTimeNS,
+                    minOomScore, freeMemKb, freeSwapKb, mapKillReason(killReason));
+        } catch (IOException e) {
+            Slog.e(TAG, "Invalid buffer data. Failed to log LMK_KILL_OCCURRED");
+            return;
+        }
+    }
+
+    /**
+     * Processes the LMK_STATE_CHANGED packet
+     * Logs the change in LMKD state which is used as start/stop boundaries for logging
+     * LMK_KILL_OCCURRED event.
+     * Code: LMK_STATE_CHANGED = 54
+     */
+    public static void logStateChanged(int state) {
+        FrameworkStatsLog.write(FrameworkStatsLog.LMK_STATE_CHANGED, state);
+    }
+
+    private static int mapKillReason(int reason) {
+        switch (reason) {
+            case PRESSURE_AFTER_KILL:
+                return FrameworkStatsLog.LMK_KILL_OCCURRED__REASON__PRESSURE_AFTER_KILL;
+            case NOT_RESPONDING:
+                return FrameworkStatsLog.LMK_KILL_OCCURRED__REASON__NOT_RESPONDING;
+            case LOW_SWAP_AND_THRASHING:
+                return FrameworkStatsLog.LMK_KILL_OCCURRED__REASON__LOW_SWAP_AND_THRASHING;
+            case LOW_MEM_AND_SWAP:
+                return FrameworkStatsLog.LMK_KILL_OCCURRED__REASON__LOW_MEM_AND_SWAP;
+            case LOW_MEM_AND_THRASHING:
+                return FrameworkStatsLog.LMK_KILL_OCCURRED__REASON__LOW_MEM_AND_THRASHING;
+            case DIRECT_RECL_AND_THRASHING:
+                return FrameworkStatsLog.LMK_KILL_OCCURRED__REASON__DIRECT_RECL_AND_THRASHING;
+            case LOW_MEM_AND_SWAP_UTIL:
+                return FrameworkStatsLog.LMK_KILL_OCCURRED__REASON__LOW_MEM_AND_SWAP_UTIL;
+            default:
+                return FrameworkStatsLog.LMK_KILL_OCCURRED__REASON__UNKNOWN;
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 444418c..e9b0146 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -125,6 +125,7 @@
 
 import dalvik.system.VMRuntime;
 
+import java.io.DataInputStream;
 import java.io.File;
 import java.io.FileDescriptor;
 import java.io.IOException;
@@ -316,18 +317,25 @@
     // LMK_GETKILLCNT
     // LMK_SUBSCRIBE
     // LMK_PROCKILL
+    // LMK_UPDATE_PROPS
+    // LMK_KILL_OCCURRED
+    // LMK_STATE_CHANGED
     static final byte LMK_TARGET = 0;
     static final byte LMK_PROCPRIO = 1;
     static final byte LMK_PROCREMOVE = 2;
     static final byte LMK_PROCPURGE = 3;
     static final byte LMK_GETKILLCNT = 4;
     static final byte LMK_SUBSCRIBE = 5;
-    static final byte LMK_PROCKILL = 6; // Note: this is an unsolicated command
+    static final byte LMK_PROCKILL = 6; // Note: this is an unsolicited command
+    static final byte LMK_UPDATE_PROPS = 7;
+    static final byte LMK_KILL_OCCURRED = 8; // Msg to subscribed clients on kill occurred event
+    static final byte LMK_STATE_CHANGED = 9; // Msg to subscribed clients on state changed
 
     // Low Memory Killer Daemon command codes.
     // These must be kept in sync with async_event_type definitions in lmkd.h
     //
     static final int LMK_ASYNC_EVENT_KILL = 0;
+    static final int LMK_ASYNC_EVENT_STAT = 1;
 
     // lmkd reconnect delay in msecs
     private static final long LMKD_RECONNECT_DELAY_MS = 1000;
@@ -776,22 +784,44 @@
                         }
 
                         @Override
-                        public boolean handleUnsolicitedMessage(ByteBuffer dataReceived,
+                        public boolean handleUnsolicitedMessage(DataInputStream inputData,
                                 int receivedLen) {
                             if (receivedLen < 4) {
                                 return false;
                             }
-                            switch (dataReceived.getInt(0)) {
-                                case LMK_PROCKILL:
-                                    if (receivedLen != 12) {
+
+                            try {
+                                switch (inputData.readInt()) {
+                                    case LMK_PROCKILL:
+                                        if (receivedLen != 12) {
+                                            return false;
+                                        }
+                                        final int pid = inputData.readInt();
+                                        final int uid = inputData.readInt();
+                                        mAppExitInfoTracker.scheduleNoteLmkdProcKilled(pid, uid);
+                                        return true;
+                                    case LMK_KILL_OCCURRED:
+                                        if (receivedLen
+                                                < LmkdStatsReporter.KILL_OCCURRED_MSG_SIZE) {
+                                            return false;
+                                        }
+                                        LmkdStatsReporter.logKillOccurred(inputData);
+                                        return true;
+                                    case LMK_STATE_CHANGED:
+                                        if (receivedLen
+                                                != LmkdStatsReporter.STATE_CHANGED_MSG_SIZE) {
+                                            return false;
+                                        }
+                                        final int state = inputData.readInt();
+                                        LmkdStatsReporter.logStateChanged(state);
+                                        return true;
+                                    default:
                                         return false;
-                                    }
-                                    mAppExitInfoTracker.scheduleNoteLmkdProcKilled(
-                                            dataReceived.getInt(4), dataReceived.getInt(8));
-                                    return true;
-                                default:
-                                    return false;
+                                }
+                            } catch (IOException e) {
+                                Slog.e(TAG, "Invalid buffer data. Failed to log LMK_KILL_OCCURRED");
                             }
+                            return false;
                         }
                     }
             );
@@ -1433,6 +1463,12 @@
             buf.putInt(LMK_SUBSCRIBE);
             buf.putInt(LMK_ASYNC_EVENT_KILL);
             ostream.write(buf.array(), 0, buf.position());
+
+            // Subscribe for stats event notifications
+            buf = ByteBuffer.allocate(4 * 2);
+            buf.putInt(LMK_SUBSCRIBE);
+            buf.putInt(LMK_ASYNC_EVENT_STAT);
+            ostream.write(buf.array(), 0, buf.position());
         } catch (IOException ex) {
             return false;
         }
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 22a6044..d0a3079 100755
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -5860,6 +5860,10 @@
                     if (index == -1) {
                         continue;
                     }
+                    if (mPublicStreamType == AudioSystem.STREAM_SYSTEM_ENFORCED
+                            && mCameraSoundForced) {
+                        index = mIndexMax;
+                    }
                     if (DEBUG_VOL) {
                         Log.v(TAG, "readSettings: found stored index " + getValidIndex(index)
                                  + " for group " + mAudioVolumeGroup.name() + ", device: " + name);
diff --git a/services/core/java/com/android/server/biometrics/AuthService.java b/services/core/java/com/android/server/biometrics/AuthService.java
index 1312679..8fd8b5c 100644
--- a/services/core/java/com/android/server/biometrics/AuthService.java
+++ b/services/core/java/com/android/server/biometrics/AuthService.java
@@ -289,7 +289,7 @@
         }
 
         @Override
-        public long[] getAuthenticatorIds() throws RemoteException {
+        public long[] getAuthenticatorIds(int userId) throws RemoteException {
             // In this method, we're not checking whether the caller is permitted to use face
             // API because current authenticator ID is leaked (in a more contrived way) via Android
             // Keystore (android.security.keystore package): the user of that API can create a key
@@ -307,9 +307,13 @@
             // method from inside app processes.
 
             final int callingUserId = UserHandle.getCallingUserId();
+            if (userId != callingUserId) {
+                getContext().enforceCallingOrSelfPermission(USE_BIOMETRIC_INTERNAL,
+                        "Must have " + USE_BIOMETRIC_INTERNAL + " permission.");
+            }
             final long identity = Binder.clearCallingIdentity();
             try {
-                return mBiometricService.getAuthenticatorIds(callingUserId);
+                return mBiometricService.getAuthenticatorIds(userId);
             } finally {
                 Binder.restoreCallingIdentity(identity);
             }
diff --git a/services/core/java/com/android/server/biometrics/OWNERS b/services/core/java/com/android/server/biometrics/OWNERS
index 8765c9a..4eac972 100644
--- a/services/core/java/com/android/server/biometrics/OWNERS
+++ b/services/core/java/com/android/server/biometrics/OWNERS
@@ -5,3 +5,4 @@
 curtislb@google.com
 ilyamaty@google.com
 joshmccloskey@google.com
+jbolinger@google.com
diff --git a/services/core/java/com/android/server/compat/CompatConfig.java b/services/core/java/com/android/server/compat/CompatConfig.java
index 55e2696..9247568 100644
--- a/services/core/java/com/android/server/compat/CompatConfig.java
+++ b/services/core/java/com/android/server/compat/CompatConfig.java
@@ -33,6 +33,7 @@
 import com.android.internal.compat.CompatibilityChangeConfig;
 import com.android.internal.compat.CompatibilityChangeInfo;
 import com.android.internal.compat.CompatibilityOverrideConfig;
+import com.android.internal.compat.CompatibilityOverridesToRemoveConfig;
 import com.android.internal.compat.IOverrideValidator;
 import com.android.internal.compat.OverrideAllowedState;
 import com.android.server.compat.config.Change;
@@ -370,6 +371,27 @@
         }
     }
 
+    /**
+     * Removes overrides whose change ID is specified in {@code overridesToRemove} that were
+     * previously added via {@link #addOverride(long, String, boolean)} or
+     * {@link #addOverrides(CompatibilityOverrideConfig, String)} for a certain package.
+     *
+     * <p>This restores the default behaviour for the given change IDs and app.
+     *
+     * @param overridesToRemove list of change IDs for which to restore the default behaviour.
+     * @param packageName       the package for which the overrides should be purged
+     */
+    void removePackageOverrides(CompatibilityOverridesToRemoveConfig overridesToRemove,
+            String packageName) {
+        synchronized (mChanges) {
+            for (Long changeId : overridesToRemove.changeIds) {
+                removeOverrideUnsafe(changeId, packageName);
+            }
+            saveOverrides();
+            invalidateCache();
+        }
+    }
+
     private long[] getAllowedChangesSinceTargetSdkForPackage(String packageName,
             int targetSdkVersion) {
         LongArray allowed = new LongArray();
diff --git a/services/core/java/com/android/server/compat/PlatformCompat.java b/services/core/java/com/android/server/compat/PlatformCompat.java
index 20469a2..2591f38 100644
--- a/services/core/java/com/android/server/compat/PlatformCompat.java
+++ b/services/core/java/com/android/server/compat/PlatformCompat.java
@@ -46,6 +46,7 @@
 import com.android.internal.compat.CompatibilityChangeConfig;
 import com.android.internal.compat.CompatibilityChangeInfo;
 import com.android.internal.compat.CompatibilityOverrideConfig;
+import com.android.internal.compat.CompatibilityOverridesToRemoveConfig;
 import com.android.internal.compat.IOverrideValidator;
 import com.android.internal.compat.IPlatformCompat;
 import com.android.internal.util.DumpUtils;
@@ -54,6 +55,7 @@
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -187,7 +189,7 @@
             String packageName) {
         // TODO(b/183630314): Unify the permission enforcement with the other setOverrides* methods.
         checkCompatChangeOverrideOverridablePermission();
-        checkAllCompatOverridesAreOverridable(overrides);
+        checkAllCompatOverridesAreOverridable(overrides.overrides.keySet());
         mCompatConfig.addOverrides(overrides, packageName);
     }
 
@@ -251,6 +253,16 @@
     }
 
     @Override
+    public void removeOverridesOnReleaseBuilds(
+            CompatibilityOverridesToRemoveConfig overridesToRemove,
+            String packageName) {
+        // TODO(b/183630314): Unify the permission enforcement with the other setOverrides* methods.
+        checkCompatChangeOverrideOverridablePermission();
+        checkAllCompatOverridesAreOverridable(overridesToRemove.changeIds);
+        mCompatConfig.removePackageOverrides(overridesToRemove, packageName);
+    }
+
+    @Override
     public CompatibilityChangeConfig getAppConfig(ApplicationInfo appInfo) {
         checkCompatChangeReadAndLogPermission();
         return mCompatConfig.getAppConfig(appInfo);
@@ -396,8 +408,8 @@
         }
     }
 
-    private void checkAllCompatOverridesAreOverridable(CompatibilityOverrideConfig overrides) {
-        for (Long changeId : overrides.overrides.keySet()) {
+    private void checkAllCompatOverridesAreOverridable(Collection<Long> changeIds) {
+        for (Long changeId : changeIds) {
             if (!mCompatConfig.isOverridable(changeId)) {
                 throw new SecurityException("Only change ids marked as Overridable can be "
                         + "overridden.");
diff --git a/services/core/java/com/android/server/connectivity/DnsManager.java b/services/core/java/com/android/server/connectivity/DnsManager.java
index cf4fe1e..05b12ba 100644
--- a/services/core/java/com/android/server/connectivity/DnsManager.java
+++ b/services/core/java/com/android/server/connectivity/DnsManager.java
@@ -16,14 +16,14 @@
 
 package com.android.server.connectivity;
 
-import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OFF;
-import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME;
 import static android.net.ConnectivitySettingsManager.DNS_RESOLVER_MAX_SAMPLES;
 import static android.net.ConnectivitySettingsManager.DNS_RESOLVER_MIN_SAMPLES;
 import static android.net.ConnectivitySettingsManager.DNS_RESOLVER_SAMPLE_VALIDITY_SECONDS;
 import static android.net.ConnectivitySettingsManager.DNS_RESOLVER_SUCCESS_THRESHOLD_PERCENT;
 import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_DEFAULT_MODE;
 import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE;
+import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_OFF;
+import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME;
 import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_SPECIFIER;
 import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.VALIDATION_RESULT_FAILURE;
 import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.VALIDATION_RESULT_SUCCESS;
@@ -33,6 +33,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.net.ConnectivityManager;
+import android.net.ConnectivitySettingsManager;
 import android.net.IDnsResolver;
 import android.net.InetAddresses;
 import android.net.LinkProperties;
@@ -131,11 +132,11 @@
      * Get PrivateDnsConfig.
      */
     public static PrivateDnsConfig getPrivateDnsConfig(Context context) {
-        final String mode = ConnectivityManager.getPrivateDnsMode(context);
+        final int mode = ConnectivitySettingsManager.getPrivateDnsMode(context);
 
-        final boolean useTls = !TextUtils.isEmpty(mode) && !PRIVATE_DNS_MODE_OFF.equals(mode);
+        final boolean useTls = mode != PRIVATE_DNS_MODE_OFF;
 
-        if (PRIVATE_DNS_MODE_PROVIDER_HOSTNAME.equals(mode)) {
+        if (PRIVATE_DNS_MODE_PROVIDER_HOSTNAME == mode) {
             final String specifier = getStringSetting(context.getContentResolver(),
                     PRIVATE_DNS_SPECIFIER);
             return new PrivateDnsConfig(specifier, null);
diff --git a/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java b/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java
index 4ecc759..091e6c4 100644
--- a/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java
+++ b/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java
@@ -27,6 +27,7 @@
 import static android.net.NetworkPolicy.WARNING_DISABLED;
 import static android.net.NetworkTemplate.NETWORK_TYPE_ALL;
 import static android.net.NetworkTemplate.OEM_MANAGED_ALL;
+import static android.net.NetworkTemplate.SUBSCRIBER_ID_MATCH_RULE_EXACT;
 import static android.provider.Settings.Global.NETWORK_DEFAULT_DAILY_MULTIPATH_QUOTA_BYTES;
 import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
 
@@ -227,7 +228,8 @@
             mNetworkTemplate = new NetworkTemplate(
                     NetworkTemplate.MATCH_MOBILE, subscriberId, new String[] { subscriberId },
                     null, NetworkStats.METERED_ALL, NetworkStats.ROAMING_ALL,
-                    NetworkStats.DEFAULT_NETWORK_NO, NETWORK_TYPE_ALL, OEM_MANAGED_ALL);
+                    NetworkStats.DEFAULT_NETWORK_NO, NETWORK_TYPE_ALL, OEM_MANAGED_ALL,
+                    SUBSCRIBER_ID_MATCH_RULE_EXACT);
             mUsageCallback = new UsageCallback() {
                 @Override
                 public void onThresholdReached(int networkType, String subscriberId) {
diff --git a/services/core/java/com/android/server/connectivity/PermissionMonitor.java b/services/core/java/com/android/server/connectivity/PermissionMonitor.java
index 7837e6e..506cadb 100644
--- a/services/core/java/com/android/server/connectivity/PermissionMonitor.java
+++ b/services/core/java/com/android/server/connectivity/PermissionMonitor.java
@@ -338,7 +338,8 @@
             return currentPermission;
         }
         try {
-            final PackageInfo app = mPackageManager.getPackageInfo(name, GET_PERMISSIONS);
+            final PackageInfo app = mPackageManager.getPackageInfo(name,
+                    GET_PERMISSIONS | MATCH_ANY_USER);
             final boolean isNetwork = hasNetworkPermission(app);
             final boolean hasRestrictedPermission = hasRestrictedNetworkPermission(app);
             if (isNetwork || hasRestrictedPermission) {
@@ -664,6 +665,7 @@
                     break;
                 case INetd.PERMISSION_UNINSTALLED:
                     uninstalledAppIds.add(netdPermissionsAppIds.keyAt(i));
+                    break;
                 default:
                     Log.e(TAG, "unknown permission type: " + permissions + "for uid: "
                             + netdPermissionsAppIds.keyAt(i));
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
index afaae8a..0677bd5 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
@@ -806,7 +806,6 @@
                     Arrays.stream(device.getEncodings()).mapToObj(
                             AudioFormat::toLogFriendlyEncoding
                     ).collect(Collectors.joining(", ")));
-            // TODO(b/80297701) use the actual device type that system audio mode is connected to.
             if (device.getType() == AudioDeviceInfo.TYPE_HDMI_ARC) {
                 return device;
             }
@@ -1225,7 +1224,6 @@
         if (isSystemAudioActivated() && port < 0) {
             // If system audio mode is on and the new active source is not under the current device,
             // Will switch to ARC input.
-            // TODO(b/115637145): handle system aduio without ARC
             routeToInputFromPortId(Constants.CEC_SWITCH_ARC);
         } else if (mIsSwitchDevice && port >= 0) {
             // If current device is a switch and the new active source is under it,
@@ -1326,7 +1324,6 @@
 
     // Handle the system audio(ARC) part of the logic on receiving routing change or information.
     private void handleRoutingChangeAndInformationForSystemAudio() {
-        // TODO(b/115637145): handle system aduio without ARC
         routeToInputFromPortId(Constants.CEC_SWITCH_ARC);
     }
 
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecMessageBuilder.java b/services/core/java/com/android/server/hdmi/HdmiCecMessageBuilder.java
index 3f949ba..ec41a2f 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecMessageBuilder.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecMessageBuilder.java
@@ -475,7 +475,6 @@
      * @return newly created {@link HdmiCecMessage}
      */
     static HdmiCecMessage buildReportShortAudioDescriptor(int src, int des, byte[] sadBytes) {
-        // TODO(b/80297701) validate.
         return buildCommand(src, des, Constants.MESSAGE_REPORT_SHORT_AUDIO_DESCRIPTOR, sadBytes);
     }
 
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlShellCommand.java b/services/core/java/com/android/server/hdmi/HdmiControlShellCommand.java
index 740407c..e233084 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlShellCommand.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlShellCommand.java
@@ -86,6 +86,8 @@
         pw.println("      Send a Vendor Command to the given target device");
         pw.println("  setsystemaudiomode, setsam [on|off]");
         pw.println("      Sets the System Audio Mode feature on or off on TV devices");
+        pw.println("  setarc [on|off]");
+        pw.println("      Sets the ARC feature on or off on TV devices");
     }
 
     private int handleShellCommand(String cmd) throws RemoteException {
@@ -100,6 +102,8 @@
             case "setsystemaudiomode":
             case "setsam":
                 return setSystemAudioMode(pw);
+            case "setarc":
+                return setArcMode(pw);
         }
 
         getErrPrintWriter().println("Unhandled command: " + cmd);
@@ -188,6 +192,27 @@
         return mCecResult.get() == HdmiControlManager.RESULT_SUCCESS ? 0 : 1;
     }
 
+    private int setArcMode(PrintWriter pw) throws RemoteException {
+        if (1 > getRemainingArgsCount()) {
+            throw new IllegalArgumentException(
+                    "Please indicate if ARC mode should be turned \"on\" or \"off\".");
+        }
+
+        String arg = getNextArg();
+        if (arg.equals("on")) {
+            pw.println("Setting ARC mode on");
+            mBinderService.setArcMode(true);
+        } else if (arg.equals("off")) {
+            pw.println("Setting ARC mode off");
+            mBinderService.setArcMode(false);
+        } else {
+            throw new IllegalArgumentException(
+                    "Please indicate if ARC mode should be turned \"on\" or \"off\".");
+        }
+
+        return 0;
+    }
+
     private boolean receiveCallback(String command) {
         try {
             if (!mLatch.await(HdmiConfig.TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
diff --git a/services/core/java/com/android/server/hdmi/SystemAudioInitiationActionFromAvr.java b/services/core/java/com/android/server/hdmi/SystemAudioInitiationActionFromAvr.java
index 0907e5d..0864a44 100644
--- a/services/core/java/com/android/server/hdmi/SystemAudioInitiationActionFromAvr.java
+++ b/services/core/java/com/android/server/hdmi/SystemAudioInitiationActionFromAvr.java
@@ -142,8 +142,4 @@
                     }
                 });
     }
-
-    private void switchToRelevantInputForDeviceAt(int physicalAddress) {
-        // TODO(shubang): implement this method
-    }
 }
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index 117c85b..07ac14f 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -29,6 +29,8 @@
 import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PATTERN;
 import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PIN;
 import static com.android.internal.widget.LockPatternUtils.EscrowTokenStateChangeCallback;
+import static com.android.internal.widget.LockPatternUtils.PROFILE_KEY_NAME_DECRYPT;
+import static com.android.internal.widget.LockPatternUtils.PROFILE_KEY_NAME_ENCRYPT;
 import static com.android.internal.widget.LockPatternUtils.SYNTHETIC_PASSWORD_HANDLE_KEY;
 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT;
 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_FOR_UNATTENDED_UPDATE;
@@ -99,6 +101,7 @@
 import android.security.keystore.recovery.KeyChainSnapshot;
 import android.security.keystore.recovery.RecoveryCertPath;
 import android.security.keystore.recovery.WrappedApplicationKey;
+import android.security.keystore2.AndroidKeyStoreLoadStoreParameter;
 import android.security.keystore2.AndroidKeyStoreProvider;
 import android.service.gatekeeper.GateKeeperResponse;
 import android.service.gatekeeper.IGateKeeperService;
@@ -153,6 +156,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Date;
+import java.util.Enumeration;
 import java.util.List;
 import java.util.Map;
 import java.util.NoSuchElementException;
@@ -225,6 +229,7 @@
     private final SyntheticPasswordManager mSpManager;
 
     private final KeyStore mKeyStore;
+    private final java.security.KeyStore mJavaKeyStore;
     private final RecoverableKeyStoreManager mRecoverableKeyStoreManager;
     private ManagedProfilePasswordCache mManagedProfilePasswordCache;
 
@@ -543,16 +548,22 @@
             return Settings.Secure.getIntForUser(contentResolver, keyName, defaultValue, userId);
         }
 
-        public @NonNull ManagedProfilePasswordCache getManagedProfilePasswordCache() {
+        public java.security.KeyStore getJavaKeyStore() {
             try {
                 java.security.KeyStore ks = java.security.KeyStore.getInstance(
                         SyntheticPasswordCrypto.androidKeystoreProviderName());
-                ks.load(null);
-                return new ManagedProfilePasswordCache(ks, getUserManager());
+                ks.load(new AndroidKeyStoreLoadStoreParameter(
+                        SyntheticPasswordCrypto.keyNamespace()));
+                return ks;
             } catch (Exception e) {
                 throw new IllegalStateException("Cannot load keystore", e);
             }
         }
+
+        public @NonNull ManagedProfilePasswordCache getManagedProfilePasswordCache(
+                java.security.KeyStore ks) {
+            return new ManagedProfilePasswordCache(ks, getUserManager());
+        }
     }
 
     public LockSettingsService(Context context) {
@@ -564,6 +575,7 @@
         mInjector = injector;
         mContext = injector.getContext();
         mKeyStore = injector.getKeyStore();
+        mJavaKeyStore = injector.getJavaKeyStore();
         mRecoverableKeyStoreManager = injector.getRecoverableKeyStoreManager();
         mHandler = injector.getHandler(injector.getServiceThread());
         mStrongAuth = injector.getStrongAuth();
@@ -586,7 +598,7 @@
         mStrongAuthTracker.register(mStrongAuth);
 
         mSpManager = injector.getSyntheticPasswordManager(mStorage);
-        mManagedProfilePasswordCache = injector.getManagedProfilePasswordCache();
+        mManagedProfilePasswordCache = injector.getManagedProfilePasswordCache(mJavaKeyStore);
 
         mRebootEscrowManager = injector.getRebootEscrowManager(new RebootEscrowCallbacks(),
                 mStorage);
@@ -959,6 +971,21 @@
             setString("migrated_wear_lockscreen_disabled", "true", 0);
             Slog.i(TAG, "Migrated lockscreen_disabled for Wear devices");
         }
+
+        if (getString("migrated_keystore_namespace", null, 0) == null) {
+            boolean success = true;
+            synchronized (mSpManager) {
+                success &= mSpManager.migrateKeyNamespace();
+            }
+            success &= migrateProfileLockKeys();
+            if (success) {
+                setString("migrated_keystore_namespace", "true", 0);
+                Slog.i(TAG, "Migrated keys to LSS namespace");
+            } else {
+                Slog.w(TAG, "Failed to migrate keys to LSS namespace");
+            }
+        }
+
     }
 
     private void migrateOldDataAfterSystemReady() {
@@ -999,6 +1026,22 @@
         }
     }
 
+    private boolean migrateProfileLockKeys() {
+        boolean success = true;
+        final List<UserInfo> users = mUserManager.getUsers();
+        final int userCount = users.size();
+        for (int i = 0; i < userCount; i++) {
+            UserInfo user = users.get(i);
+            if (user.isManagedProfile() && !getSeparateProfileChallengeEnabledInternal(user.id)) {
+                success &= SyntheticPasswordCrypto.migrateLockSettingsKey(
+                        PROFILE_KEY_NAME_ENCRYPT + user.id);
+                success &= SyntheticPasswordCrypto.migrateLockSettingsKey(
+                        PROFILE_KEY_NAME_DECRYPT + user.id);
+            }
+        }
+        return success;
+    }
+
     /**
      * Returns the lowest password quality that still presents the same UI for entering it.
      *
@@ -1266,7 +1309,7 @@
 
     private void unlockKeystore(byte[] password, int userHandle) {
         if (DEBUG) Slog.v(TAG, "Unlock keystore for user: " + userHandle);
-        Authorization.onLockScreenEvent(false, userHandle, password);
+        Authorization.onLockScreenEvent(false, userHandle, password, null);
     }
 
     @VisibleForTesting /** Note: this method is overridden in unit tests */
@@ -1284,11 +1327,8 @@
         byte[] encryptedPassword = Arrays.copyOfRange(storedData, PROFILE_KEY_IV_SIZE,
                 storedData.length);
         byte[] decryptionResult;
-        java.security.KeyStore keyStore = java.security.KeyStore.getInstance(
-                SyntheticPasswordCrypto.androidKeystoreProviderName());
-        keyStore.load(null);
-        SecretKey decryptionKey = (SecretKey) keyStore.getKey(
-                LockPatternUtils.PROFILE_KEY_NAME_DECRYPT + userId, null);
+        SecretKey decryptionKey = (SecretKey) mJavaKeyStore.getKey(
+                PROFILE_KEY_NAME_DECRYPT + userId, null);
 
         Cipher cipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/"
                 + KeyProperties.BLOCK_MODE_GCM + "/" + KeyProperties.ENCRYPTION_PADDING_NONE);
@@ -1744,30 +1784,26 @@
             KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES);
             keyGenerator.init(new SecureRandom());
             SecretKey secretKey = keyGenerator.generateKey();
-            java.security.KeyStore keyStore = java.security.KeyStore.getInstance(
-                    SyntheticPasswordCrypto.androidKeystoreProviderName());
-            keyStore.load(null);
             try {
-                keyStore.setEntry(
-                        LockPatternUtils.PROFILE_KEY_NAME_ENCRYPT + userId,
+                mJavaKeyStore.setEntry(
+                        PROFILE_KEY_NAME_ENCRYPT + userId,
                         new java.security.KeyStore.SecretKeyEntry(secretKey),
                         new KeyProtection.Builder(KeyProperties.PURPOSE_ENCRYPT)
                                 .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
                                 .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
                                 .build());
-                keyStore.setEntry(
-                        LockPatternUtils.PROFILE_KEY_NAME_DECRYPT + userId,
+                mJavaKeyStore.setEntry(
+                        PROFILE_KEY_NAME_DECRYPT + userId,
                         new java.security.KeyStore.SecretKeyEntry(secretKey),
                         new KeyProtection.Builder(KeyProperties.PURPOSE_DECRYPT)
                                 .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
                                 .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
                                 .setUserAuthenticationRequired(true)
                                 .setUserAuthenticationValidityDurationSeconds(30)
-                                .setCriticalToDeviceEncryption(true)
                                 .build());
                 // Key imported, obtain a reference to it.
-                SecretKey keyStoreEncryptionKey = (SecretKey) keyStore.getKey(
-                        LockPatternUtils.PROFILE_KEY_NAME_ENCRYPT + userId, null);
+                SecretKey keyStoreEncryptionKey = (SecretKey) mJavaKeyStore.getKey(
+                        PROFILE_KEY_NAME_ENCRYPT + userId, null);
                 Cipher cipher = Cipher.getInstance(
                         KeyProperties.KEY_ALGORITHM_AES + "/" + KeyProperties.BLOCK_MODE_GCM + "/"
                                 + KeyProperties.ENCRYPTION_PADDING_NONE);
@@ -1776,10 +1812,10 @@
                 iv = cipher.getIV();
             } finally {
                 // The original key can now be discarded.
-                keyStore.deleteEntry(LockPatternUtils.PROFILE_KEY_NAME_ENCRYPT + userId);
+                mJavaKeyStore.deleteEntry(PROFILE_KEY_NAME_ENCRYPT + userId);
             }
-        } catch (CertificateException | UnrecoverableKeyException
-                | IOException | BadPaddingException | IllegalBlockSizeException | KeyStoreException
+        } catch (UnrecoverableKeyException
+                | BadPaddingException | IllegalBlockSizeException | KeyStoreException
                 | NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeyException e) {
             throw new IllegalStateException("Failed to encrypt key", e);
         }
@@ -2300,13 +2336,9 @@
     private void removeKeystoreProfileKey(int targetUserId) {
         Slog.i(TAG, "Remove keystore profile key for user: " + targetUserId);
         try {
-            java.security.KeyStore keyStore = java.security.KeyStore.getInstance(
-                    SyntheticPasswordCrypto.androidKeystoreProviderName());
-            keyStore.load(null);
-            keyStore.deleteEntry(LockPatternUtils.PROFILE_KEY_NAME_ENCRYPT + targetUserId);
-            keyStore.deleteEntry(LockPatternUtils.PROFILE_KEY_NAME_DECRYPT + targetUserId);
-        } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException
-                | IOException e) {
+            mJavaKeyStore.deleteEntry(PROFILE_KEY_NAME_ENCRYPT + targetUserId);
+            mJavaKeyStore.deleteEntry(PROFILE_KEY_NAME_DECRYPT + targetUserId);
+        } catch (KeyStoreException e) {
             // We have tried our best to remove all keys
             Slog.e(TAG, "Unable to remove keystore profile key for user:" + targetUserId, e);
         }
@@ -3257,6 +3289,12 @@
         pw.println();
         pw.decreaseIndent();
 
+        pw.println("Keys in namespace:");
+        pw.increaseIndent();
+        dumpKeystoreKeys(pw);
+        pw.println();
+        pw.decreaseIndent();
+
         pw.println("Storage:");
         pw.increaseIndent();
         mStorage.dump(pw);
@@ -3276,6 +3314,18 @@
         pw.decreaseIndent();
     }
 
+    private void dumpKeystoreKeys(IndentingPrintWriter pw) {
+        try {
+            final Enumeration<String> aliases = mJavaKeyStore.aliases();
+            while (aliases.hasMoreElements()) {
+                pw.println(aliases.nextElement());
+            }
+        } catch (KeyStoreException e) {
+            pw.println("Unable to get keys: " + e.toString());
+            Slog.d(TAG, "Dump error", e);
+        }
+    }
+
     /**
      * Cryptographically disable escrow token support for the current user, if the user is not
      * managed (either user has a profile owner, or if device is managed). Do not disable
diff --git a/services/core/java/com/android/server/locksettings/ManagedProfilePasswordCache.java b/services/core/java/com/android/server/locksettings/ManagedProfilePasswordCache.java
index fa477c8..672c3f7 100644
--- a/services/core/java/com/android/server/locksettings/ManagedProfilePasswordCache.java
+++ b/services/core/java/com/android/server/locksettings/ManagedProfilePasswordCache.java
@@ -23,7 +23,6 @@
 import android.security.keystore.KeyGenParameterSpec;
 import android.security.keystore.KeyProperties;
 import android.security.keystore.UserNotAuthenticatedException;
-import android.security.keystore2.AndroidKeyStoreSpi;
 import android.util.Slog;
 import android.util.SparseArray;
 
@@ -95,11 +94,12 @@
             SecretKey key;
             try {
                 generator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES,
-                        AndroidKeyStoreSpi.NAME);
+                        mKeyStore.getProvider());
                 generator.init(new KeyGenParameterSpec.Builder(
                         keyName, KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
                         .setKeySize(KEY_LENGTH)
                         .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
+                        .setNamespace(SyntheticPasswordCrypto.keyNamespace())
                         .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
                         // Generate auth-bound key to user 0 (since we the caller is user 0)
                         .setUserAuthenticationRequired(true)
diff --git a/services/core/java/com/android/server/locksettings/RebootEscrowManager.java b/services/core/java/com/android/server/locksettings/RebootEscrowManager.java
index 90694d0..3f2b8ff 100644
--- a/services/core/java/com/android/server/locksettings/RebootEscrowManager.java
+++ b/services/core/java/com/android/server/locksettings/RebootEscrowManager.java
@@ -31,6 +31,7 @@
 import android.annotation.NonNull;
 import android.annotation.UserIdInt;
 import android.content.Context;
+import android.content.pm.PackageManager;
 import android.content.pm.UserInfo;
 import android.os.Handler;
 import android.os.SystemClock;
@@ -224,6 +225,12 @@
         }
 
         public boolean serverBasedResumeOnReboot() {
+            // Always use the server based RoR if the HAL isn't installed on device.
+            if (!mContext.getPackageManager().hasSystemFeature(
+                    PackageManager.FEATURE_REBOOT_ESCROW)) {
+                return true;
+            }
+
             return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_OTA,
                     "server_based_ror_enabled", false);
         }
@@ -374,6 +381,7 @@
         try {
             escrowKey = getAndClearRebootEscrowKey(kk);
         } catch (IOException e) {
+            Slog.i(TAG, "Failed to load escrow key, scheduling retry.", e);
             scheduleLoadRebootEscrowDataOrFail(retryHandler, attemptNumber + 1, users,
                     rebootEscrowUsers);
             return;
diff --git a/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java b/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java
index 35e6489..3386408 100644
--- a/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java
+++ b/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java
@@ -16,8 +16,12 @@
 
 package com.android.server.locksettings;
 
+import android.security.AndroidKeyStoreMaintenance;
 import android.security.keystore.KeyProperties;
 import android.security.keystore.KeyProtection;
+import android.security.keystore2.AndroidKeyStoreLoadStoreParameter;
+import android.system.keystore2.Domain;
+import android.system.keystore2.KeyDescriptor;
 import android.util.Slog;
 
 import java.io.ByteArrayOutputStream;
@@ -125,9 +129,7 @@
 
     public static byte[] decryptBlobV1(String keyAlias, byte[] blob, byte[] applicationId) {
         try {
-            KeyStore keyStore = KeyStore.getInstance(androidKeystoreProviderName());
-            keyStore.load(null);
-
+            KeyStore keyStore = getKeyStore();
             SecretKey decryptionKey = (SecretKey) keyStore.getKey(keyAlias, null);
             if (decryptionKey == null) {
                 throw new IllegalStateException("SP key is missing: " + keyAlias);
@@ -144,10 +146,20 @@
         return "AndroidKeyStore";
     }
 
+    static int keyNamespace() {
+        return KeyProperties.NAMESPACE_LOCKSETTINGS;
+    }
+
+    private static KeyStore getKeyStore()
+            throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException {
+        KeyStore keyStore = KeyStore.getInstance(androidKeystoreProviderName());
+        keyStore.load(new AndroidKeyStoreLoadStoreParameter(keyNamespace()));
+        return keyStore;
+    }
+
     public static byte[] decryptBlob(String keyAlias, byte[] blob, byte[] applicationId) {
         try {
-            KeyStore keyStore = KeyStore.getInstance(androidKeystoreProviderName());
-            keyStore.load(null);
+            final KeyStore keyStore = getKeyStore();
 
             SecretKey decryptionKey = (SecretKey) keyStore.getKey(keyAlias, null);
             if (decryptionKey == null) {
@@ -170,8 +182,7 @@
             KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES);
             keyGenerator.init(AES_KEY_LENGTH * 8, new SecureRandom());
             SecretKey secretKey = keyGenerator.generateKey();
-            KeyStore keyStore = KeyStore.getInstance(androidKeystoreProviderName());
-            keyStore.load(null);
+            final KeyStore keyStore = getKeyStore();
             KeyProtection.Builder builder = new KeyProtection.Builder(KeyProperties.PURPOSE_DECRYPT)
                     .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
                     .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
@@ -200,8 +211,7 @@
     public static void destroyBlobKey(String keyAlias) {
         KeyStore keyStore;
         try {
-            keyStore = KeyStore.getInstance(androidKeystoreProviderName());
-            keyStore.load(null);
+            keyStore = getKeyStore();
             keyStore.deleteEntry(keyAlias);
             Slog.i(TAG, "SP key deleted: " + keyAlias);
         } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException
@@ -229,4 +239,32 @@
             throw new IllegalStateException("NoSuchAlgorithmException for SHA-512", e);
         }
     }
+
+    static boolean migrateLockSettingsKey(String alias) {
+        final KeyDescriptor legacyKey = new KeyDescriptor();
+        legacyKey.domain = Domain.APP;
+        legacyKey.nspace = KeyProperties.NAMESPACE_APPLICATION;
+        legacyKey.alias = alias;
+
+        final KeyDescriptor newKey = new KeyDescriptor();
+        newKey.domain = Domain.SELINUX;
+        newKey.nspace = SyntheticPasswordCrypto.keyNamespace();
+        newKey.alias = alias;
+        Slog.i(TAG, "Migrating key " + alias);
+        int err = AndroidKeyStoreMaintenance.migrateKeyNamespace(legacyKey, newKey);
+        if (err == 0) {
+            return true;
+        } else if (err == AndroidKeyStoreMaintenance.KEY_NOT_FOUND) {
+            Slog.i(TAG, "Key does not exist");
+            // Treat this as a success so we don't migrate again.
+            return true;
+        } else if (err == AndroidKeyStoreMaintenance.INVALID_ARGUMENT) {
+            Slog.i(TAG, "Key already exists");
+            // Treat this as a success so we don't migrate again.
+            return true;
+        } else {
+            Slog.e(TAG, String.format("Failed to migrate key: %d", err));
+            return false;
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java b/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
index 6b5295f..0c182a0 100644
--- a/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
+++ b/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
@@ -519,7 +519,7 @@
     public void removeUser(int userId) {
         for (long handle : mStorage.listSyntheticPasswordHandlesForUser(SP_BLOB_NAME, userId)) {
             destroyWeaverSlot(handle, userId);
-            destroySPBlobKey(getHandleName(handle));
+            destroySPBlobKey(getKeyName(handle));
         }
     }
 
@@ -955,7 +955,7 @@
         } else {
             secret = authToken.getSyntheticPassword();
         }
-        byte[] content = createSPBlob(getHandleName(handle), secret, applicationId, sid);
+        byte[] content = createSPBlob(getKeyName(handle), secret, applicationId, sid);
         byte[] blob = new byte[content.length + 1 + 1];
         /*
          * We can upgrade from v1 to v2 because that's just a change in the way that
@@ -1137,10 +1137,10 @@
         }
         final byte[] secret;
         if (version == SYNTHETIC_PASSWORD_VERSION_V1) {
-            secret = SyntheticPasswordCrypto.decryptBlobV1(getHandleName(handle),
+            secret = SyntheticPasswordCrypto.decryptBlobV1(getKeyName(handle),
                     Arrays.copyOfRange(blob, 2, blob.length), applicationId);
         } else {
-            secret = decryptSPBlob(getHandleName(handle),
+            secret = decryptSPBlob(getKeyName(handle),
                 Arrays.copyOfRange(blob, 2, blob.length), applicationId);
         }
         if (secret == null) {
@@ -1235,7 +1235,7 @@
 
     private void destroySyntheticPassword(long handle, int userId) {
         destroyState(SP_BLOB_NAME, handle, userId);
-        destroySPBlobKey(getHandleName(handle));
+        destroySPBlobKey(getKeyName(handle));
         if (hasState(WEAVER_SLOT_NAME, handle, userId)) {
             destroyWeaverSlot(handle, userId);
         }
@@ -1351,7 +1351,7 @@
         }
     }
 
-    private String getHandleName(long handle) {
+    private String getKeyName(long handle) {
         return String.format("%s%x", LockPatternUtils.SYNTHETIC_PASSWORD_KEY_PREFIX, handle);
     }
 
@@ -1412,4 +1412,19 @@
         }
         return hexBytes;
     }
+
+    /**
+     * Migrate all existing SP keystore keys from uid 1000 app domain to LSS selinux domain
+     */
+    public boolean migrateKeyNamespace() {
+        boolean success = true;
+        final Map<Integer, List<Long>> allHandles =
+                mStorage.listSyntheticPasswordHandlesForAllUsers(SP_BLOB_NAME);
+        for (List<Long> userHandles : allHandles.values()) {
+            for (long handle : userHandles) {
+                success &= SyntheticPasswordCrypto.migrateLockSettingsKey(getKeyName(handle));
+            }
+        }
+        return success;
+    }
 }
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 1f44d25..d0da912 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -1921,7 +1921,7 @@
      * Collect all ifaces from a {@link NetworkStateSnapshot} into the given set.
      */
     private static void collectIfaces(ArraySet<String> ifaces, NetworkStateSnapshot snapshot) {
-        ifaces.addAll(snapshot.linkProperties.getAllInterfaceNames());
+        ifaces.addAll(snapshot.getLinkProperties().getAllInterfaceNames());
     }
 
     /**
@@ -1995,14 +1995,14 @@
         if (LOGV) Slog.v(TAG, "updateNetworkRulesNL()");
         Trace.traceBegin(TRACE_TAG_NETWORK, "updateNetworkRulesNL");
 
-        final List<NetworkStateSnapshot> snapshots = mConnManager.getAllNetworkStateSnapshot();
+        final List<NetworkStateSnapshot> snapshots = mConnManager.getAllNetworkStateSnapshots();
 
         // First, generate identities of all connected networks so we can
         // quickly compare them against all defined policies below.
         mNetIdToSubId.clear();
         final ArrayMap<NetworkStateSnapshot, NetworkIdentity> identified = new ArrayMap<>();
         for (final NetworkStateSnapshot snapshot : snapshots) {
-            mNetIdToSubId.put(snapshot.network.getNetId(), parseSubId(snapshot));
+            mNetIdToSubId.put(snapshot.getNetwork().getNetId(), parseSubId(snapshot));
 
             // Policies matched by NPMS only match by subscriber ID or by ssid. Thus subtype
             // in the object created here is never used and its value doesn't matter, so use
@@ -2090,7 +2090,7 @@
         // One final pass to catch any metered ifaces that don't have explicitly
         // defined policies; typically Wi-Fi networks.
         for (final NetworkStateSnapshot snapshot : snapshots) {
-            if (!snapshot.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_METERED)) {
+            if (!snapshot.getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_METERED)) {
                 matchingIfaces.clear();
                 collectIfaces(matchingIfaces, snapshot);
                 for (int j = matchingIfaces.size() - 1; j >= 0; j--) {
@@ -2126,14 +2126,14 @@
         mSubscriptionOpportunisticQuota.clear();
         for (final NetworkStateSnapshot snapshot : snapshots) {
             if (!quotaEnabled) continue;
-            if (snapshot.network == null) continue;
-            final int subId = getSubIdLocked(snapshot.network);
+            if (snapshot.getNetwork() == null) continue;
+            final int subId = getSubIdLocked(snapshot.getNetwork());
             final SubscriptionPlan plan = getPrimarySubscriptionPlanLocked(subId);
             if (plan == null) continue;
 
             final long quotaBytes;
             final long limitBytes = plan.getDataLimitBytes();
-            if (!snapshot.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_ROAMING)) {
+            if (!snapshot.getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_ROAMING)) {
                 // Clamp to 0 when roaming
                 quotaBytes = 0;
             } else if (limitBytes == SubscriptionPlan.BYTES_UNKNOWN) {
@@ -2151,7 +2151,7 @@
                         .truncatedTo(ChronoUnit.DAYS)
                         .toInstant().toEpochMilli();
                 final long totalBytes = getTotalBytes(
-                        NetworkTemplate.buildTemplateMobileAll(snapshot.subscriberId),
+                        NetworkTemplate.buildTemplateMobileAll(snapshot.getSubscriberId()),
                         start, startOfDay);
                 final long remainingBytes = limitBytes - totalBytes;
                 // Number of remaining days including current day
@@ -5770,8 +5770,8 @@
 
     private int parseSubId(@NonNull NetworkStateSnapshot snapshot) {
         int subId = INVALID_SUBSCRIPTION_ID;
-        if (snapshot.networkCapabilities.hasTransport(TRANSPORT_CELLULAR)) {
-            NetworkSpecifier spec = snapshot.networkCapabilities.getNetworkSpecifier();
+        if (snapshot.getNetworkCapabilities().hasTransport(TRANSPORT_CELLULAR)) {
+            NetworkSpecifier spec = snapshot.getNetworkCapabilities().getNetworkSpecifier();
             if (spec instanceof TelephonyNetworkSpecifier) {
                 subId = ((TelephonyNetworkSpecifier) spec).getSubscriptionId();
             }
diff --git a/services/core/java/com/android/server/net/NetworkStatsFactory.java b/services/core/java/com/android/server/net/NetworkStatsFactory.java
index d042b88..e7c0a50 100644
--- a/services/core/java/com/android/server/net/NetworkStatsFactory.java
+++ b/services/core/java/com/android/server/net/NetworkStatsFactory.java
@@ -382,8 +382,8 @@
 
         // Migrate data usage over a VPN to the TUN network.
         for (UnderlyingNetworkInfo info : vpnArray) {
-            delta.migrateTun(info.ownerUid, info.iface,
-                    info.underlyingIfaces.toArray(new String[0]));
+            delta.migrateTun(info.getOwnerUid(), info.getIface(),
+                    info.getUnderlyingIfaces());
             // Filter out debug entries as that may lead to over counting.
             delta.filterDebugEntries();
         }
diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java
index 19f5e3c..3c14440 100644
--- a/services/core/java/com/android/server/net/NetworkStatsService.java
+++ b/services/core/java/com/android/server/net/NetworkStatsService.java
@@ -24,7 +24,6 @@
 import static android.content.Intent.ACTION_USER_REMOVED;
 import static android.content.Intent.EXTRA_UID;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
-import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
 import static android.net.NetworkIdentity.SUBTYPE_COMBINED;
 import static android.net.NetworkStack.checkNetworkStackPermission;
 import static android.net.NetworkStats.DEFAULT_NETWORK_ALL;
@@ -97,12 +96,12 @@
 import android.net.Network;
 import android.net.NetworkCapabilities;
 import android.net.NetworkIdentity;
+import android.net.NetworkSpecifier;
 import android.net.NetworkStack;
 import android.net.NetworkStateSnapshot;
 import android.net.NetworkStats;
 import android.net.NetworkStats.NonMonotonicObserver;
 import android.net.NetworkStatsHistory;
-import android.net.NetworkSpecifier;
 import android.net.NetworkTemplate;
 import android.net.TelephonyNetworkSpecifier;
 import android.net.TrafficStats;
@@ -1296,9 +1295,9 @@
         final ArraySet<String> mobileIfaces = new ArraySet<>();
         for (NetworkStateSnapshot snapshot : snapshots) {
             final int displayTransport =
-                    getDisplayTransport(snapshot.networkCapabilities.getTransportTypes());
+                    getDisplayTransport(snapshot.getNetworkCapabilities().getTransportTypes());
             final boolean isMobile = (NetworkCapabilities.TRANSPORT_CELLULAR == displayTransport);
-            final boolean isDefault = ArrayUtils.contains(mDefaultNetworks, snapshot.network);
+            final boolean isDefault = ArrayUtils.contains(mDefaultNetworks, snapshot.getNetwork());
             final int subType = combineSubtypeEnabled ? SUBTYPE_COMBINED
                     : getSubTypeForStateSnapshot(snapshot);
             final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, snapshot,
@@ -1306,7 +1305,7 @@
 
             // Traffic occurring on the base interface is always counted for
             // both total usage and UID details.
-            final String baseIface = snapshot.linkProperties.getInterfaceName();
+            final String baseIface = snapshot.getLinkProperties().getInterfaceName();
             if (baseIface != null) {
                 findOrCreateNetworkIdentitySet(mActiveIfaces, baseIface).add(ident);
                 findOrCreateNetworkIdentitySet(mActiveUidIfaces, baseIface).add(ident);
@@ -1316,7 +1315,7 @@
                 // If IMS is metered, then the IMS network usage has already included VT usage.
                 // VT is considered always metered in framework's layer. If VT is not metered
                 // per carrier's policy, modem will report 0 usage for VT calls.
-                if (snapshot.networkCapabilities.hasCapability(
+                if (snapshot.getNetworkCapabilities().hasCapability(
                         NetworkCapabilities.NET_CAPABILITY_IMS) && !ident.getMetered()) {
 
                     // Copy the identify from IMS one but mark it as metered.
@@ -1364,7 +1363,7 @@
             // accounting is explicitly bypassed for traffic from the clat uid.
             //
             // TODO: This code might be combined to above code.
-            for (String iface : snapshot.linkProperties.getAllInterfaceNames()) {
+            for (String iface : snapshot.getLinkProperties().getAllInterfaceNames()) {
                 // baseIface has been handled, so ignore it.
                 if (TextUtils.equals(baseIface, iface)) continue;
                 if (iface != null) {
@@ -1383,11 +1382,11 @@
     }
 
     private static int getSubIdForMobile(@NonNull NetworkStateSnapshot state) {
-        if (!state.networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
+        if (!state.getNetworkCapabilities().hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
             throw new IllegalArgumentException("Mobile state need capability TRANSPORT_CELLULAR");
         }
 
-        final NetworkSpecifier spec = state.networkCapabilities.getNetworkSpecifier();
+        final NetworkSpecifier spec = state.getNetworkCapabilities().getNetworkSpecifier();
         if (spec instanceof TelephonyNetworkSpecifier) {
              return ((TelephonyNetworkSpecifier) spec).getSubscriptionId();
         } else {
@@ -1402,11 +1401,11 @@
      * transport types do not actually fill this value.
      */
     private int getSubTypeForStateSnapshot(@NonNull NetworkStateSnapshot state) {
-        if (!state.networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
+        if (!state.getNetworkCapabilities().hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
             return 0;
         }
 
-        return mNetworkStatsSubscriptionsMonitor.getRatTypeForSubscriberId(state.subscriberId);
+        return mNetworkStatsSubscriptionsMonitor.getRatTypeForSubscriberId(state.getSubscriberId());
     }
 
     private static <K> NetworkIdentitySet findOrCreateNetworkIdentitySet(
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index c01a115..29c3dd9 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -6850,7 +6850,7 @@
                                     .appendPath(record.getKey()).build())
                             .addFlags(Intent.FLAG_RECEIVER_FOREGROUND)
                             .putExtra(EXTRA_KEY, record.getKey()),
-                    PendingIntent.FLAG_UPDATE_CURRENT);
+                    PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
             mAlarmManager.setExactAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME_WAKEUP,
                     mSystemClock.elapsedRealtime() + record.getNotification().getTimeoutAfter(),
                     pi);
@@ -7713,6 +7713,21 @@
             int rank, int count, boolean wasPosted, String listenerName) {
         final String canceledKey = r.getKey();
 
+        // Get pending intent used to create alarm, use FLAG_NO_CREATE if PendingIntent
+        // does not already exist, then null will be returned.
+        final PendingIntent pi = PendingIntent.getBroadcast(getContext(),
+                REQUEST_CODE_TIMEOUT,
+                new Intent(ACTION_NOTIFICATION_TIMEOUT)
+                        .setData(new Uri.Builder().scheme(SCHEME_TIMEOUT)
+                                .appendPath(r.getKey()).build())
+                        .addFlags(Intent.FLAG_RECEIVER_FOREGROUND),
+                PendingIntent.FLAG_NO_CREATE | PendingIntent.FLAG_IMMUTABLE);
+
+        // Cancel alarm corresponding to pi.
+        if (pi != null) {
+            mAlarmManager.cancel(pi);
+        }
+
         // Record caller.
         recordCallerLocked(r);
 
diff --git a/services/core/java/com/android/server/notification/SnoozeHelper.java b/services/core/java/com/android/server/notification/SnoozeHelper.java
index 9a9e733..da472be 100644
--- a/services/core/java/com/android/server/notification/SnoozeHelper.java
+++ b/services/core/java/com/android/server/notification/SnoozeHelper.java
@@ -37,6 +37,7 @@
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.internal.util.XmlUtils;
+import com.android.server.pm.PackageManagerService;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -463,6 +464,7 @@
         return PendingIntent.getBroadcast(mContext,
                 REQUEST_CODE_REPOST,
                 new Intent(REPOST_ACTION)
+                        .setPackage(PackageManagerService.PLATFORM_PACKAGE_NAME)
                         .setData(new Uri.Builder().scheme(REPOST_SCHEME).appendPath(key).build())
                         .addFlags(Intent.FLAG_RECEIVER_FOREGROUND)
                         .putExtra(EXTRA_KEY, key)
diff --git a/services/core/java/com/android/server/pm/ApexManager.java b/services/core/java/com/android/server/pm/ApexManager.java
index c6a55b4..cb0af11 100644
--- a/services/core/java/com/android/server/pm/ApexManager.java
+++ b/services/core/java/com/android/server/pm/ApexManager.java
@@ -25,6 +25,7 @@
 import android.apex.ApexInfoList;
 import android.apex.ApexSessionInfo;
 import android.apex.ApexSessionParams;
+import android.apex.CompressedApexInfoList;
 import android.apex.IApexService;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
@@ -357,6 +358,21 @@
     public abstract void markBootCompleted();
 
     /**
+     * Estimate how much storage space is needed on /data/ for decompressing apexes
+     * @param infoList List of apexes that are compressed in target build.
+     * @return Size, in bytes, the amount of space needed on /data/
+     */
+    public abstract long calculateSizeForCompressedApex(CompressedApexInfoList infoList)
+            throws RemoteException;
+
+    /**
+     * Reserve space on /data so that apexes can be decompressed after OTA
+     * @param infoList List of apexes that are compressed in target build.
+     */
+    public abstract void reserveSpaceForCompressedApex(CompressedApexInfoList infoList)
+            throws RemoteException;
+
+    /**
      * Dumps various state information to the provided {@link PrintWriter} object.
      *
      * @param pw the {@link PrintWriter} object to send information to.
@@ -898,6 +914,18 @@
             }
         }
 
+        @Override
+        public long calculateSizeForCompressedApex(CompressedApexInfoList infoList)
+                throws RemoteException {
+            return waitForApexService().calculateSizeForCompressedApex(infoList);
+        }
+
+        @Override
+        public void reserveSpaceForCompressedApex(CompressedApexInfoList infoList)
+                throws RemoteException {
+            waitForApexService().reserveSpaceForCompressedApex(infoList);
+        }
+
         /**
          * Dump information about the packages contained in a particular cache
          * @param packagesCache the cache to print information about.
@@ -1150,6 +1178,16 @@
         }
 
         @Override
+        public long calculateSizeForCompressedApex(CompressedApexInfoList infoList) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public void reserveSpaceForCompressedApex(CompressedApexInfoList infoList) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
         void dump(PrintWriter pw, String packageName) {
             // No-op
         }
diff --git a/services/core/java/com/android/server/pm/BackgroundDexOptService.java b/services/core/java/com/android/server/pm/BackgroundDexOptService.java
index acec93c..77c1c1d 100644
--- a/services/core/java/com/android/server/pm/BackgroundDexOptService.java
+++ b/services/core/java/com/android/server/pm/BackgroundDexOptService.java
@@ -16,7 +16,6 @@
 
 package com.android.server.pm;
 
-import static com.android.server.pm.PackageManagerService.DEBUG_DEXOPT;
 import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
 
 import android.annotation.Nullable;
@@ -24,12 +23,13 @@
 import android.app.job.JobParameters;
 import android.app.job.JobScheduler;
 import android.app.job.JobService;
+import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.PackageInfo;
-import android.os.BatteryManager;
+import android.os.BatteryManagerInternal;
 import android.os.Environment;
 import android.os.ServiceManager;
 import android.os.SystemProperties;
@@ -37,6 +37,7 @@
 import android.os.storage.StorageManager;
 import android.util.ArraySet;
 import android.util.Log;
+import android.util.Slog;
 
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.FrameworkStatsLog;
@@ -65,9 +66,7 @@
     private static final int JOB_IDLE_OPTIMIZE = 800;
     private static final int JOB_POST_BOOT_UPDATE = 801;
 
-    private static final long IDLE_OPTIMIZATION_PERIOD = DEBUG
-            ? TimeUnit.MINUTES.toMillis(1)
-            : TimeUnit.DAYS.toMillis(1);
+    private static final long IDLE_OPTIMIZATION_PERIOD = TimeUnit.DAYS.toMillis(1);
 
     private static ComponentName sDexoptServiceName = new ComponentName(
             "android",
@@ -115,14 +114,24 @@
             return;
         }
 
-        JobScheduler js = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
+        final JobScheduler js = context.getSystemService(JobScheduler.class);
 
         // Schedule a one-off job which scans installed packages and updates
-        // out-of-date oat files.
-        js.schedule(new JobInfo.Builder(JOB_POST_BOOT_UPDATE, sDexoptServiceName)
-                    .setMinimumLatency(TimeUnit.MINUTES.toMillis(1))
-                    .setOverrideDeadline(TimeUnit.MINUTES.toMillis(1))
-                    .build());
+        // out-of-date oat files. Schedule it 10 minutes after the boot complete event,
+        // so that we don't overload the boot with additional dex2oat compilations.
+        context.registerReceiver(new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                js.schedule(new JobInfo.Builder(JOB_POST_BOOT_UPDATE, sDexoptServiceName)
+                        .setMinimumLatency(TimeUnit.MINUTES.toMillis(10))
+                        .setOverrideDeadline(TimeUnit.MINUTES.toMillis(60))
+                        .build());
+                context.unregisterReceiver(this);
+                if (DEBUG) {
+                    Slog.i(TAG, "BootBgDexopt scheduled");
+                }
+            }
+        }, new IntentFilter(Intent.ACTION_BOOT_COMPLETED));
 
         // Schedule a daily job which scans installed packages and compiles
         // those with fresh profiling data.
@@ -132,8 +141,8 @@
                     .setPeriodic(IDLE_OPTIMIZATION_PERIOD)
                     .build());
 
-        if (DEBUG_DEXOPT) {
-            Log.i(TAG, "Jobs scheduled");
+        if (DEBUG) {
+            Slog.d(TAG, "BgDexopt scheduled");
         }
     }
 
@@ -149,32 +158,11 @@
         }
     }
 
-    // Returns the current battery level as a 0-100 integer.
-    private int getBatteryLevel() {
-        IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
-        Intent intent = registerReceiver(null, filter);
-        int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
-        int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
-        boolean present = intent.getBooleanExtra(BatteryManager.EXTRA_PRESENT, true);
-
-        if (!present) {
-            // No battery, treat as if 100%, no possibility of draining battery.
-            return 100;
-        }
-
-        if (level < 0 || scale <= 0) {
-            // Battery data unavailable. This should never happen, so assume the worst.
-            return 0;
-        }
-
-        return (100 * level / scale);
-    }
-
     private long getLowStorageThreshold(Context context) {
         @SuppressWarnings("deprecation")
         final long lowThreshold = StorageManager.from(context).getStorageLowBytes(mDataDir);
         if (lowThreshold == 0) {
-            Log.e(TAG, "Invalid low storage threshold");
+            Slog.e(TAG, "Invalid low storage threshold");
         }
 
         return lowThreshold;
@@ -198,9 +186,8 @@
 
     private void postBootUpdate(JobParameters jobParams, PackageManagerService pm,
             ArraySet<String> pkgs) {
-        // Load low battery threshold from the system config. This is a 0-100 integer.
-        final int lowBatteryThreshold = getResources().getInteger(
-                com.android.internal.R.integer.config_lowBatteryWarningLevel);
+        final BatteryManagerInternal batteryManagerInternal =
+                LocalServices.getService(BatteryManagerInternal.class);
         final long lowThreshold = getLowStorageThreshold(this);
 
         mAbortPostBootUpdate.set(false);
@@ -215,20 +202,19 @@
                 // Different job, which supersedes this one, is running.
                 break;
             }
-            if (getBatteryLevel() < lowBatteryThreshold) {
+            if (batteryManagerInternal.getBatteryLevelLow()) {
                 // Rather bail than completely drain the battery.
                 break;
             }
             long usableSpace = mDataDir.getUsableSpace();
             if (usableSpace < lowThreshold) {
                 // Rather bail than completely fill up the disk.
-                Log.w(TAG, "Aborting background dex opt job due to low storage: " +
+                Slog.w(TAG, "Aborting background dex opt job due to low storage: " +
                         usableSpace);
                 break;
             }
-
-            if (DEBUG_DEXOPT) {
-                Log.i(TAG, "Updating package " + pkg);
+            if (DEBUG) {
+                Slog.i(TAG, "Updating package " + pkg);
             }
 
             // Update package if needed. Note that there can be no race between concurrent
@@ -260,13 +246,13 @@
             public void run() {
                 int result = idleOptimization(pm, pkgs, BackgroundDexOptService.this);
                 if (result == OPTIMIZE_PROCESSED) {
-                    Log.i(TAG, "Idle optimizations completed.");
+                    Slog.i(TAG, "Idle optimizations completed.");
                 } else if (result == OPTIMIZE_ABORT_NO_SPACE_LEFT) {
-                    Log.w(TAG, "Idle optimizations aborted because of space constraints.");
+                    Slog.w(TAG, "Idle optimizations aborted because of space constraints.");
                 } else if (result == OPTIMIZE_ABORT_BY_JOB_SCHEDULER) {
-                    Log.w(TAG, "Idle optimizations aborted by job scheduler.");
+                    Slog.w(TAG, "Idle optimizations aborted by job scheduler.");
                 } else {
-                    Log.w(TAG, "Idle optimizations ended with unexpected code: " + result);
+                    Slog.w(TAG, "Idle optimizations ended with unexpected code: " + result);
                 }
                 if (result != OPTIMIZE_ABORT_BY_JOB_SCHEDULER) {
                     // Abandon our timeslice and do not reschedule.
@@ -280,7 +266,7 @@
     // Optimize the given packages and return the optimization result (one of the OPTIMIZE_* codes).
     private int idleOptimization(PackageManagerService pm, ArraySet<String> pkgs,
             Context context) {
-        Log.i(TAG, "Performing idle optimizations");
+        Slog.i(TAG, "Performing idle optimizations");
         // If post-boot update is still running, request that it exits early.
         mExitPostBootUpdate.set(true);
         mAbortIdleOptimization.set(false);
@@ -355,11 +341,15 @@
             final long lowStorageThresholdForDowngrade = LOW_THRESHOLD_MULTIPLIER_FOR_DOWNGRADE
                     * lowStorageThreshold;
             boolean shouldDowngrade = shouldDowngrade(lowStorageThresholdForDowngrade);
-            Log.d(TAG, "Should Downgrade " + shouldDowngrade);
+            if (DEBUG) {
+                Slog.d(TAG, "Should Downgrade " + shouldDowngrade);
+            }
             if (shouldDowngrade) {
                 Set<String> unusedPackages =
                         pm.getUnusedPackages(mDowngradeUnusedAppsThresholdInMillis);
-                Log.d(TAG, "Unsused Packages " +  String.join(",", unusedPackages));
+                if (DEBUG) {
+                    Slog.d(TAG, "Unsused Packages " +  String.join(",", unusedPackages));
+                }
 
                 if (!unusedPackages.isEmpty()) {
                     for (String pkg : unusedPackages) {
@@ -431,7 +421,9 @@
      */
     private boolean downgradePackage(PackageManagerService pm, String pkg,
             boolean isForPrimaryDex) {
-        Log.d(TAG, "Downgrading " + pkg);
+        if (DEBUG) {
+            Slog.d(TAG, "Downgrading " + pkg);
+        }
         boolean dex_opt_performed = false;
         int reason = PackageManagerService.REASON_INACTIVE_PACKAGE_DOWNGRADE;
         int dexoptFlags = DexoptOptions.DEXOPT_BOOT_COMPLETE
@@ -553,7 +545,7 @@
         long usableSpace = mDataDir.getUsableSpace();
         if (usableSpace < lowStorageThreshold) {
             // Rather bail than completely fill up the disk.
-            Log.w(TAG, "Aborting background dex opt job due to low storage: " + usableSpace);
+            Slog.w(TAG, "Aborting background dex opt job due to low storage: " + usableSpace);
             return OPTIMIZE_ABORT_NO_SPACE_LEFT;
         }
 
@@ -592,8 +584,8 @@
 
     @Override
     public boolean onStartJob(JobParameters params) {
-        if (DEBUG_DEXOPT) {
-            Log.i(TAG, "onStartJob");
+        if (DEBUG) {
+            Slog.i(TAG, "onStartJob");
         }
 
         // NOTE: PackageManagerService.isStorageLow uses a different set of criteria from
@@ -601,17 +593,13 @@
         // restart with a period of ~1 minute.
         PackageManagerService pm = (PackageManagerService)ServiceManager.getService("package");
         if (pm.isStorageLow()) {
-            if (DEBUG_DEXOPT) {
-                Log.i(TAG, "Low storage, skipping this run");
-            }
+            Slog.i(TAG, "Low storage, skipping this run");
             return false;
         }
 
         final ArraySet<String> pkgs = pm.getOptimizablePackages();
         if (pkgs.isEmpty()) {
-            if (DEBUG_DEXOPT) {
-                Log.i(TAG, "No packages to optimize");
-            }
+            Slog.i(TAG, "No packages to optimize");
             return false;
         }
 
@@ -627,8 +615,8 @@
 
     @Override
     public boolean onStopJob(JobParameters params) {
-        if (DEBUG_DEXOPT) {
-            Log.i(TAG, "onStopJob");
+        if (DEBUG) {
+            Slog.d(TAG, "onStopJob");
         }
 
         if (params.getJobId() == JOB_POST_BOOT_UPDATE) {
@@ -649,7 +637,7 @@
     private void notifyPinService(ArraySet<String> updatedPackages) {
         PinnerService pinnerService = LocalServices.getService(PinnerService.class);
         if (pinnerService != null) {
-            Log.i(TAG, "Pinning optimized code " + updatedPackages);
+            Slog.i(TAG, "Pinning optimized code " + updatedPackages);
             pinnerService.update(updatedPackages, false /* force */);
         }
     }
@@ -684,7 +672,7 @@
         final String sysPropKey = "pm.dexopt.downgrade_after_inactive_days";
         String sysPropValue = SystemProperties.get(sysPropKey);
         if (sysPropValue == null || sysPropValue.isEmpty()) {
-            Log.w(TAG, "SysProp " + sysPropKey + " not set");
+            Slog.w(TAG, "SysProp " + sysPropKey + " not set");
             return Long.MAX_VALUE;
         }
         return TimeUnit.DAYS.toMillis(Long.parseLong(sysPropValue));
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 48fee0b..0d06426 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -9962,6 +9962,8 @@
     public boolean performDexOptMode(String packageName,
             boolean checkProfiles, String targetCompilerFilter, boolean force,
             boolean bootComplete, String splitName) {
+        enforceSystemOrRootOrShell("performDexOptMode");
+
         int flags = (checkProfiles ? DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES : 0) |
                 (force ? DexoptOptions.DEXOPT_FORCE : 0) |
                 (bootComplete ? DexoptOptions.DEXOPT_BOOT_COMPLETE : 0);
@@ -12528,6 +12530,7 @@
                     if (hasOldPkg) {
                         mPermissionManager.revokeRuntimePermissionsIfGroupChanged(pkg, oldPkg,
                                 allPackageNames);
+                        mPermissionManager.revokeStoragePermissionsIfScopeExpanded(pkg, oldPkg);
                     }
                     if (hasPermissionDefinitionChanges) {
                         mPermissionManager.revokeRuntimePermissionsIfPermissionDefinitionChanged(
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index 3ffca02..b500e16 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -206,6 +206,9 @@
     private static final int USER_PERMISSION_FLAGS = FLAG_PERMISSION_USER_SET
             | FLAG_PERMISSION_USER_FIXED;
 
+    /** All storage permissions */
+    private static final List<String> STORAGE_PERMISSIONS = new ArrayList<>();
+
     /** If the permission of the value is granted, so is the key */
     private static final Map<String, String> FULLER_PERMISSION_MAP = new HashMap<>();
 
@@ -214,6 +217,9 @@
                 Manifest.permission.ACCESS_FINE_LOCATION);
         FULLER_PERMISSION_MAP.put(Manifest.permission.INTERACT_ACROSS_USERS,
                 Manifest.permission.INTERACT_ACROSS_USERS_FULL);
+        STORAGE_PERMISSIONS.add(Manifest.permission.READ_EXTERNAL_STORAGE);
+        STORAGE_PERMISSIONS.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
+        STORAGE_PERMISSIONS.add(Manifest.permission.ACCESS_MEDIA_LOCATION);
     }
 
     /** Lock to protect internal data access */
@@ -2266,6 +2272,49 @@
     }
 
     /**
+     * If the app is updated, and has scoped storage permissions, then it is possible that the
+     * app updated in an attempt to get unscoped storage. If so, revoke all storage permissions.
+     * @param newPackage The new package that was installed
+     * @param oldPackage The old package that was updated
+     */
+    private void revokeStoragePermissionsIfScopeExpanded(
+            @NonNull AndroidPackage newPackage,
+            @NonNull AndroidPackage oldPackage,
+            @NonNull PermissionCallback permissionCallback) {
+        boolean downgradedSdk = oldPackage.getTargetSdkVersion() >= Build.VERSION_CODES.Q
+                && newPackage.getTargetSdkVersion() < Build.VERSION_CODES.Q;
+        boolean upgradedSdk = oldPackage.getTargetSdkVersion() < Build.VERSION_CODES.Q
+                && newPackage.getTargetSdkVersion() >= Build.VERSION_CODES.Q;
+        boolean newlyRequestsLegacy = !upgradedSdk && !oldPackage.isRequestLegacyExternalStorage()
+                && newPackage.isRequestLegacyExternalStorage();
+
+        if (!newlyRequestsLegacy && !downgradedSdk) {
+            return;
+        }
+
+        final int callingUid = Binder.getCallingUid();
+        final int userId = UserHandle.getUserId(newPackage.getUid());
+        int numRequestedPermissions = newPackage.getRequestedPermissions().size();
+        for (int i = 0; i < numRequestedPermissions; i++) {
+            PermissionInfo permInfo = getPermissionInfo(newPackage.getRequestedPermissions().get(i),
+                    newPackage.getPackageName(), 0);
+            if (permInfo == null || !STORAGE_PERMISSIONS.contains(permInfo.name)) {
+                continue;
+            }
+
+            EventLog.writeEvent(0x534e4554, "171430330", newPackage.getUid(),
+                    "Revoking permission " + permInfo.name + " from package "
+                            + newPackage.getPackageName() + " as either the sdk downgraded "
+                            + downgradedSdk + " or newly requested legacy full storage "
+                            + newlyRequestsLegacy);
+
+            revokeRuntimePermissionInternal(permInfo.name, newPackage.getPackageName(),
+                    false, callingUid, userId, null, permissionCallback);
+        }
+
+    }
+
+    /**
      * We might auto-grant permissions if any permission of the group is already granted. Hence if
      * the group of a granted permission changes we need to revoke it to avoid having permissions of
      * the new group auto-granted.
@@ -4734,6 +4783,19 @@
                 @UserIdInt int userId) {
             return PermissionManagerService.this.isPermissionsReviewRequired(pkg, userId);
         }
+        /**
+         * If the app is updated, and has scoped storage permissions, then it is possible that the
+         * app updated in an attempt to get unscoped storage. If so, revoke all storage permissions.
+         * @param newPackage The new package that was installed
+         * @param oldPackage The old package that was updated
+         */
+        public void revokeStoragePermissionsIfScopeExpanded(
+                @NonNull AndroidPackage newPackage,
+                @NonNull AndroidPackage oldPackage
+        ) {
+            PermissionManagerService.this.revokeStoragePermissionsIfScopeExpanded(newPackage,
+                    oldPackage, mDefaultPermissionCallback);
+        }
 
         @Override
         public void revokeRuntimePermissionsIfGroupChanged(
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java
index 393e852..a8e842f 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java
@@ -266,6 +266,17 @@
             @NonNull ArrayList<String> allPackageNames);
 
     /**
+     * If the app is updated, and has scoped storage permissions, then it is possible that the
+     * app updated in an attempt to get unscoped storage. If so, revoke all storage permissions.
+     * @param newPackage The new package that was installed
+     * @param oldPackage The old package that was updated
+     */
+    public abstract void revokeStoragePermissionsIfScopeExpanded(
+            @NonNull AndroidPackage newPackage,
+            @NonNull AndroidPackage oldPackage
+    );
+
+    /**
      * Add all permissions in the given package.
      * <p>
      * NOTE: argument {@code groupTEMP} is temporary until mPermissionGroups is moved to
diff --git a/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java b/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java
index 24337f3..ed4a7bf 100644
--- a/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java
+++ b/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java
@@ -24,10 +24,14 @@
 import static android.os.RecoverySystem.RESUME_ON_REBOOT_REBOOT_ERROR_UNSPECIFIED;
 import static android.os.RecoverySystem.ResumeOnRebootRebootErrorCode;
 import static android.os.UserHandle.USER_SYSTEM;
+import static android.ota.nano.OtaPackageMetadata.ApexMetadata;
 
 import static com.android.internal.widget.LockSettingsInternal.ARM_REBOOT_ERROR_NONE;
+import static com.android.internal.widget.LockSettingsInternal.ARM_REBOOT_ERROR_NO_PROVIDER;
 
 import android.annotation.IntDef;
+import android.apex.CompressedApexInfo;
+import android.apex.CompressedApexInfoList;
 import android.content.Context;
 import android.content.IntentSender;
 import android.content.SharedPreferences;
@@ -47,9 +51,11 @@
 import android.os.ShellCallback;
 import android.os.SystemProperties;
 import android.provider.DeviceConfig;
+import android.sysprop.ApexProperties;
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.FastImmutableArraySet;
+import android.util.Log;
 import android.util.Slog;
 
 import com.android.internal.annotations.GuardedBy;
@@ -59,6 +65,7 @@
 import com.android.internal.widget.RebootEscrowListener;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
+import com.android.server.pm.ApexManager;
 
 import libcore.io.IoUtils;
 
@@ -68,9 +75,13 @@
 import java.io.FileDescriptor;
 import java.io.FileWriter;
 import java.io.IOException;
+import java.io.InputStream;
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
 
 /**
  * The recovery system service is responsible for coordinating recovery related
@@ -388,7 +399,13 @@
 
     @VisibleForTesting
     void onSystemServicesReady() {
-        mInjector.getLockSettingsService().setRebootEscrowListener(this);
+        LockSettingsInternal lockSettings = mInjector.getLockSettingsService();
+        if (lockSettings == null) {
+            Slog.e(TAG, "Failed to get lock settings service, skipping set"
+                    + " RebootEscrowListener");
+            return;
+        }
+        lockSettings.setRebootEscrowListener(this);
     }
 
     @Override // Binder call
@@ -554,12 +571,18 @@
             case ROR_NEED_PREPARATION:
                 final long origId = Binder.clearCallingIdentity();
                 try {
-                    boolean result = mInjector.getLockSettingsService().prepareRebootEscrow();
-                    // Clear the RoR preparation state if lock settings reports an failure.
-                    if (!result) {
-                        clearRoRPreparationState();
+                    LockSettingsInternal lockSettings = mInjector.getLockSettingsService();
+                    if (lockSettings == null) {
+                        Slog.e(TAG, "Failed to get lock settings service, skipping"
+                                + " prepareRebootEscrow");
+                        return false;
                     }
-                    return result;
+                    // Clear the RoR preparation state if lock settings reports an failure.
+                    if (!lockSettings.prepareRebootEscrow()) {
+                        clearRoRPreparationState();
+                        return false;
+                    }
+                    return true;
                 } finally {
                     Binder.restoreCallingIdentity(origId);
                 }
@@ -674,7 +697,14 @@
             case ROR_REQUESTED_NEED_CLEAR:
                 final long origId = Binder.clearCallingIdentity();
                 try {
-                    return mInjector.getLockSettingsService().clearRebootEscrow();
+                    LockSettingsInternal lockSettings = mInjector.getLockSettingsService();
+                    if (lockSettings == null) {
+                        Slog.e(TAG, "Failed to get lock settings service, skipping"
+                                + " clearRebootEscrow");
+                        return false;
+                    }
+
+                    return lockSettings.clearRebootEscrow();
                 } finally {
                     Binder.restoreCallingIdentity(origId);
                 }
@@ -768,7 +798,15 @@
         final long origId = Binder.clearCallingIdentity();
         int providerErrorCode;
         try {
-            providerErrorCode = mInjector.getLockSettingsService().armRebootEscrow();
+            LockSettingsInternal lockSettings = mInjector.getLockSettingsService();
+            if (lockSettings == null) {
+                Slog.e(TAG, "Failed to get lock settings service, skipping"
+                        + " armRebootEscrow");
+                return new RebootPreparationError(
+                        RESUME_ON_REBOOT_REBOOT_ERROR_PROVIDER_PREPARATION_FAILURE,
+                        ARM_REBOOT_ERROR_NO_PROVIDER);
+            }
+            providerErrorCode = lockSettings.armRebootEscrow();
         } finally {
             Binder.restoreCallingIdentity(origId);
         }
@@ -871,6 +909,76 @@
         return rebootWithLskfImpl(packageName, reason, slotSwitch);
     }
 
+    public static boolean isUpdatableApexSupported() {
+        return ApexProperties.updatable().orElse(false);
+    }
+
+    // Metadata should be no more than few MB, if it's larger than 100MB something is wrong.
+    private static final long APEX_INFO_SIZE_LIMIT = 24 * 1024 * 100;
+
+    private static CompressedApexInfoList getCompressedApexInfoList(String packageFile)
+            throws IOException {
+        try (ZipFile zipFile = new ZipFile(packageFile)) {
+            final ZipEntry entry = zipFile.getEntry("apex_info.pb");
+            if (entry == null) {
+                return null;
+            }
+            if (entry.getSize() >= APEX_INFO_SIZE_LIMIT) {
+                throw new IllegalArgumentException("apex_info.pb has size "
+                        + entry.getSize()
+                        + " which is larger than the permitted limit" + APEX_INFO_SIZE_LIMIT);
+            }
+            if (entry.getSize() == 0) {
+                CompressedApexInfoList infoList = new CompressedApexInfoList();
+                infoList.apexInfos = new CompressedApexInfo[0];
+                return infoList;
+            }
+            Log.i(TAG, "Allocating " + entry.getSize()
+                    + " bytes of memory to store OTA Metadata");
+            byte[] data = new byte[(int) entry.getSize()];
+
+            try (InputStream is = zipFile.getInputStream(entry)) {
+                int bytesRead = is.read(data);
+                String msg = "Read " + bytesRead + " when expecting " + data.length;
+                Log.e(TAG, msg);
+                if (bytesRead != data.length) {
+                    throw new IOException(msg);
+                }
+            }
+            ApexMetadata metadata = ApexMetadata.parseFrom(data);
+            CompressedApexInfoList apexInfoList = new CompressedApexInfoList();
+            apexInfoList.apexInfos =
+                    Arrays.stream(metadata.apexInfo).filter(apex -> apex.isCompressed).map(apex -> {
+                        CompressedApexInfo info = new CompressedApexInfo();
+                        info.moduleName = apex.packageName;
+                        info.decompressedSize = apex.decompressedSize;
+                        info.versionCode = apex.version;
+                        return info;
+                    }).toArray(CompressedApexInfo[]::new);
+            return apexInfoList;
+        }
+    }
+
+    @Override
+    public boolean allocateSpaceForUpdate(String packageFile) {
+        if (!isUpdatableApexSupported()) {
+            Log.i(TAG, "Updatable Apex not supported, "
+                    + "allocateSpaceForUpdate does nothing.");
+            return true;
+        }
+        try {
+            CompressedApexInfoList apexInfoList = getCompressedApexInfoList(packageFile);
+            ApexManager apexManager = ApexManager.getInstance();
+            apexManager.reserveSpaceForCompressedApex(apexInfoList);
+            return true;
+        } catch (RemoteException e) {
+            e.rethrowAsRuntimeException();
+        } catch (IOException | UnsupportedOperationException e) {
+            Slog.e(TAG, "Failed to reserve space for compressed apex: ", e);
+        }
+        return false;
+    }
+
     @Override // Binder call
     public boolean isLskfCaptured(String packageName) {
         enforcePermissionForResumeOnReboot();
diff --git a/services/core/java/com/android/server/telecom/TelecomLoaderService.java b/services/core/java/com/android/server/telecom/TelecomLoaderService.java
index 52ad893..8236836 100644
--- a/services/core/java/com/android/server/telecom/TelecomLoaderService.java
+++ b/services/core/java/com/android/server/telecom/TelecomLoaderService.java
@@ -31,6 +31,7 @@
 import android.telecom.PhoneAccountHandle;
 import android.telecom.TelecomManager;
 import android.telephony.CarrierConfigManager;
+import android.telephony.SubscriptionManager;
 import android.util.IntArray;
 import android.util.Slog;
 
@@ -44,6 +45,9 @@
 import com.android.server.pm.UserManagerService;
 import com.android.server.pm.permission.PermissionManagerServiceInternal;
 
+import java.util.ArrayList;
+import java.util.List;
+
 /**
  * Starts the telecom component by binding to its ITelecomService implementation. Telecom is setup
  * to run in the system-server process so once it is loaded into memory it will stay running.
@@ -208,13 +212,23 @@
                     return null;
                 }
             }
+            SubscriptionManager subscriptionManager =
+                    mContext.getSystemService(SubscriptionManager.class);
+            if (subscriptionManager == null) {
+                return null;
+            }
             TelecomManager telecomManager =
                     (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
-            PhoneAccountHandle phoneAccount = telecomManager.getSimCallManager(userId);
-            if (phoneAccount != null) {
-                return new String[]{phoneAccount.getComponentName().getPackageName()};
+            List<String> packages = new ArrayList<>();
+            int[] subIds = subscriptionManager.getActiveSubscriptionIdList();
+            for (int subId : subIds) {
+                PhoneAccountHandle phoneAccount =
+                        telecomManager.getSimCallManagerForSubscription(subId);
+                if (phoneAccount != null) {
+                    packages.add(phoneAccount.getComponentName().getPackageName());
+                }
             }
-            return null;
+            return packages.toArray(new String[] {});
         });
     }
 
diff --git a/services/core/java/com/android/server/testharness/TestHarnessModeService.java b/services/core/java/com/android/server/testharness/TestHarnessModeService.java
index 5311369..64ca85e 100644
--- a/services/core/java/com/android/server/testharness/TestHarnessModeService.java
+++ b/services/core/java/com/android/server/testharness/TestHarnessModeService.java
@@ -286,6 +286,9 @@
     private class TestHarnessModeShellCommand extends ShellCommand {
         @Override
         public int onCommand(String cmd) {
+            if (cmd == null) {
+                return handleDefaultCommands(cmd);
+            }
             switch (cmd) {
                 case "enable":
                 case "restore":
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index ff763fc..90b095b 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -39,6 +39,7 @@
 import android.content.res.XmlResourceParser;
 import android.database.ContentObserver;
 import android.graphics.drawable.Drawable;
+import android.hardware.biometrics.BiometricManager;
 import android.hardware.biometrics.BiometricSourceType;
 import android.net.Uri;
 import android.os.Binder;
@@ -185,8 +186,6 @@
     private boolean mTrustAgentsCanRun = false;
     private int mCurrentUser = UserHandle.USER_SYSTEM;
 
-    private Authorization mAuthorizationService;
-
     public TrustManagerService(Context context) {
         super(context);
         mContext = context;
@@ -196,7 +195,6 @@
         mStrongAuthTracker = new StrongAuthTracker(context);
         mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
         mSettingsObserver = new SettingsObserver(mHandler);
-        mAuthorizationService = new Authorization();
     }
 
     @Override
@@ -698,13 +696,14 @@
         }
         if (changed) {
             dispatchDeviceLocked(userId, locked);
-
-            Authorization.onLockScreenEvent(locked, userId, null);
+            Authorization.onLockScreenEvent(locked, userId, null,
+                    getBiometricSids(userId));
             // Also update the user's profiles who have unified challenge, since they
             // share the same unlocked state (see {@link #isDeviceLocked(int)})
             for (int profileHandle : mUserManager.getEnabledProfileIds(userId)) {
                 if (mLockPatternUtils.isManagedProfileWithUnifiedChallenge(profileHandle)) {
-                    mAuthorizationService.onLockScreenEvent(locked, profileHandle, null);
+                    Authorization.onLockScreenEvent(locked, profileHandle, null,
+                            getBiometricSids(profileHandle));
                 }
             }
         }
@@ -1044,6 +1043,14 @@
         }
     }
 
+    private long[] getBiometricSids(int userId) {
+        BiometricManager biometricManager = mContext.getSystemService(BiometricManager.class);
+        if (biometricManager == null) {
+            return null;
+        }
+        return biometricManager.getAuthenticatorIds(userId);
+    }
+
     // User lifecycle
 
     @Override
@@ -1255,7 +1262,8 @@
                         mDeviceLockedForUser.put(userId, locked);
                     }
 
-                    Authorization.onLockScreenEvent(locked, userId, null);
+                    Authorization.onLockScreenEvent(locked, userId, null,
+                            getBiometricSids(userId));
 
                     if (locked) {
                         try {
diff --git a/services/core/java/com/android/server/vcn/UnderlyingNetworkTracker.java b/services/core/java/com/android/server/vcn/UnderlyingNetworkTracker.java
index 8818023..3bdeec0 100644
--- a/services/core/java/com/android/server/vcn/UnderlyingNetworkTracker.java
+++ b/services/core/java/com/android/server/vcn/UnderlyingNetworkTracker.java
@@ -158,8 +158,15 @@
      * carrier owned networks may be selected, as the request specifies only subIds in the VCN's
      * subscription group, while the VCN networks are excluded by virtue of not having subIds set on
      * the VCN-exposed networks.
+     *
+     * <p>If the VCN that this UnderlyingNetworkTracker belongs to is in test-mode, this will return
+     * a NetworkRequest that only matches Test Networks.
      */
     private NetworkRequest getRouteSelectionRequest() {
+        if (mVcnContext.isInTestMode()) {
+            return getTestNetworkRequest(mLastSnapshot.getAllSubIdsInGroup(mSubscriptionGroup));
+        }
+
         return getBaseNetworkRequestBuilder()
                 .setSubscriptionIds(mLastSnapshot.getAllSubIdsInGroup(mSubscriptionGroup))
                 .build();
@@ -210,6 +217,15 @@
                 .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
     }
 
+    /** Builds and returns a NetworkRequest for the given subIds to match Test Networks. */
+    private NetworkRequest getTestNetworkRequest(@NonNull Set<Integer> subIds) {
+        return new NetworkRequest.Builder()
+                .clearCapabilities()
+                .addTransportType(NetworkCapabilities.TRANSPORT_TEST)
+                .setSubscriptionIds(subIds)
+                .build();
+    }
+
     /**
      * Update this UnderlyingNetworkTracker's TelephonySubscriptionSnapshot.
      *
diff --git a/services/core/java/com/android/server/vcn/Vcn.java b/services/core/java/com/android/server/vcn/Vcn.java
index cccb096..f918827 100644
--- a/services/core/java/com/android/server/vcn/Vcn.java
+++ b/services/core/java/com/android/server/vcn/Vcn.java
@@ -50,6 +50,7 @@
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.VcnManagementService.VcnCallback;
 import com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionSnapshot;
+import com.android.server.vcn.util.LogUtils;
 
 import java.util.Arrays;
 import java.util.Collections;
@@ -305,13 +306,13 @@
                 handleTeardown();
                 break;
             default:
-                Slog.wtf(getLogTag(), "Unknown msg.what: " + msg.what);
+                logWtf("Unknown msg.what: " + msg.what);
         }
     }
 
     private void handleConfigUpdated(@NonNull VcnConfig config) {
         // TODO: Add a dump function in VcnConfig that omits PII. Until then, use hashCode()
-        Slog.v(getLogTag(), "Config updated: config = " + config.hashCode());
+        logDbg("Config updated: old = " + mConfig.hashCode() + "; new = " + config.hashCode());
 
         mConfig = config;
 
@@ -326,8 +327,7 @@
             // connection details may have changed).
             if (!mConfig.getGatewayConnectionConfigs().contains(gatewayConnectionConfig)) {
                 if (gatewayConnection == null) {
-                    Slog.wtf(
-                            getLogTag(), "Found gatewayConnectionConfig without GatewayConnection");
+                    logWtf("Found gatewayConnectionConfig without GatewayConnection");
                 } else {
                     gatewayConnection.teardownAsynchronously();
                 }
@@ -340,6 +340,7 @@
     }
 
     private void handleTeardown() {
+        logDbg("Tearing down");
         mVcnContext.getVcnNetworkProvider().unregisterListener(mRequestListener);
 
         for (VcnGatewayConnection gatewayConnection : mVcnGatewayConnections.values()) {
@@ -350,6 +351,7 @@
     }
 
     private void handleSafeModeStatusChanged() {
+        logDbg("VcnGatewayConnection safe mode status changed");
         boolean hasSafeModeGatewayConnection = false;
 
         // If any VcnGatewayConnection is in safe mode, mark the entire VCN as being in safe mode
@@ -365,21 +367,19 @@
                 hasSafeModeGatewayConnection ? VCN_STATUS_CODE_SAFE_MODE : VCN_STATUS_CODE_ACTIVE;
         if (oldStatus != mCurrentStatus) {
             mVcnCallback.onSafeModeStatusChanged(hasSafeModeGatewayConnection);
+            logDbg(
+                    "Safe mode "
+                            + (mCurrentStatus == VCN_STATUS_CODE_SAFE_MODE ? "entered" : "exited"));
         }
     }
 
     private void handleNetworkRequested(@NonNull NetworkRequest request) {
-        Slog.v(getLogTag(), "Received request " + request);
+        logVdbg("Received request " + request);
 
         // If preexisting VcnGatewayConnection(s) satisfy request, return
         for (VcnGatewayConnectionConfig gatewayConnectionConfig : mVcnGatewayConnections.keySet()) {
             if (isRequestSatisfiedByGatewayConnectionConfig(request, gatewayConnectionConfig)) {
-                if (VDBG) {
-                    Slog.v(
-                            getLogTag(),
-                            "Request already satisfied by existing VcnGatewayConnection: "
-                                    + request);
-                }
+                logDbg("Request already satisfied by existing VcnGatewayConnection: " + request);
                 return;
             }
         }
@@ -389,13 +389,23 @@
         for (VcnGatewayConnectionConfig gatewayConnectionConfig :
                 mConfig.getGatewayConnectionConfigs()) {
             if (isRequestSatisfiedByGatewayConnectionConfig(request, gatewayConnectionConfig)) {
-                Slog.v(getLogTag(), "Bringing up new VcnGatewayConnection for request " + request);
+                logDbg("Bringing up new VcnGatewayConnection for request " + request);
 
                 if (getExposedCapabilitiesForMobileDataState(gatewayConnectionConfig).isEmpty()) {
                     // Skip; this network does not provide any services if mobile data is disabled.
                     continue;
                 }
 
+                // This should never happen, by virtue of checking for the above check for
+                // pre-existing VcnGatewayConnections that satisfy a given request, but if state
+                // that affects the satsifying of requests changes, this is theoretically possible.
+                if (mVcnGatewayConnections.containsKey(gatewayConnectionConfig)) {
+                    logWtf(
+                            "Attempted to bring up VcnGatewayConnection for config "
+                                    + "with existing VcnGatewayConnection");
+                    return;
+                }
+
                 final VcnGatewayConnection vcnGatewayConnection =
                         mDeps.newVcnGatewayConnection(
                                 mVcnContext,
@@ -405,8 +415,12 @@
                                 new VcnGatewayStatusCallbackImpl(gatewayConnectionConfig),
                                 mIsMobileDataEnabled);
                 mVcnGatewayConnections.put(gatewayConnectionConfig, vcnGatewayConnection);
+
+                return;
             }
         }
+
+        logVdbg("Request could not be fulfilled by VCN: " + request);
     }
 
     private Set<Integer> getExposedCapabilitiesForMobileDataState(
@@ -423,7 +437,7 @@
     }
 
     private void handleGatewayConnectionQuit(VcnGatewayConnectionConfig config) {
-        Slog.v(getLogTag(), "VcnGatewayConnection quit: " + config);
+        logDbg("VcnGatewayConnection quit: " + config);
         mVcnGatewayConnections.remove(config);
 
         // Trigger a re-evaluation of all NetworkRequests (to make sure any that can be satisfied
@@ -458,15 +472,18 @@
                 if (exposedCaps.contains(NET_CAPABILITY_INTERNET)
                         || exposedCaps.contains(NET_CAPABILITY_DUN)) {
                     if (gatewayConnection == null) {
-                        Slog.wtf(
-                                getLogTag(),
-                                "Found gatewayConnectionConfig without GatewayConnection");
+                        logWtf("Found gatewayConnectionConfig without" + " GatewayConnection");
                     } else {
                         // TODO(b/184868850): Optimize by restarting NetworkAgents without teardown.
                         gatewayConnection.teardownAsynchronously();
                     }
                 }
             }
+
+            // Trigger re-evaluation of all requests; mobile data state impacts supported caps.
+            mVcnContext.getVcnNetworkProvider().resendAllRequests(mRequestListener);
+
+            logDbg("Mobile data " + (mIsMobileDataEnabled ? "enabled" : "disabled"));
         }
     }
 
@@ -495,8 +512,38 @@
         return request.canBeSatisfiedBy(builder.build());
     }
 
-    private String getLogTag() {
-        return TAG + " [" + mSubscriptionGroup.hashCode() + "]";
+    private String getLogPrefix() {
+        return "[" + LogUtils.getHashedSubscriptionGroup(mSubscriptionGroup) + "]: ";
+    }
+
+    private void logVdbg(String msg) {
+        if (VDBG) {
+            Slog.v(TAG, getLogPrefix() + msg);
+        }
+    }
+
+    private void logDbg(String msg) {
+        Slog.d(TAG, getLogPrefix() + msg);
+    }
+
+    private void logDbg(String msg, Throwable tr) {
+        Slog.d(TAG, getLogPrefix() + msg, tr);
+    }
+
+    private void logErr(String msg) {
+        Slog.e(TAG, getLogPrefix() + msg);
+    }
+
+    private void logErr(String msg, Throwable tr) {
+        Slog.e(TAG, getLogPrefix() + msg, tr);
+    }
+
+    private void logWtf(String msg) {
+        Slog.wtf(TAG, getLogPrefix() + msg);
+    }
+
+    private void logWtf(String msg, Throwable tr) {
+        Slog.wtf(TAG, getLogPrefix() + msg, tr);
     }
 
     /**
@@ -509,6 +556,7 @@
         pw.increaseIndent();
 
         pw.println("mCurrentStatus: " + mCurrentStatus);
+        pw.println("mIsMobileDataEnabled: " + mIsMobileDataEnabled);
 
         pw.println("mVcnGatewayConnections:");
         for (VcnGatewayConnection gw : mVcnGatewayConnections.values()) {
diff --git a/services/core/java/com/android/server/vcn/VcnContext.java b/services/core/java/com/android/server/vcn/VcnContext.java
index 7399e56..d958222 100644
--- a/services/core/java/com/android/server/vcn/VcnContext.java
+++ b/services/core/java/com/android/server/vcn/VcnContext.java
@@ -31,14 +31,17 @@
     @NonNull private final Context mContext;
     @NonNull private final Looper mLooper;
     @NonNull private final VcnNetworkProvider mVcnNetworkProvider;
+    private final boolean mIsInTestMode;
 
     public VcnContext(
             @NonNull Context context,
             @NonNull Looper looper,
-            @NonNull VcnNetworkProvider vcnNetworkProvider) {
+            @NonNull VcnNetworkProvider vcnNetworkProvider,
+            boolean isInTestMode) {
         mContext = Objects.requireNonNull(context, "Missing context");
         mLooper = Objects.requireNonNull(looper, "Missing looper");
         mVcnNetworkProvider = Objects.requireNonNull(vcnNetworkProvider, "Missing networkProvider");
+        mIsInTestMode = isInTestMode;
     }
 
     @NonNull
@@ -56,6 +59,10 @@
         return mVcnNetworkProvider;
     }
 
+    public boolean isInTestMode() {
+        return mIsInTestMode;
+    }
+
     /**
      * Verifies that the caller is running on the VcnContext Thread.
      *
diff --git a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
index 6ca3c4b..5cecff6 100644
--- a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
+++ b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
@@ -52,7 +52,6 @@
 import android.net.NetworkScore;
 import android.net.RouteInfo;
 import android.net.TelephonyNetworkSpecifier;
-import android.net.TunnelConnectionParams;
 import android.net.Uri;
 import android.net.annotations.PolicyDirection;
 import android.net.ipsec.ike.ChildSessionCallback;
@@ -89,6 +88,7 @@
 import com.android.server.vcn.UnderlyingNetworkTracker.UnderlyingNetworkRecord;
 import com.android.server.vcn.UnderlyingNetworkTracker.UnderlyingNetworkTrackerCallback;
 import com.android.server.vcn.Vcn.VcnGatewayStatusCallback;
+import com.android.server.vcn.util.LogUtils;
 import com.android.server.vcn.util.MtuUtils;
 
 import java.io.IOException;
@@ -702,6 +702,7 @@
      * <p>Once torn down, this VcnTunnel CANNOT be started again.
      */
     public void teardownAsynchronously() {
+        logDbg("Triggering async teardown");
         sendDisconnectRequestedAndAcquireWakelock(
                 DISCONNECT_REASON_TEARDOWN, true /* shouldQuit */);
 
@@ -711,6 +712,8 @@
 
     @Override
     protected void onQuitting() {
+        logDbg("Quitting VcnGatewayConnection");
+
         // No need to call setInterfaceDown(); the IpSecInterface is being fully torn down.
         if (mTunnelIface != null) {
             mTunnelIface.close();
@@ -751,6 +754,10 @@
             // TODO(b/180132994): explore safely removing this Thread check
             mVcnContext.ensureRunningOnLooperThread();
 
+            logDbg(
+                    "Selected underlying network changed: "
+                            + (underlying == null ? null : underlying.network));
+
             // TODO(b/179091925): Move the delayed-message handling to BaseState
 
             // If underlying is null, all underlying networks have been lost. Disconnect VCN after a
@@ -775,6 +782,8 @@
 
         if (!mIsQuitting) {
             mWakeLock.acquire();
+
+            logVdbg("Wakelock acquired: " + mWakeLock);
         }
     }
 
@@ -782,6 +791,8 @@
         mVcnContext.ensureRunningOnLooperThread();
 
         mWakeLock.release();
+
+        logVdbg("Wakelock released: " + mWakeLock);
     }
 
     /**
@@ -799,8 +810,7 @@
 
     @Override
     public void sendMessage(int what) {
-        Slog.wtf(
-                TAG,
+        logWtf(
                 "sendMessage should not be used in VcnGatewayConnection. See"
                         + " sendMessageAndAcquireWakeLock()");
         super.sendMessage(what);
@@ -808,8 +818,7 @@
 
     @Override
     public void sendMessage(int what, Object obj) {
-        Slog.wtf(
-                TAG,
+        logWtf(
                 "sendMessage should not be used in VcnGatewayConnection. See"
                         + " sendMessageAndAcquireWakeLock()");
         super.sendMessage(what, obj);
@@ -817,8 +826,7 @@
 
     @Override
     public void sendMessage(int what, int arg1) {
-        Slog.wtf(
-                TAG,
+        logWtf(
                 "sendMessage should not be used in VcnGatewayConnection. See"
                         + " sendMessageAndAcquireWakeLock()");
         super.sendMessage(what, arg1);
@@ -826,8 +834,7 @@
 
     @Override
     public void sendMessage(int what, int arg1, int arg2) {
-        Slog.wtf(
-                TAG,
+        logWtf(
                 "sendMessage should not be used in VcnGatewayConnection. See"
                         + " sendMessageAndAcquireWakeLock()");
         super.sendMessage(what, arg1, arg2);
@@ -835,8 +842,7 @@
 
     @Override
     public void sendMessage(int what, int arg1, int arg2, Object obj) {
-        Slog.wtf(
-                TAG,
+        logWtf(
                 "sendMessage should not be used in VcnGatewayConnection. See"
                         + " sendMessageAndAcquireWakeLock()");
         super.sendMessage(what, arg1, arg2, obj);
@@ -844,8 +850,7 @@
 
     @Override
     public void sendMessage(Message msg) {
-        Slog.wtf(
-                TAG,
+        logWtf(
                 "sendMessage should not be used in VcnGatewayConnection. See"
                         + " sendMessageAndAcquireWakeLock()");
         super.sendMessage(msg);
@@ -936,10 +941,14 @@
     }
 
     private void setTeardownTimeoutAlarm() {
+        logVdbg("Setting teardown timeout alarm; mCurrentToken: " + mCurrentToken);
+
         // Safe to assign this alarm because it is either 1) already null, or 2) already fired. In
         // either case, there is nothing to cancel.
         if (mTeardownTimeoutAlarm != null) {
-            Slog.wtf(TAG, "mTeardownTimeoutAlarm should be null before being set");
+            logWtf(
+                    "mTeardownTimeoutAlarm should be null before being set; mCurrentToken: "
+                            + mCurrentToken);
         }
 
         final Message delayedMessage = obtainMessage(EVENT_TEARDOWN_TIMEOUT_EXPIRED, mCurrentToken);
@@ -951,6 +960,8 @@
     }
 
     private void cancelTeardownTimeoutAlarm() {
+        logVdbg("Cancelling teardown timeout alarm; mCurrentToken: " + mCurrentToken);
+
         if (mTeardownTimeoutAlarm != null) {
             mTeardownTimeoutAlarm.cancel();
             mTeardownTimeoutAlarm = null;
@@ -961,6 +972,11 @@
     }
 
     private void setDisconnectRequestAlarm() {
+        logVdbg(
+                "Setting alarm to disconnect due to underlying network loss;"
+                        + " mCurrentToken: "
+                        + mCurrentToken);
+
         // Only schedule a NEW alarm if none is already set.
         if (mDisconnectRequestAlarm != null) {
             return;
@@ -981,6 +997,11 @@
     }
 
     private void cancelDisconnectRequestAlarm() {
+        logVdbg(
+                "Cancelling alarm to disconnect due to underlying network loss;"
+                        + " mCurrentToken: "
+                        + mCurrentToken);
+
         if (mDisconnectRequestAlarm != null) {
             mDisconnectRequestAlarm.cancel();
             mDisconnectRequestAlarm = null;
@@ -994,10 +1015,14 @@
     }
 
     private void setRetryTimeoutAlarm(long delay) {
+        logVdbg("Setting retry alarm; mCurrentToken: " + mCurrentToken);
+
         // Safe to assign this alarm because it is either 1) already null, or 2) already fired. In
         // either case, there is nothing to cancel.
         if (mRetryTimeoutAlarm != null) {
-            Slog.wtf(TAG, "mRetryTimeoutAlarm should be null before being set");
+            logWtf(
+                    "mRetryTimeoutAlarm should be null before being set; mCurrentToken: "
+                            + mCurrentToken);
         }
 
         final Message delayedMessage = obtainMessage(EVENT_RETRY_TIMEOUT_EXPIRED, mCurrentToken);
@@ -1005,6 +1030,8 @@
     }
 
     private void cancelRetryTimeoutAlarm() {
+        logVdbg("Cancel retry alarm; mCurrentToken: " + mCurrentToken);
+
         if (mRetryTimeoutAlarm != null) {
             mRetryTimeoutAlarm.cancel();
             mRetryTimeoutAlarm = null;
@@ -1015,6 +1042,8 @@
 
     @VisibleForTesting(visibility = Visibility.PRIVATE)
     void setSafeModeAlarm() {
+        logVdbg("Setting safe mode alarm; mCurrentToken: " + mCurrentToken);
+
         // Only schedule a NEW alarm if none is already set.
         if (mSafeModeTimeoutAlarm != null) {
             return;
@@ -1029,6 +1058,8 @@
     }
 
     private void cancelSafeModeAlarm() {
+        logVdbg("Cancel safe mode alarm; mCurrentToken: " + mCurrentToken);
+
         if (mSafeModeTimeoutAlarm != null) {
             mSafeModeTimeoutAlarm.cancel();
             mSafeModeTimeoutAlarm = null;
@@ -1093,6 +1124,14 @@
                             + exception.getMessage();
         }
 
+        logDbg(
+                "Encountered error; code="
+                        + errorCode
+                        + ", exceptionClass="
+                        + exceptionClass
+                        + ", exceptionMessage="
+                        + exceptionMessage);
+
         mGatewayStatusCallback.onGatewayConnectionError(
                 mConnectionConfig.getGatewayConnectionName(),
                 errorCode,
@@ -1138,7 +1177,7 @@
             try {
                 enterState();
             } catch (Exception e) {
-                Slog.wtf(TAG, "Uncaught exception", e);
+                logWtf("Uncaught exception", e);
                 sendDisconnectRequestedAndAcquireWakelock(
                         DISCONNECT_REASON_INTERNAL_ERROR + e.toString(), true /* shouldQuit */);
             }
@@ -1170,14 +1209,14 @@
         public final boolean processMessage(Message msg) {
             final int token = msg.arg1;
             if (!isValidToken(token)) {
-                Slog.v(TAG, "Message called with obsolete token: " + token + "; what: " + msg.what);
+                logDbg("Message called with obsolete token: " + token + "; what: " + msg.what);
                 return HANDLED;
             }
 
             try {
                 processStateMsg(msg);
             } catch (Exception e) {
-                Slog.wtf(TAG, "Uncaught exception", e);
+                logWtf("Uncaught exception", e);
                 sendDisconnectRequestedAndAcquireWakelock(
                         DISCONNECT_REASON_INTERNAL_ERROR + e.toString(), true /* shouldQuit */);
             }
@@ -1195,7 +1234,7 @@
             try {
                 exitState();
             } catch (Exception e) {
-                Slog.wtf(TAG, "Uncaught exception", e);
+                logWtf("Uncaught exception", e);
                 sendDisconnectRequestedAndAcquireWakelock(
                         DISCONNECT_REASON_INTERNAL_ERROR + e.toString(), true /* shouldQuit */);
             }
@@ -1235,7 +1274,7 @@
         protected void handleDisconnectRequested(EventDisconnectRequestedInfo info) {
             // TODO(b/180526152): notify VcnStatusCallback for Network loss
 
-            Slog.v(TAG, "Tearing down. Cause: " + info.reason);
+            logDbg("Tearing down. Cause: " + info.reason);
             mIsQuitting = info.shouldQuit;
 
             teardownNetwork();
@@ -1251,6 +1290,7 @@
 
         protected void handleSafeModeTimeoutExceeded() {
             mSafeModeTimeoutAlarm = null;
+            logDbg("Entering safe mode after timeout exceeded");
 
             // Connectivity for this GatewayConnection is broken; tear down the Network.
             teardownNetwork();
@@ -1259,13 +1299,15 @@
         }
 
         protected void logUnexpectedEvent(int what) {
-            Slog.d(TAG, String.format(
-                    "Unexpected event code %d in state %s", what, this.getClass().getSimpleName()));
+            logDbg(
+                    "Unexpected event code "
+                            + what
+                            + " in state "
+                            + this.getClass().getSimpleName());
         }
 
         protected void logWtfUnknownEvent(int what) {
-            Slog.wtf(TAG, String.format(
-                    "Unknown event code %d in state %s", what, this.getClass().getSimpleName()));
+            logWtf("Unknown event code " + what + " in state " + this.getClass().getSimpleName());
         }
     }
 
@@ -1282,7 +1324,7 @@
             }
 
             if (mIkeSession != null || mNetworkAgent != null) {
-                Slog.wtf(TAG, "Active IKE Session or NetworkAgent in DisconnectedState");
+                logWtf("Active IKE Session or NetworkAgent in DisconnectedState");
             }
 
             cancelSafeModeAlarm();
@@ -1350,7 +1392,7 @@
         @Override
         protected void enterState() throws Exception {
             if (mIkeSession == null) {
-                Slog.wtf(TAG, "IKE session was already closed when entering Disconnecting state.");
+                logWtf("IKE session was already closed when entering Disconnecting state.");
                 sendMessageAndAcquireWakeLock(EVENT_SESSION_CLOSED, mCurrentToken);
                 return;
             }
@@ -1437,7 +1479,7 @@
         @Override
         protected void enterState() {
             if (mIkeSession != null) {
-                Slog.wtf(TAG, "ConnectingState entered with active session");
+                logWtf("ConnectingState entered with active session");
 
                 // Attempt to recover.
                 mIkeSession.kill();
@@ -1456,7 +1498,7 @@
 
                     if (oldUnderlying == null) {
                         // This should never happen, but if it does, there's likely a nasty bug.
-                        Slog.wtf(TAG, "Old underlying network was null in connected state. Bug?");
+                        logWtf("Old underlying network was null in connected state. Bug?");
                     }
 
                     // If new underlying is null, all underlying networks have been lost; disconnect
@@ -1551,16 +1593,29 @@
                                 // new NetworkAgent replaces an old one before the unwanted() call
                                 // is processed.
                                 if (mNetworkAgent != agentRef) {
-                                    Slog.d(TAG, "unwanted() called on stale NetworkAgent");
+                                    logDbg("unwanted() called on stale NetworkAgent");
                                     return;
                                 }
 
-                                Slog.d(TAG, "NetworkAgent was unwanted");
+                                logDbg("NetworkAgent was unwanted");
                                 teardownAsynchronously();
                             } /* networkUnwantedCallback */,
                             (status) -> {
-                                if (status == NetworkAgent.VALIDATION_STATUS_VALID) {
-                                    clearFailedAttemptCounterAndSafeModeAlarm();
+                                switch (status) {
+                                    case NetworkAgent.VALIDATION_STATUS_VALID:
+                                        clearFailedAttemptCounterAndSafeModeAlarm();
+                                        break;
+                                    case NetworkAgent.VALIDATION_STATUS_NOT_VALID:
+                                        // Will only set a new alarm if no safe mode alarm is
+                                        // currently scheduled.
+                                        setSafeModeAlarm();
+                                        break;
+                                    default:
+                                        logWtf(
+                                                "Unknown validation status "
+                                                        + status
+                                                        + "; ignoring");
+                                        break;
                                 }
                             } /* validationStatusCallback */);
 
@@ -1589,13 +1644,26 @@
                 @NonNull Network underlyingNetwork,
                 @NonNull IpSecTransform transform,
                 int direction) {
+            if (direction != IpSecManager.DIRECTION_IN && direction != IpSecManager.DIRECTION_OUT) {
+                Slog.wtf(TAG, "Applying transform for unexpected direction: " + direction);
+            }
+
             try {
                 tunnelIface.setUnderlyingNetwork(underlyingNetwork);
 
                 // Transforms do not need to be persisted; the IkeSession will keep them alive
                 mIpSecManager.applyTunnelModeTransform(tunnelIface, direction, transform);
+
+                // For inbound transforms, additionally allow forwarded traffic to bridge to DUN (as
+                // needed)
+                final Set<Integer> exposedCaps = mConnectionConfig.getAllExposedCapabilities();
+                if (direction == IpSecManager.DIRECTION_IN
+                        && exposedCaps.contains(NET_CAPABILITY_DUN)) {
+                    mIpSecManager.applyTunnelModeTransform(
+                            tunnelIface, IpSecManager.DIRECTION_FWD, transform);
+                }
             } catch (IOException e) {
-                Slog.d(TAG, "Transform application failed for network " + token, e);
+                logDbg("Transform application failed for network " + token, e);
                 sessionLost(token, e);
             }
         }
@@ -1629,7 +1697,7 @@
                     tunnelIface.removeAddress(address.getAddress(), address.getPrefixLength());
                 }
             } catch (IOException e) {
-                Slog.d(TAG, "Adding address to tunnel failed for token " + token, e);
+                logDbg("Adding address to tunnel failed for token " + token, e);
                 sessionLost(token, e);
             }
         }
@@ -1709,6 +1777,8 @@
         }
 
         private void handleMigrationCompleted(EventMigrationCompletedInfo migrationCompletedInfo) {
+            logDbg("Migration completed: " + mUnderlying.network);
+
             applyTransform(
                     mCurrentToken,
                     mTunnelIface,
@@ -1731,6 +1801,8 @@
             mUnderlying = ((EventUnderlyingNetworkChangedInfo) msg.obj).newUnderlying;
 
             if (mUnderlying == null) {
+                logDbg("Underlying network lost");
+
                 // Ignored for now; a new network may be coming up. If none does, the delayed
                 // NETWORK_LOST disconnect will be fired, and tear down the session + network.
                 return;
@@ -1739,7 +1811,7 @@
             // mUnderlying assumed non-null, given check above.
             // If network changed, migrate. Otherwise, update any existing networkAgent.
             if (oldUnderlying == null || !oldUnderlying.network.equals(mUnderlying.network)) {
-                Slog.v(TAG, "Migrating to new network: " + mUnderlying.network);
+                logDbg("Migrating to new network: " + mUnderlying.network);
                 mIkeSession.setNetwork(mUnderlying.network);
             } else {
                 // oldUnderlying is non-null & underlying network itself has not changed
@@ -1790,7 +1862,7 @@
             mFailedAttempts++;
 
             if (mUnderlying == null) {
-                Slog.wtf(TAG, "Underlying network was null in retry state");
+                logWtf("Underlying network was null in retry state");
                 transitionTo(mDisconnectedState);
             } else {
                 // Safe to blindly set up, as it is cancelled and cleared on exiting this state
@@ -1838,7 +1910,7 @@
 
         private long getNextRetryIntervalsMs() {
             final int retryDelayIndex = mFailedAttempts - 1;
-            final long[] retryIntervalsMs = mConnectionConfig.getRetryIntervalsMs();
+            final long[] retryIntervalsMs = mConnectionConfig.getRetryIntervalsMillis();
 
             // Repeatedly use last item in retry timeout list.
             if (retryDelayIndex >= retryIntervalsMs.length) {
@@ -1924,14 +1996,8 @@
             @NonNull IpSecTunnelInterface tunnelIface,
             @NonNull VcnChildSessionConfiguration childConfig,
             @Nullable UnderlyingNetworkRecord underlying) {
-        final TunnelConnectionParams tunnelParams =
+        final IkeTunnelConnectionParams ikeTunnelParams =
                 gatewayConnectionConfig.getTunnelConnectionParams();
-        if (!(tunnelParams instanceof IkeTunnelConnectionParams)) {
-            throw new IllegalStateException(
-                    "TunnelConnectionParams is not IkeTunnelConnectionParams");
-        }
-
-        final IkeTunnelConnectionParams ikeTunnelParams = (IkeTunnelConnectionParams) tunnelParams;
         final LinkProperties lp = new LinkProperties();
 
         lp.setInterfaceName(tunnelIface.getInterfaceName());
@@ -1966,25 +2032,25 @@
 
         @Override
         public void onOpened(@NonNull IkeSessionConfiguration ikeSessionConfig) {
-            Slog.v(TAG, "IkeOpened for token " + mToken);
+            logDbg("IkeOpened for token " + mToken);
             // Nothing to do here.
         }
 
         @Override
         public void onClosed() {
-            Slog.v(TAG, "IkeClosed for token " + mToken);
+            logDbg("IkeClosed for token " + mToken);
             sessionClosed(mToken, null);
         }
 
         @Override
         public void onClosedExceptionally(@NonNull IkeException exception) {
-            Slog.v(TAG, "IkeClosedExceptionally for token " + mToken, exception);
+            logDbg("IkeClosedExceptionally for token " + mToken, exception);
             sessionClosed(mToken, exception);
         }
 
         @Override
         public void onError(@NonNull IkeProtocolException exception) {
-            Slog.v(TAG, "IkeError for token " + mToken, exception);
+            logDbg("IkeError for token " + mToken, exception);
             // Non-fatal, log and continue.
         }
     }
@@ -2001,7 +2067,7 @@
         /** Internal proxy method for injecting of mocked ChildSessionConfiguration */
         @VisibleForTesting(visibility = Visibility.PRIVATE)
         void onOpened(@NonNull VcnChildSessionConfiguration childConfig) {
-            Slog.v(TAG, "ChildOpened for token " + mToken);
+            logDbg("ChildOpened for token " + mToken);
             childOpened(mToken, childConfig);
         }
 
@@ -2012,19 +2078,19 @@
 
         @Override
         public void onClosed() {
-            Slog.v(TAG, "ChildClosed for token " + mToken);
+            logDbg("ChildClosed for token " + mToken);
             sessionLost(mToken, null);
         }
 
         @Override
         public void onClosedExceptionally(@NonNull IkeException exception) {
-            Slog.v(TAG, "ChildClosedExceptionally for token " + mToken, exception);
+            logDbg("ChildClosedExceptionally for token " + mToken, exception);
             sessionLost(mToken, exception);
         }
 
         @Override
         public void onIpSecTransformCreated(@NonNull IpSecTransform transform, int direction) {
-            Slog.v(TAG, "ChildTransformCreated; Direction: " + direction + "; token " + mToken);
+            logDbg("ChildTransformCreated; Direction: " + direction + "; token " + mToken);
             childTransformCreated(mToken, transform, direction);
         }
 
@@ -2032,7 +2098,7 @@
         public void onIpSecTransformsMigrated(
                 @NonNull IpSecTransform inIpSecTransform,
                 @NonNull IpSecTransform outIpSecTransform) {
-            Slog.v(TAG, "ChildTransformsMigrated; token " + mToken);
+            logDbg("ChildTransformsMigrated; token " + mToken);
             migrationCompleted(mToken, inIpSecTransform, outIpSecTransform);
         }
 
@@ -2040,10 +2106,48 @@
         public void onIpSecTransformDeleted(@NonNull IpSecTransform transform, int direction) {
             // Nothing to be done; no references to the IpSecTransform are held, and this transform
             // will be closed by the IKE library.
-            Slog.v(TAG, "ChildTransformDeleted; Direction: " + direction + "; for token " + mToken);
+            logDbg("ChildTransformDeleted; Direction: " + direction + "; for token " + mToken);
         }
     }
 
+    private String getLogPrefix() {
+        return "["
+                + LogUtils.getHashedSubscriptionGroup(mSubscriptionGroup)
+                + "-"
+                + mConnectionConfig.getGatewayConnectionName()
+                + "]: ";
+    }
+
+    private void logVdbg(String msg) {
+        if (VDBG) {
+            Slog.v(TAG, getLogPrefix() + msg);
+        }
+    }
+
+    private void logDbg(String msg) {
+        Slog.d(TAG, getLogPrefix() + msg);
+    }
+
+    private void logDbg(String msg, Throwable tr) {
+        Slog.d(TAG, getLogPrefix() + msg, tr);
+    }
+
+    private void logErr(String msg) {
+        Slog.e(TAG, getLogPrefix() + msg);
+    }
+
+    private void logErr(String msg, Throwable tr) {
+        Slog.e(TAG, getLogPrefix() + msg, tr);
+    }
+
+    private void logWtf(String msg) {
+        Slog.wtf(TAG, getLogPrefix() + msg);
+    }
+
+    private void logWtf(String msg, Throwable tr) {
+        Slog.wtf(TAG, getLogPrefix() + msg, tr);
+    }
+
     /**
      * Dumps the state of this VcnGatewayConnection for logging and debugging purposes.
      *
@@ -2138,32 +2242,16 @@
     }
 
     private IkeSessionParams buildIkeParams(@NonNull Network network) {
-        final TunnelConnectionParams tunnelConnectionParams =
+        final IkeTunnelConnectionParams ikeTunnelConnectionParams =
                 mConnectionConfig.getTunnelConnectionParams();
-
-        if (tunnelConnectionParams instanceof IkeTunnelConnectionParams) {
-            final IkeTunnelConnectionParams ikeTunnelConnectionParams =
-                    (IkeTunnelConnectionParams) tunnelConnectionParams;
-            final IkeSessionParams.Builder builder =
-                    new IkeSessionParams.Builder(ikeTunnelConnectionParams.getIkeSessionParams());
-            builder.setNetwork(network);
-
-            return builder.build();
-        }
-
-        throw new IllegalStateException("TunnelConnectionParams is not IkeTunnelConnectionParams");
+        final IkeSessionParams.Builder builder =
+                new IkeSessionParams.Builder(ikeTunnelConnectionParams.getIkeSessionParams());
+        builder.setNetwork(network);
+        return builder.build();
     }
 
     private ChildSessionParams buildChildParams() {
-        final TunnelConnectionParams tunnelConnectionParams =
-                mConnectionConfig.getTunnelConnectionParams();
-
-        if (tunnelConnectionParams instanceof IkeTunnelConnectionParams) {
-            return ((IkeTunnelConnectionParams) tunnelConnectionParams)
-                    .getTunnelModeChildSessionParams();
-        }
-
-        throw new IllegalStateException("TunnelConnectionParams is not IkeTunnelConnectionParams");
+        return mConnectionConfig.getTunnelConnectionParams().getTunnelModeChildSessionParams();
     }
 
     @VisibleForTesting(visibility = Visibility.PRIVATE)
diff --git a/services/core/java/com/android/server/vcn/util/LogUtils.java b/services/core/java/com/android/server/vcn/util/LogUtils.java
new file mode 100644
index 0000000..93728ce
--- /dev/null
+++ b/services/core/java/com/android/server/vcn/util/LogUtils.java
@@ -0,0 +1,39 @@
+/*
+ * 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 com.android.server.vcn.util;
+
+import android.annotation.Nullable;
+import android.os.ParcelUuid;
+
+import com.android.internal.util.HexDump;
+
+/** @hide */
+public class LogUtils {
+    /**
+     * Returns the hash of the subscription group in hexadecimal format.
+     *
+     * @return the hexadecimal encoded string if uuid was non-null, else {@code null}
+     */
+    @Nullable
+    public static String getHashedSubscriptionGroup(@Nullable ParcelUuid uuid) {
+        if (uuid == null) {
+            return null;
+        }
+
+        return HexDump.toHexString(uuid.hashCode());
+    }
+}
diff --git a/services/core/java/com/android/server/wm/LockTaskController.java b/services/core/java/com/android/server/wm/LockTaskController.java
index c4a42ab..281d2c9 100644
--- a/services/core/java/com/android/server/wm/LockTaskController.java
+++ b/services/core/java/com/android/server/wm/LockTaskController.java
@@ -512,7 +512,7 @@
             setStatusBarState(mLockTaskModeState, userId);
             setKeyguardState(mLockTaskModeState, userId);
             if (oldLockTaskModeState == LOCK_TASK_MODE_PINNED) {
-                lockKeyguardIfNeeded();
+                lockKeyguardIfNeeded(userId);
             }
             if (getDevicePolicyManager() != null) {
                 getDevicePolicyManager().notifyLockTaskModeChanged(false, null, userId);
@@ -824,15 +824,15 @@
      * Helper method for locking the device immediately. This may be necessary when the device
      * leaves the pinned mode.
      */
-    private void lockKeyguardIfNeeded() {
-        if (shouldLockKeyguard()) {
+    private void lockKeyguardIfNeeded(int userId) {
+        if (shouldLockKeyguard(userId)) {
             mWindowManager.lockNow(null);
             mWindowManager.dismissKeyguard(null /* callback */, null /* message */);
             getLockPatternUtils().requireCredentialEntry(USER_ALL);
         }
     }
 
-    private boolean shouldLockKeyguard() {
+    private boolean shouldLockKeyguard(int userId) {
         // This functionality should be kept consistent with
         // com.android.settings.security.ScreenPinningSettings (see b/127605586)
         try {
@@ -842,7 +842,7 @@
         } catch (Settings.SettingNotFoundException e) {
             // Log to SafetyNet for b/127605586
             android.util.EventLog.writeEvent(0x534e4554, "127605586", -1, "");
-            return getLockPatternUtils().isSecure(USER_CURRENT);
+            return getLockPatternUtils().isSecure(userId);
         }
     }
 
diff --git a/services/core/jni/OWNERS b/services/core/jni/OWNERS
index bbcc2c1..e8050fa 100644
--- a/services/core/jni/OWNERS
+++ b/services/core/jni/OWNERS
@@ -29,3 +29,4 @@
 per-file com_android_server_security_* = file:/core/java/android/security/OWNERS
 per-file com_android_server_tv_* = file:/media/java/android/media/tv/OWNERS
 per-file com_android_server_vibrator_* = file:/services/core/java/com/android/server/vibrator/OWNERS
+per-file com_android_server_am_CachedAppOptimizer.cpp = timmurray@google.com, edgararriaga@google.com, dualli@google.com, carmenjackson@google.com, philipcuadra@google.com
\ No newline at end of file
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 736a6f6..8e3cb25 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -91,7 +91,6 @@
 import static android.os.UserManagerInternal.OWNER_TYPE_DEVICE_OWNER;
 import static android.os.UserManagerInternal.OWNER_TYPE_PROFILE_OWNER;
 import static android.os.UserManagerInternal.OWNER_TYPE_PROFILE_OWNER_OF_ORGANIZATION_OWNED_DEVICE;
-import static android.provider.Settings.Global.PRIVATE_DNS_MODE;
 import static android.provider.Settings.Global.PRIVATE_DNS_SPECIFIER;
 import static android.provider.Telephony.Carriers.DPC_URI;
 import static android.provider.Telephony.Carriers.ENFORCE_KEY;
@@ -195,6 +194,7 @@
 import android.media.AudioManager;
 import android.media.IAudioService;
 import android.net.ConnectivityManager;
+import android.net.ConnectivitySettingsManager;
 import android.net.IIpConnectivityMetrics;
 import android.net.ProxyInfo;
 import android.net.Uri;
@@ -15566,12 +15566,12 @@
         return context.getResources().getString(R.string.config_managed_provisioning_package);
     }
 
-    private void putPrivateDnsSettings(@Nullable String mode, @Nullable String host) {
+    private void putPrivateDnsSettings(int mode, @Nullable String host) {
         // Set Private DNS settings using system permissions, as apps cannot write
         // to global settings.
         mInjector.binderWithCleanCallingIdentity(() -> {
-            mInjector.settingsGlobalPutString(PRIVATE_DNS_MODE, mode);
-            mInjector.settingsGlobalPutString(PRIVATE_DNS_SPECIFIER, host);
+            ConnectivitySettingsManager.setPrivateDnsMode(mContext, mode);
+            ConnectivitySettingsManager.setPrivateDnsHostname(mContext, host);
         });
     }
 
@@ -15592,7 +15592,8 @@
                     throw new IllegalArgumentException(
                             "Host provided for opportunistic mode, but is not needed.");
                 }
-                putPrivateDnsSettings(ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC, null);
+                putPrivateDnsSettings(ConnectivitySettingsManager.PRIVATE_DNS_MODE_OPPORTUNISTIC,
+                        null);
                 return PRIVATE_DNS_SET_NO_ERROR;
             case PRIVATE_DNS_MODE_PROVIDER_HOSTNAME:
                 if (TextUtils.isEmpty(privateDnsHost)
@@ -15604,7 +15605,7 @@
                 // Connectivity check will have been performed in the DevicePolicyManager before
                 // the call here.
                 putPrivateDnsSettings(
-                        ConnectivityManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME,
+                        ConnectivitySettingsManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME,
                         privateDnsHost);
                 return PRIVATE_DNS_SET_NO_ERROR;
             default:
@@ -15621,13 +15622,13 @@
 
         Objects.requireNonNull(who, "ComponentName is null");
         enforceDeviceOwner(who);
-        final String currentMode = ConnectivityManager.getPrivateDnsMode(mContext);
+        final int currentMode = ConnectivitySettingsManager.getPrivateDnsMode(mContext);
         switch (currentMode) {
-            case ConnectivityManager.PRIVATE_DNS_MODE_OFF:
+            case ConnectivitySettingsManager.PRIVATE_DNS_MODE_OFF:
                 return PRIVATE_DNS_MODE_OFF;
-            case ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC:
+            case ConnectivitySettingsManager.PRIVATE_DNS_MODE_OPPORTUNISTIC:
                 return PRIVATE_DNS_MODE_OPPORTUNISTIC;
-            case ConnectivityManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME:
+            case ConnectivitySettingsManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME:
                 return PRIVATE_DNS_MODE_PROVIDER_HOSTNAME;
         }
 
diff --git a/services/net/TEST_MAPPING b/services/net/TEST_MAPPING
index 7025dd1..7eca1f9 100644
--- a/services/net/TEST_MAPPING
+++ b/services/net/TEST_MAPPING
@@ -2,6 +2,9 @@
   "imports": [
     {
       "path": "frameworks/base/core/java/android/net"
+    },
+    {
+      "path": "packages/modules/Wifi/framework"
     }
   ]
-}
\ No newline at end of file
+}
diff --git a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
index 1208ecc..9706d7f 100644
--- a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
+++ b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
@@ -23,11 +23,13 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.ResolveInfo;
 import android.os.Handler;
 import android.os.IBinder.DeathRecipient;
 import android.os.Looper;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.SystemProperties;
 import android.os.UpdateEngine;
 import android.os.UpdateEngineCallback;
 import android.os.UserHandle;
@@ -42,6 +44,9 @@
 import com.android.server.wm.ActivityMetricsLaunchObserverRegistry;
 import com.android.server.wm.ActivityTaskManagerInternal;
 
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.List;
 import java.util.concurrent.ThreadLocalRandom;
 import java.util.concurrent.TimeUnit;
 
@@ -75,7 +80,7 @@
      */
     public static boolean enabled() {
         return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_PROFCOLLECT_NATIVE_BOOT, "enabled",
-            false);
+            false) || SystemProperties.getBoolean("persist.profcollectd.enabled_override", false);
     }
 
     @Override
@@ -297,24 +302,20 @@
             return;
         }
 
-        final boolean uploadReport =
-                DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_PROFCOLLECT_NATIVE_BOOT,
-                                        "upload_report", false);
-
         new Thread(() -> {
             try {
                 String reportUuid = mIProfcollect.report();
 
-                if (!uploadReport) {
+                final int profileId = getBBProfileId();
+                String reportDir = "/data/user/" + profileId
+                        + "/com.google.android.apps.internal.betterbug/cache/";
+                String reportPath = reportDir + reportUuid + ".zip";
+
+                if (!Files.exists(Paths.get(reportDir))) {
+                    Log.i(LOG_TAG, "Destination directory does not exist, abort upload.");
                     return;
                 }
 
-                final int profileId = getBBProfileId();
-                mIProfcollect.copy_report_to_bb(profileId, reportUuid);
-                String reportPath =
-                        "/data/user/" + profileId
-                        + "/com.google.android.apps.internal.betterbug/cache/"
-                        + reportUuid + ".zip";
                 Intent uploadIntent =
                         new Intent("com.google.android.apps.betterbug.intent.action.UPLOAD_PROFILE")
                         .setPackage("com.google.android.apps.internal.betterbug")
@@ -323,9 +324,15 @@
                         .putExtra("EXTRA_PROFILE_PATH", reportPath)
                         .addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
                 Context context = getContext();
-                if (context.getPackageManager().queryBroadcastReceivers(uploadIntent, 0) != null) {
-                    context.sendBroadcast(uploadIntent);
+
+                List<ResolveInfo> receivers =
+                        context.getPackageManager().queryBroadcastReceivers(uploadIntent, 0);
+                if (receivers == null || receivers.isEmpty()) {
+                    Log.i(LOG_TAG, "No one to receive upload intent, abort upload.");
+                    return;
                 }
+                mIProfcollect.copy_report_to_bb(profileId, reportUuid);
+                context.sendBroadcast(uploadIntent);
                 mIProfcollect.delete_report(reportUuid);
             } catch (RemoteException e) {
                 Log.e(LOG_TAG, e.getMessage());
diff --git a/services/tests/servicestests/src/com/android/server/compat/CompatConfigBuilder.java b/services/tests/servicestests/src/com/android/server/compat/CompatConfigBuilder.java
index 7bdc87e..6b9aa18 100644
--- a/services/tests/servicestests/src/com/android/server/compat/CompatConfigBuilder.java
+++ b/services/tests/servicestests/src/com/android/server/compat/CompatConfigBuilder.java
@@ -115,7 +115,12 @@
         return this;
     }
 
-    CompatConfigBuilder addOverridableChangeWithId(long id) {
+    CompatConfigBuilder addEnabledOverridableChangeWithId(long id) {
+        mChanges.add(new CompatChange(id, "", -1, -1, false, false, "", true));
+        return this;
+    }
+
+    CompatConfigBuilder addDisabledOverridableChangeWithId(long id) {
         mChanges.add(new CompatChange(id, "", -1, -1, true, false, "", true));
         return this;
     }
diff --git a/services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java b/services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java
index a866363..0248b9b 100644
--- a/services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java
+++ b/services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java
@@ -36,6 +36,7 @@
 
 import com.android.internal.compat.AndroidBuildClassifier;
 import com.android.internal.compat.CompatibilityOverrideConfig;
+import com.android.internal.compat.CompatibilityOverridesToRemoveConfig;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -50,6 +51,10 @@
 import java.nio.file.Files;
 import java.nio.file.Paths;
 import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
 import java.util.UUID;
 
 @RunWith(AndroidJUnit4.class)
@@ -249,7 +254,7 @@
         when(packageManager.getApplicationInfo(eq("com.some.package"), anyInt()))
             .thenReturn(applicationInfo);
 
-        // Force the validator to prevent overriding the change by using a user build.
+        // Force the validator to prevent overriding non-overridable changes by using a user build.
         when(mBuildClassifier.isDebuggableBuild()).thenReturn(false);
         when(mBuildClassifier.isFinalBuild()).thenReturn(true);
 
@@ -261,10 +266,12 @@
 
     @Test
     public void testInstallerCanSetOverrides() throws Exception {
-        final long changeId = 1234L;
-        final int installerUid = 23;
+        final long disabledChangeId1 = 1234L;
+        final long disabledChangeId2 = 1235L;
+        // We make disabledChangeId2 non-overridable to make sure it is ignored.
         CompatConfig compatConfig = CompatConfigBuilder.create(mBuildClassifier, mContext)
-                .addOverridableChangeWithId(1234L)
+                .addDisabledOverridableChangeWithId(disabledChangeId1)
+                .addDisabledChangeWithId(disabledChangeId2)
                 .build();
         ApplicationInfo applicationInfo = ApplicationInfoBuilder.create()
                 .withPackageName("com.some.package")
@@ -274,19 +281,56 @@
         when(packageManager.getApplicationInfo(eq("com.some.package"), anyInt()))
                 .thenReturn(applicationInfo);
 
-        // Force the validator to prevent overriding the change by using a user build.
+        // Force the validator to prevent overriding non-overridable changes by using a user build.
         when(mBuildClassifier.isDebuggableBuild()).thenReturn(false);
         when(mBuildClassifier.isFinalBuild()).thenReturn(true);
 
         CompatibilityOverrideConfig config = new CompatibilityOverrideConfig(
-                Collections.singletonMap(1234L,
+                Collections.singletonMap(disabledChangeId1,
                         new PackageOverride.Builder()
                                 .setMaxVersionCode(99L)
                                 .setEnabled(true)
                                 .build()));
 
         compatConfig.addOverrides(config, "com.some.package");
-        assertThat(compatConfig.isChangeEnabled(1234L, applicationInfo)).isTrue();
+        assertThat(compatConfig.isChangeEnabled(disabledChangeId1, applicationInfo)).isTrue();
+        assertThat(compatConfig.isChangeEnabled(disabledChangeId2, applicationInfo)).isFalse();
+    }
+
+    @Test
+    public void testPreventInstallerSetNonOverridable() throws Exception {
+        final long disabledChangeId1 = 1234L;
+        final long disabledChangeId2 = 1235L;
+        final long disabledChangeId3 = 1236L;
+        CompatConfig compatConfig = CompatConfigBuilder.create(mBuildClassifier, mContext)
+                .addDisabledOverridableChangeWithId(disabledChangeId1)
+                .addDisabledChangeWithId(disabledChangeId2)
+                .addDisabledOverridableChangeWithId(disabledChangeId3)
+                .build();
+        ApplicationInfo applicationInfo = ApplicationInfoBuilder.create()
+                .withPackageName("com.some.package")
+                .build();
+        PackageManager packageManager = mock(PackageManager.class);
+        when(mContext.getPackageManager()).thenReturn(packageManager);
+        when(packageManager.getApplicationInfo(eq("com.some.package"), anyInt()))
+                .thenReturn(applicationInfo);
+
+        // Force the validator to prevent overriding non-overridable changes by using a user build.
+        when(mBuildClassifier.isDebuggableBuild()).thenReturn(false);
+        when(mBuildClassifier.isFinalBuild()).thenReturn(true);
+
+        Map<Long, PackageOverride> overrides = new HashMap<>();
+        overrides.put(disabledChangeId1, new PackageOverride.Builder().setEnabled(true).build());
+        overrides.put(disabledChangeId2, new PackageOverride.Builder().setEnabled(true).build());
+        overrides.put(disabledChangeId3, new PackageOverride.Builder().setEnabled(true).build());
+        CompatibilityOverrideConfig config = new CompatibilityOverrideConfig(overrides);
+
+        assertThrows(SecurityException.class,
+                () -> compatConfig.addOverrides(config, "com.some.package")
+        );
+        assertThat(compatConfig.isChangeEnabled(disabledChangeId1, applicationInfo)).isTrue();
+        assertThat(compatConfig.isChangeEnabled(disabledChangeId2, applicationInfo)).isFalse();
+        assertThat(compatConfig.isChangeEnabled(disabledChangeId3, applicationInfo)).isFalse();
     }
 
     @Test
@@ -459,7 +503,7 @@
         assertThat(compatConfig.isChangeEnabled(1234L, applicationInfo)).isTrue();
 
         // Reject all override attempts.
-        // Force the validator to prevent overriding the change by using a user build.
+        // Force the validator to prevent overriding non-overridable changes by using a user build.
         when(mBuildClassifier.isDebuggableBuild()).thenReturn(false);
         when(mBuildClassifier.isFinalBuild()).thenReturn(false);
         // Try to turn off change, but validator prevents it.
@@ -481,7 +525,7 @@
                 .thenReturn(applicationInfo);
 
         // Reject all override attempts.
-        // Force the validator to prevent overriding the change by using a user build.
+        // Force the validator to prevent overriding non-overridable changes by using a user build.
         when(mBuildClassifier.isDebuggableBuild()).thenReturn(false);
         when(mBuildClassifier.isFinalBuild()).thenReturn(true);
         // Try to remove a non existing override, and it doesn't fail.
@@ -509,6 +553,90 @@
     }
 
     @Test
+    public void testInstallerCanRemoveOverrides() throws Exception {
+        final long disabledChangeId1 = 1234L;
+        final long disabledChangeId2 = 1235L;
+        final long enabledChangeId = 1236L;
+        // We make disabledChangeId2 non-overridable to make sure it is ignored.
+        CompatConfig compatConfig = CompatConfigBuilder.create(mBuildClassifier, mContext)
+                .addDisabledOverridableChangeWithId(disabledChangeId1)
+                .addDisabledChangeWithId(disabledChangeId2)
+                .addEnabledOverridableChangeWithId(enabledChangeId)
+                .build();
+        ApplicationInfo applicationInfo = ApplicationInfoBuilder.create()
+                .withPackageName("com.some.package")
+                .build();
+        when(mPackageManager.getApplicationInfo(eq("com.some.package"), anyInt()))
+                .thenReturn(applicationInfo);
+
+        assertThat(compatConfig.addOverride(disabledChangeId1, "com.some.package", true)).isTrue();
+        assertThat(compatConfig.addOverride(disabledChangeId2, "com.some.package", true)).isTrue();
+        assertThat(compatConfig.addOverride(enabledChangeId, "com.some.package", false)).isTrue();
+        assertThat(compatConfig.isChangeEnabled(disabledChangeId1, applicationInfo)).isTrue();
+        assertThat(compatConfig.isChangeEnabled(disabledChangeId2, applicationInfo)).isTrue();
+        assertThat(compatConfig.isChangeEnabled(enabledChangeId, applicationInfo)).isFalse();
+
+        // Force the validator to prevent overriding non-overridable changes by using a user build.
+        when(mBuildClassifier.isDebuggableBuild()).thenReturn(false);
+        when(mBuildClassifier.isFinalBuild()).thenReturn(true);
+
+        Set<Long> overridesToRemove = new HashSet<>();
+        overridesToRemove.add(disabledChangeId1);
+        overridesToRemove.add(enabledChangeId);
+        CompatibilityOverridesToRemoveConfig config = new CompatibilityOverridesToRemoveConfig(
+                overridesToRemove);
+
+        compatConfig.removePackageOverrides(config, "com.some.package");
+        assertThat(compatConfig.isChangeEnabled(disabledChangeId1, applicationInfo)).isFalse();
+        assertThat(compatConfig.isChangeEnabled(disabledChangeId2, applicationInfo)).isTrue();
+        assertThat(compatConfig.isChangeEnabled(enabledChangeId, applicationInfo)).isTrue();
+    }
+
+    @Test
+    public void testPreventInstallerRemoveNonOverridable() throws Exception {
+        final long disabledChangeId1 = 1234L;
+        final long disabledChangeId2 = 1235L;
+        final long disabledChangeId3 = 1236L;
+        CompatConfig compatConfig = CompatConfigBuilder.create(mBuildClassifier, mContext)
+                .addDisabledOverridableChangeWithId(disabledChangeId1)
+                .addDisabledChangeWithId(disabledChangeId2)
+                .addDisabledOverridableChangeWithId(disabledChangeId3)
+                .build();
+        ApplicationInfo applicationInfo = ApplicationInfoBuilder.create()
+                .withPackageName("com.some.package")
+                .build();
+        PackageManager packageManager = mock(PackageManager.class);
+        when(mContext.getPackageManager()).thenReturn(packageManager);
+        when(packageManager.getApplicationInfo(eq("com.some.package"), anyInt()))
+                .thenReturn(applicationInfo);
+
+        assertThat(compatConfig.addOverride(disabledChangeId1, "com.some.package", true)).isTrue();
+        assertThat(compatConfig.addOverride(disabledChangeId2, "com.some.package", true)).isTrue();
+        assertThat(compatConfig.addOverride(disabledChangeId3, "com.some.package", true)).isTrue();
+        assertThat(compatConfig.isChangeEnabled(disabledChangeId1, applicationInfo)).isTrue();
+        assertThat(compatConfig.isChangeEnabled(disabledChangeId2, applicationInfo)).isTrue();
+        assertThat(compatConfig.isChangeEnabled(disabledChangeId3, applicationInfo)).isTrue();
+
+        // Force the validator to prevent overriding non-overridable changes by using a user build.
+        when(mBuildClassifier.isDebuggableBuild()).thenReturn(false);
+        when(mBuildClassifier.isFinalBuild()).thenReturn(true);
+
+        Set<Long> overridesToRemove = new HashSet<>();
+        overridesToRemove.add(disabledChangeId1);
+        overridesToRemove.add(disabledChangeId2);
+        overridesToRemove.add(disabledChangeId3);
+        CompatibilityOverridesToRemoveConfig config = new CompatibilityOverridesToRemoveConfig(
+                overridesToRemove);
+
+        assertThrows(SecurityException.class,
+                () -> compatConfig.removePackageOverrides(config, "com.some.package")
+        );
+        assertThat(compatConfig.isChangeEnabled(disabledChangeId1, applicationInfo)).isFalse();
+        assertThat(compatConfig.isChangeEnabled(disabledChangeId2, applicationInfo)).isTrue();
+        assertThat(compatConfig.isChangeEnabled(disabledChangeId3, applicationInfo)).isTrue();
+    }
+
+    @Test
     public void testEnableTargetSdkChangesForPackage() throws Exception {
         CompatConfig compatConfig = CompatConfigBuilder.create(mBuildClassifier, mContext)
                 .addEnabledChangeWithId(1L)
diff --git a/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java b/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java
index a2664e5..9accd49 100644
--- a/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java
+++ b/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java
@@ -98,7 +98,7 @@
                 .addEnableAfterSdkChangeWithId(Build.VERSION_CODES.Q, 5L)
                 .addEnableAfterSdkChangeWithId(Build.VERSION_CODES.R, 6L)
                 .addLoggingOnlyChangeWithId(7L)
-                .addOverridableChangeWithId(8L)
+                .addDisabledOverridableChangeWithId(8L)
                 .build();
         mPlatformCompat = new PlatformCompat(mContext, mCompatConfig, mBuildClassifier);
         assertThat(mPlatformCompat.listAllChanges()).asList().containsExactly(
diff --git a/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java b/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java
index deaeb46..a1bce52 100644
--- a/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java
+++ b/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java
@@ -374,7 +374,7 @@
                 .setPersisted(true)
                 .setRequiredNetwork(new NetworkRequest.Builder()
                         .addCapability(NET_CAPABILITY_IMS)
-                        .addUnwantedCapability(NET_CAPABILITY_OEM_PAID)
+                        .addForbiddenCapability(NET_CAPABILITY_OEM_PAID)
                         .build())
                 .build());
     }
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java
index 41562bb..a8b10f6 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java
@@ -155,7 +155,8 @@
         }
 
         @Override
-        public ManagedProfilePasswordCache getManagedProfilePasswordCache() {
+        public ManagedProfilePasswordCache getManagedProfilePasswordCache(
+                java.security.KeyStore ks) {
             return mock(ManagedProfilePasswordCache.class);
         }
 
diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
index e9e2486..a02a039 100644
--- a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
@@ -1091,7 +1091,7 @@
         // first, pretend that wifi network comes online. no policy active,
         // which means we shouldn't push limit to interface.
         snapshots = List.of(buildWifi());
-        when(mConnManager.getAllNetworkStateSnapshot()).thenReturn(snapshots);
+        when(mConnManager.getAllNetworkStateSnapshots()).thenReturn(snapshots);
 
         mPolicyListener.expect().onMeteredIfacesChanged(any());
         mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION));
@@ -1099,7 +1099,7 @@
 
         // now change cycle to be on 15th, and test in early march, to verify we
         // pick cycle day in previous month.
-        when(mConnManager.getAllNetworkStateSnapshot()).thenReturn(snapshots);
+        when(mConnManager.getAllNetworkStateSnapshots()).thenReturn(snapshots);
 
         // pretend that 512 bytes total have happened
         stats = new NetworkStats(getElapsedRealtime(), 1)
@@ -1360,7 +1360,7 @@
                 .insertEntry(TEST_IFACE, 0L, 0L, 0L, 0L);
 
         {
-            when(mConnManager.getAllNetworkStateSnapshot()).thenReturn(snapshots);
+            when(mConnManager.getAllNetworkStateSnapshots()).thenReturn(snapshots);
             when(mStatsService.getNetworkTotalBytes(sTemplateWifi, TIME_FEB_15,
                     currentTimeMillis())).thenReturn(stats.getTotalBytes());
 
@@ -1483,7 +1483,7 @@
     }
 
     private PersistableBundle setupUpdateMobilePolicyCycleTests() throws RemoteException {
-        when(mConnManager.getAllNetworkStateSnapshot())
+        when(mConnManager.getAllNetworkStateSnapshots())
                 .thenReturn(new ArrayList<NetworkStateSnapshot>());
 
         setupTelephonySubscriptionManagers(FAKE_SUB_ID, FAKE_SUBSCRIBER_ID);
@@ -1496,7 +1496,7 @@
 
     @Test
     public void testUpdateMobilePolicyCycleWithNullConfig() throws RemoteException {
-        when(mConnManager.getAllNetworkStateSnapshot())
+        when(mConnManager.getAllNetworkStateSnapshots())
                 .thenReturn(new ArrayList<NetworkStateSnapshot>());
 
         setupTelephonySubscriptionManagers(FAKE_SUB_ID, FAKE_SUBSCRIBER_ID);
@@ -2089,7 +2089,7 @@
                 new Network(TEST_NET_ID),
                 buildNetworkCapabilities(TEST_SUB_ID, roaming),
                 buildLinkProperties(TEST_IFACE), TEST_IMSI, TYPE_MOBILE));
-        when(mConnManager.getAllNetworkStateSnapshot()).thenReturn(snapshots);
+        when(mConnManager.getAllNetworkStateSnapshots()).thenReturn(snapshots);
     }
 
     private void expectDefaultCarrierConfig() throws Exception {
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java
index 3deeea2..c2ead5f 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java
@@ -49,6 +49,7 @@
 
 import com.android.internal.util.FastXmlSerializer;
 import com.android.server.UiServiceTestCase;
+import com.android.server.pm.PackageManagerService;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -257,6 +258,17 @@
     }
 
     @Test
+    public void testSnoozeSentToAndroid() throws Exception {
+        NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM);
+        mSnoozeHelper.snooze(r, 1000);
+        ArgumentCaptor<PendingIntent> captor = ArgumentCaptor.forClass(PendingIntent.class);
+        verify(mAm, times(1)).setExactAndAllowWhileIdle(
+                anyInt(), anyLong(), captor.capture());
+        assertEquals(PackageManagerService.PLATFORM_PACKAGE_NAME,
+                captor.getValue().getIntent().getPackage());
+    }
+
+    @Test
     public void testSnooze() throws Exception {
         NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM);
         mSnoozeHelper.snooze(r, (String) null);
diff --git a/services/tests/wmtests/src/com/android/server/wm/LockTaskControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/LockTaskControllerTest.java
index e345bec..fdc01b4 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LockTaskControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LockTaskControllerTest.java
@@ -450,7 +450,7 @@
         Settings.Secure.clearProviderForTest();
 
         // AND a password is set
-        when(mLockPatternUtils.isSecure(anyInt()))
+        when(mLockPatternUtils.isSecure(TEST_USER_ID))
                 .thenReturn(true);
 
         // AND there is a task record
diff --git a/telecomm/java/android/telecom/CallScreeningService.java b/telecomm/java/android/telecom/CallScreeningService.java
index 7988b03..b980d3f 100644
--- a/telecomm/java/android/telecom/CallScreeningService.java
+++ b/telecomm/java/android/telecom/CallScreeningService.java
@@ -305,7 +305,7 @@
              * called with {@code false}, and all other parameters in this builder will be ignored.
              * <p>
              * This request will only be honored if the {@link CallScreeningService} shares the same
-             * uid as the default dialer app. Otherwise, the call will go through as usual.
+             * uid as the system dialer app. Otherwise, the call will go through as usual.
              * <p>
              * Apps built with SDK version {@link android.os.Build.VERSION_CODES#R} or later which
              * are using the microphone as part of audio processing should specify the
diff --git a/telecomm/java/android/telecom/CallerInfo.java b/telecomm/java/android/telecom/CallerInfo.java
index 2983e63..a63ee46 100644
--- a/telecomm/java/android/telecom/CallerInfo.java
+++ b/telecomm/java/android/telecom/CallerInfo.java
@@ -406,8 +406,7 @@
         // Change the callerInfo number ONLY if it is an emergency number
         // or if it is the voicemail number.  If it is either, take a
         // shortcut and skip the query.
-        TelephonyManager tm = context.getSystemService(TelephonyManager.class);
-        if (tm.isEmergencyNumber(number)) {
+        if (PhoneNumberUtils.isLocalEmergencyNumber(context, number)) {
             return new CallerInfo().markAsEmergency(context);
         } else if (PhoneNumberUtils.isVoiceMailNumber(null, subId, number)) {
             return new CallerInfo().markAsVoiceMail(context, subId);
diff --git a/telecomm/java/android/telecom/CallerInfoAsyncQuery.java b/telecomm/java/android/telecom/CallerInfoAsyncQuery.java
index a9e1a8f..bf49f3c 100644
--- a/telecomm/java/android/telecom/CallerInfoAsyncQuery.java
+++ b/telecomm/java/android/telecom/CallerInfoAsyncQuery.java
@@ -483,7 +483,16 @@
 
         // check to see if these are recognized numbers, and use shortcuts if we can.
         TelephonyManager tm = context.getSystemService(TelephonyManager.class);
-        if (tm.isEmergencyNumber(number)) {
+        boolean isEmergencyNumber = false;
+        try {
+            isEmergencyNumber = tm.isEmergencyNumber(number);
+        } catch (IllegalStateException ise) {
+            // Ignore the exception that Telephony is not up. Use PhoneNumberUtils API now.
+            // Ideally the PhoneNumberUtils API needs to be removed once the
+            // telphony service not up issue can be fixed (b/187412989)
+            isEmergencyNumber = PhoneNumberUtils.isLocalEmergencyNumber(context, number);
+        }
+        if (isEmergencyNumber) {
             cw.event = EVENT_EMERGENCY_NUMBER;
         } else if (PhoneNumberUtils.isVoiceMailNumber(context, subId, number)) {
             cw.event = EVENT_VOICEMAIL_NUMBER;
diff --git a/telecomm/java/android/telecom/Logging/Session.java b/telecomm/java/android/telecom/Logging/Session.java
index 4aa3614..e2fb601 100644
--- a/telecomm/java/android/telecom/Logging/Session.java
+++ b/telecomm/java/android/telecom/Logging/Session.java
@@ -453,19 +453,19 @@
 
     @Override
     public String toString() {
-        if (mParentSession != null && mIsStartedFromActiveSession) {
+        Session sessionToPrint = this;
+        if (getParentSession() != null && isStartedFromActiveSession()) {
             // Log.startSession was called from within another active session. Use the parent's
             // Id instead of the child to reduce confusion.
-            return mParentSession.toString();
-        } else {
-            StringBuilder methodName = new StringBuilder();
-            methodName.append(getFullMethodPath(false /*truncatePath*/));
-            if (mOwnerInfo != null && !mOwnerInfo.isEmpty()) {
-                methodName.append("(");
-                methodName.append(mOwnerInfo);
-                methodName.append(")");
-            }
-            return methodName.toString() + "@" + getFullSessionId();
+            sessionToPrint = getRootSession("toString");
         }
+        StringBuilder methodName = new StringBuilder();
+        methodName.append(sessionToPrint.getFullMethodPath(false /*truncatePath*/));
+        if (sessionToPrint.getOwnerInfo() != null && !sessionToPrint.getOwnerInfo().isEmpty()) {
+            methodName.append("(");
+            methodName.append(sessionToPrint.getOwnerInfo());
+            methodName.append(")");
+        }
+        return methodName.toString() + "@" + sessionToPrint.getFullSessionId();
     }
 }
diff --git a/telephony/common/android/telephony/LocationAccessPolicy.java b/telephony/common/android/telephony/LocationAccessPolicy.java
index 25b062f..502bfa3 100644
--- a/telephony/common/android/telephony/LocationAccessPolicy.java
+++ b/telephony/common/android/telephony/LocationAccessPolicy.java
@@ -86,8 +86,9 @@
             private String mCallingFeatureId;
             private int mCallingUid;
             private int mCallingPid;
-            private int mMinSdkVersionForCoarse = Integer.MAX_VALUE;
-            private int mMinSdkVersionForFine = Integer.MAX_VALUE;
+            private int mMinSdkVersionForCoarse = -1;
+            private int mMinSdkVersionForFine = -1;
+            private int mMinSdkVersionForEnforcement = -1;
             private boolean mLogAsInfo = false;
             private String mMethod;
 
@@ -125,7 +126,14 @@
 
             /**
              * Apps that target at least this sdk version will be checked for coarse location
-             * permission. Defaults to INT_MAX (which means don't check)
+             * permission. This method MUST be called before calling {@link #build()}. Otherwise, an
+             * {@link IllegalArgumentException} will be thrown.
+             *
+             * Additionally, if both the argument to this method and
+             * {@link #setMinSdkVersionForFine} are greater than {@link Build.VERSION_CODES#BASE},
+             * you must call {@link #setMinSdkVersionForEnforcement} with the min of the two to
+             * affirm that you do not want any location checks below a certain SDK version.
+             * Otherwise, {@link #build} will throw an {@link IllegalArgumentException}.
              */
             public Builder setMinSdkVersionForCoarse(
                     int minSdkVersionForCoarse) {
@@ -135,7 +143,14 @@
 
             /**
              * Apps that target at least this sdk version will be checked for fine location
-             * permission. Defaults to INT_MAX (which means don't check)
+             * permission.  This method MUST be called before calling {@link #build()}.
+             * Otherwise, an {@link IllegalArgumentException} will be thrown.
+             *
+             * Additionally, if both the argument to this method and
+             * {@link #setMinSdkVersionForCoarse} are greater than {@link Build.VERSION_CODES#BASE},
+             * you must call {@link #setMinSdkVersionForEnforcement} with the min of the two to
+             * affirm that you do not want any location checks below a certain SDK version.
+             * Otherwise, {@link #build} will throw an {@link IllegalArgumentException}.
              */
             public Builder setMinSdkVersionForFine(
                     int minSdkVersionForFine) {
@@ -144,6 +159,17 @@
             }
 
             /**
+             * If both the argument to {@link #setMinSdkVersionForFine} and
+             * {@link #setMinSdkVersionForCoarse} are greater than {@link Build.VERSION_CODES#BASE},
+             * this method must be called with the min of the two to
+             * affirm that you do not want any location checks below a certain SDK version.
+             */
+            public Builder setMinSdkVersionForEnforcement(int minSdkVersionForEnforcement) {
+                mMinSdkVersionForEnforcement = minSdkVersionForEnforcement;
+                return this;
+            }
+
+            /**
              * Optional, for logging purposes only.
              */
             public Builder setMethod(String method) {
@@ -161,6 +187,26 @@
 
             /** build LocationPermissionQuery */
             public LocationPermissionQuery build() {
+                if (mMinSdkVersionForCoarse < 0 || mMinSdkVersionForFine < 0) {
+                    throw new IllegalArgumentException("Must specify min sdk versions for"
+                            + " enforcement for both coarse and fine permissions");
+                }
+                if (mMinSdkVersionForFine > Build.VERSION_CODES.BASE
+                        && mMinSdkVersionForCoarse > Build.VERSION_CODES.BASE) {
+                    if (mMinSdkVersionForEnforcement != Math.min(
+                            mMinSdkVersionForCoarse, mMinSdkVersionForFine)) {
+                        throw new IllegalArgumentException("setMinSdkVersionForEnforcement must be"
+                                + " called.");
+                    }
+                }
+
+                if (mMinSdkVersionForFine < mMinSdkVersionForCoarse) {
+                    throw new IllegalArgumentException("Since fine location permission includes"
+                            + " access to coarse location, the min sdk level for enforcement of"
+                            + " the fine location permission must not be less than the min sdk"
+                            + " level for enforcement of the coarse location permission.");
+                }
+
                 return new LocationPermissionQuery(mCallingPackage, mCallingFeatureId,
                         mCallingUid, mCallingPid, mMinSdkVersionForCoarse, mMinSdkVersionForFine,
                         mLogAsInfo, mMethod);
diff --git a/telephony/common/com/android/internal/telephony/PackageChangeReceiver.java b/telephony/common/com/android/internal/telephony/PackageChangeReceiver.java
index 0b47547..e9b7d95 100644
--- a/telephony/common/com/android/internal/telephony/PackageChangeReceiver.java
+++ b/telephony/common/com/android/internal/telephony/PackageChangeReceiver.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.telephony;
+package com.android.internal.telephony;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
diff --git a/telephony/common/com/android/internal/telephony/SipMessageParsingUtils.java b/telephony/common/com/android/internal/telephony/SipMessageParsingUtils.java
index 179248d..804d1ed 100644
--- a/telephony/common/com/android/internal/telephony/SipMessageParsingUtils.java
+++ b/telephony/common/com/android/internal/telephony/SipMessageParsingUtils.java
@@ -17,6 +17,7 @@
 package com.android.internal.telephony;
 
 import android.net.Uri;
+import android.util.ArraySet;
 import android.util.Log;
 import android.util.Pair;
 
@@ -24,6 +25,8 @@
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
 
 /**
  * Utility methods for parsing parts of {@link android.telephony.ims.SipMessage}s.
@@ -70,6 +73,24 @@
     // compact form of the call-id header key
     private static final String CALL_ID_SIP_HEADER_KEY_COMPACT = "i";
 
+    // from header key
+    private static final String FROM_HEADER_KEY = "from";
+    // compact form of the from header key
+    private static final String FROM_HEADER_KEY_COMPACT = "f";
+
+    // to header key
+    private static final String TO_HEADER_KEY = "to";
+    // compact form of the to header key
+    private static final String TO_HEADER_KEY_COMPACT = "t";
+
+    // The tag parameter found in both the from and to headers
+    private static final String TAG_PARAM_KEY = "tag";
+
+    // accept-contact header key
+    private static final String ACCEPT_CONTACT_HEADER_KEY = "accept-contact";
+    // compact form of the accept-contact header key
+    private static final String ACCEPT_CONTACT_HEADER_KEY_COMPACT = "a";
+
     /**
      * @return true if the SIP message start line is considered a request (based on known request
      * methods).
@@ -81,6 +102,15 @@
     }
 
     /**
+     * @return true if the SIP message start line is considered a response.
+     */
+    public static boolean isSipResponse(String startLine) {
+        String[] splitLine = splitStartLineAndVerify(startLine);
+        if (splitLine == null) return false;
+        return verifySipResponse(splitLine);
+    }
+
+    /**
      * Return the via branch parameter, which is used to identify the transaction ID (request and
      * response pair) in a SIP transaction.
      * @param headerString The string containing the headers of the SIP message.
@@ -95,35 +125,42 @@
             // branch param YY1.
             String[] subHeaders = header.second.split(SUBHEADER_VALUE_SEPARATOR);
             for (String subHeader : subHeaders) {
-                // Search for ;branch=z9hG4bKXXXXXX and return parameter value
-                String[] params = subHeader.split(PARAM_SEPARATOR);
-                if (params.length < 2) {
-                    // This param doesn't include a branch param, move to next param.
-                    Log.w(TAG, "getTransactionId: via detected without branch param:"
-                            + subHeader);
-                    continue;
-                }
-                // by spec, each param can only appear once in a header.
-                for (String param : params) {
-                    String[] pair = param.split(PARAM_KEY_VALUE_SEPARATOR);
-                    if (pair.length < 2) {
-                        // ignore info before the first parameter
-                        continue;
-                    }
-                    if (pair.length > 2) {
-                        Log.w(TAG,
-                                "getTransactionId: unexpected parameter" + Arrays.toString(pair));
-                    }
-                    // Trim whitespace in parameter
-                    pair[0] = pair[0].trim();
-                    pair[1] = pair[1].trim();
-                    if (BRANCH_PARAM_KEY.equalsIgnoreCase(pair[0])) {
-                        // There can be multiple "Via" headers in the SIP message, however we want
-                        // to return the first once found, as this corresponds with the transaction
-                        // that is relevant here.
-                        return pair[1];
-                    }
-                }
+                String paramValue = getParameterValue(subHeader, BRANCH_PARAM_KEY);
+                if (paramValue == null) continue;
+                return paramValue;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Search a header's value for a specific parameter.
+     * @param headerValue The header key's value.
+     * @param parameterKey The parameter key we are looking for.
+     * @return The value associated with the specified parameter key or {@link null} if that key is
+     * not found.
+     */
+    private static String getParameterValue(String headerValue, String parameterKey) {
+        String[] params = headerValue.split(PARAM_SEPARATOR);
+        if (params.length < 2) {
+            return null;
+        }
+        // by spec, each param can only appear once in a header.
+        for (String param : params) {
+            String[] pair = param.split(PARAM_KEY_VALUE_SEPARATOR);
+            if (pair.length < 2) {
+                // ignore info before the first parameter
+                continue;
+            }
+            if (pair.length > 2) {
+                Log.w(TAG,
+                        "getParameterValue: unexpected parameter" + Arrays.toString(pair));
+            }
+            // Trim whitespace in parameter
+            pair[0] = pair[0].trim();
+            pair[1] = pair[1].trim();
+            if (parameterKey.equalsIgnoreCase(pair[0])) {
+                return pair[1];
             }
         }
         return null;
@@ -134,18 +171,105 @@
      * @param headerString The string containing the headers of the SIP message.
      */
     public static String getCallId(String headerString) {
-        // search for the call-Id header, there should only be one in the header.
+        // search for the call-Id header, there should only be one in the headers.
         List<Pair<String, String>> headers = parseHeaders(headerString, true,
                 CALL_ID_SIP_HEADER_KEY, CALL_ID_SIP_HEADER_KEY_COMPACT);
         return !headers.isEmpty() ? headers.get(0).second : null;
     }
 
-    private static String[] splitStartLineAndVerify(String startLine) {
-        String[] splitLine = startLine.split(" ");
+    /**
+     * @return Return the from header's tag parameter or {@code null} if it doesn't exist.
+     */
+    public static String getFromTag(String headerString) {
+        // search for the from header, there should only be one in the headers.
+        List<Pair<String, String>> headers = parseHeaders(headerString, true,
+                FROM_HEADER_KEY, FROM_HEADER_KEY_COMPACT);
+        if (headers.isEmpty()) {
+            return null;
+        }
+        // There should only be one from header in the SIP message
+        return getParameterValue(headers.get(0).second, TAG_PARAM_KEY);
+    }
+
+    /**
+     * @return Return the to header's tag parameter or {@code null} if it doesn't exist.
+     */
+    public static String getToTag(String headerString) {
+        // search for the to header, there should only be one in the headers.
+        List<Pair<String, String>> headers = parseHeaders(headerString, true,
+                TO_HEADER_KEY, TO_HEADER_KEY_COMPACT);
+        if (headers.isEmpty()) {
+            return null;
+        }
+        // There should only be one from header in the SIP message
+        return getParameterValue(headers.get(0).second, TAG_PARAM_KEY);
+    }
+
+    /**
+     * Validate that the start line is correct and split into its three segments.
+     * @param startLine The start line to verify and split.
+     * @return The split start line, which will always have three segments.
+     */
+    public static String[] splitStartLineAndVerify(String startLine) {
+        String[] splitLine = startLine.split(" ", 3);
         if (isStartLineMalformed(splitLine)) return null;
         return splitLine;
     }
 
+
+    /**
+     * @return All feature tags starting with "+" in the Accept-Contact header.
+     */
+    public static Set<String> getAcceptContactFeatureTags(String headerString) {
+        List<Pair<String, String>> headers = SipMessageParsingUtils.parseHeaders(headerString,
+                false, ACCEPT_CONTACT_HEADER_KEY, ACCEPT_CONTACT_HEADER_KEY_COMPACT);
+        if (headerString.isEmpty()) {
+            return Collections.emptySet();
+        }
+        Set<String> featureTags = new ArraySet<>();
+        for (Pair<String, String> header : headers) {
+            String[] splitParams = header.second.split(PARAM_SEPARATOR);
+            if (splitParams.length < 2) {
+                continue;
+            }
+            // Start at 1 here, since the first entry is the header value and not params.
+            // We only care about IMS feature tags here, so filter tags with a "+"
+            Set<String> fts = Arrays.asList(splitParams).subList(1, splitParams.length).stream()
+                    .map(String::trim).filter(p -> p.startsWith("+")).collect(Collectors.toSet());
+            for (String ft : fts) {
+                String[] paramKeyValue = ft.split(PARAM_KEY_VALUE_SEPARATOR, 2);
+                if (paramKeyValue.length < 2) {
+                    featureTags.add(ft);
+                    continue;
+                }
+                // Splits keys like +a="b,c" into +a="b" and +a="c"
+                String[] splitValue = splitParamValue(paramKeyValue[1]);
+                for (String value : splitValue) {
+                    featureTags.add(paramKeyValue[0] + PARAM_KEY_VALUE_SEPARATOR + value);
+                }
+            }
+        }
+        return featureTags;
+    }
+
+    /**
+     * Takes a string such as "\"a,b,c,d\"" and splits it by "," into a String array of
+     * [\"a\", \"b\", \"c\", \"d\"]
+     */
+    private static String[] splitParamValue(String paramValue) {
+        if (!paramValue.startsWith("\"") && !paramValue.endsWith("\"")) {
+            return new String[] {paramValue};
+        }
+        // Remove quotes on outside
+        paramValue = paramValue.substring(1, paramValue.length() - 1);
+        String[] splitValues = paramValue.split(",");
+        for (int i = 0; i < splitValues.length; i++) {
+            // Encapsulate each split value in its own quotations.
+            splitValues[i] = "\"" + splitValues[i] + "\"";
+        }
+        return splitValues;
+    }
+
     private static boolean isStartLineMalformed(String[] startLine) {
         if (startLine == null || startLine.length == 0)  {
             return true;
@@ -158,18 +282,27 @@
 
     private static boolean verifySipRequest(String[] request) {
         // Request-Line  =  Method SP Request-URI SP SIP-Version CRLF
-        boolean verified = request[2].contains(SIP_VERSION_2);
-        verified &= (Uri.parse(request[1]).getScheme() != null);
+        if (!request[2].contains(SIP_VERSION_2)) return false;
+        boolean verified;
+        try {
+            verified = (Uri.parse(request[1]).getScheme() != null);
+        } catch (NumberFormatException e) {
+            return false;
+        }
         verified &= Arrays.stream(SIP_REQUEST_METHODS).anyMatch(s -> request[0].contains(s));
         return verified;
     }
 
     private static boolean verifySipResponse(String[] response) {
         // Status-Line = SIP-Version SP Status-Code SP Reason-Phrase CRLF
-        boolean verified = response[0].contains(SIP_VERSION_2);
-        int statusCode = Integer.parseInt(response[1]);
-        verified &= (statusCode >= 100  && statusCode < 700);
-        return verified;
+        if (!response[0].contains(SIP_VERSION_2)) return false;
+        int statusCode;
+        try {
+            statusCode = Integer.parseInt(response[1]);
+        } catch (NumberFormatException e) {
+            return false;
+        }
+        return (statusCode >= 100  && statusCode < 700);
     }
 
     /**
@@ -184,7 +317,7 @@
      *                           (This is internally an equalsIgnoreMatch comparison).
      * @return the matched header keys and values.
      */
-    private static List<Pair<String, String>> parseHeaders(String headerString,
+    public static List<Pair<String, String>> parseHeaders(String headerString,
             boolean stopAtFirstMatch, String... matchingHeaderKeys) {
         // Ensure there is no leading whitespace
         headerString = removeLeadingWhitespace(headerString);
diff --git a/telephony/common/com/android/internal/telephony/SmsApplication.java b/telephony/common/com/android/internal/telephony/SmsApplication.java
index b8b60da..16614c8 100644
--- a/telephony/common/com/android/internal/telephony/SmsApplication.java
+++ b/telephony/common/com/android/internal/telephony/SmsApplication.java
@@ -40,7 +40,6 @@
 import android.os.UserHandle;
 import android.provider.Telephony;
 import android.provider.Telephony.Sms.Intents;
-import android.telephony.PackageChangeReceiver;
 import android.telephony.TelephonyManager;
 import android.util.Log;
 
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 210e4a5..f6ba7be 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -4106,6 +4106,26 @@
         public static final String KEY_RCS_FEATURE_TAG_ALLOWED_STRING_ARRAY =
                 KEY_PREFIX + "rcs_feature_tag_allowed_string_array";
 
+        /**
+         * Flag indicating whether or not carrier forbids device send the RCS request when the
+         * device receive the network response with the SIP code 489 BAD EVENT.
+         * <p>
+         * The default value for this key is {@code false}.
+         * @hide
+         */
+        public static final String KEY_RCS_REQUEST_FORBIDDEN_BY_SIP_489_BOOL =
+                KEY_PREFIX + "rcs_request_forbidden_by_sip_489_bool";
+
+        /**
+         * Indicates the interval that SUBSCRIBE requests from applications will be retried at when
+         * the carrier network has responded to a previous request with a forbidden error.
+         * <p>
+         * The default value for this key is 20 minutes.
+         * @hide
+         */
+        public static final String KEY_RCS_REQUEST_RETRY_INTERVAL_MILLIS_LONG =
+                KEY_PREFIX + "rcs_request_retry_interval_millis_long";
+
         private Ims() {}
 
         private static PersistableBundle getDefaults() {
@@ -4119,6 +4139,8 @@
             defaults.putBoolean(KEY_RCS_BULK_CAPABILITY_EXCHANGE_BOOL, false);
             defaults.putBoolean(KEY_ENABLE_PRESENCE_GROUP_SUBSCRIBE_BOOL, true);
             defaults.putInt(KEY_NON_RCS_CAPABILITIES_CACHE_EXPIRATION_SEC_INT, 30 * 24 * 60 * 60);
+            defaults.putBoolean(KEY_RCS_REQUEST_FORBIDDEN_BY_SIP_489_BOOL, false);
+            defaults.putLong(KEY_RCS_REQUEST_RETRY_INTERVAL_MILLIS_LONG, 20 * 60 * 1000);
             defaults.putStringArray(KEY_RCS_FEATURE_TAG_ALLOWED_STRING_ARRAY, new String[]{
                     "+g.3gpp.icsi-ref=\"urn%3Aurn-7%3A3gpp-service.ims.icsi.oma.cpm.msg\"",
                     "+g.3gpp.icsi-ref=\"urn%3Aurn-7%3A3gpp-service.ims.icsi.oma.cpm.largemsg\"",
@@ -4367,6 +4389,14 @@
     public static final String KEY_DISPLAY_NO_DATA_NOTIFICATION_ON_PERMANENT_FAILURE_BOOL =
             "display_no_data_notification_on_permanent_failure_bool";
 
+    /**
+     * Determine whether unthrottle data retry when tracking area code (TAC/LAC) from cell changes
+     *
+     * @hide
+     */
+    public static final String KEY_UNTHROTTLE_DATA_RETRY_WHEN_TAC_CHANGES_BOOL =
+            "unthrottle_data_retry_when_tac_changes_bool";
+
     /** The default value for every variable. */
     private final static PersistableBundle sDefaults;
 
@@ -4934,6 +4964,7 @@
         sDefaults.putBoolean(KEY_STORE_SIM_PIN_FOR_UNATTENDED_REBOOT_BOOL, true);
         sDefaults.putBoolean(KEY_HIDE_ENABLE_2G, false);
         sDefaults.putBoolean(KEY_DISPLAY_NO_DATA_NOTIFICATION_ON_PERMANENT_FAILURE_BOOL, false);
+        sDefaults.putBoolean(KEY_UNTHROTTLE_DATA_RETRY_WHEN_TAC_CHANGES_BOOL, false);
     }
 
     /**
diff --git a/telephony/java/android/telephony/CellIdentityNr.java b/telephony/java/android/telephony/CellIdentityNr.java
index 0dfc7f6..b3ec1f0 100644
--- a/telephony/java/android/telephony/CellIdentityNr.java
+++ b/telephony/java/android/telephony/CellIdentityNr.java
@@ -231,7 +231,7 @@
     }
 
     /**
-     * @return Mobile Network Code in string fomrat, or {@code null} if unknown.
+     * @return Mobile Network Code in string format, or {@code null} if unknown.
      */
     @Nullable
     public String getMncString() {
diff --git a/telephony/java/android/telephony/PhysicalChannelConfig.java b/telephony/java/android/telephony/PhysicalChannelConfig.java
index 1c9cd94..8a4bb46 100644
--- a/telephony/java/android/telephony/PhysicalChannelConfig.java
+++ b/telephony/java/android/telephony/PhysicalChannelConfig.java
@@ -182,16 +182,6 @@
     }
 
     /**
-     * @return the absolute radio frequency channel number for this physical channel,
-     * {@link #CHANNEL_NUMBER_UNKNOWN} if unknown.
-     * @deprecated Use {@link #getDownlinkChannelNumber()} to get the channel number.
-     */
-    @Deprecated
-    public int getChannelNumber() {
-        return getDownlinkChannelNumber();
-    }
-
-    /**
      * @return the rough frequency range for this physical channel,
      * {@link ServiceState#FREQUENCY_RANGE_UNKNOWN} if unknown.
      * @see {@link ServiceState#FREQUENCY_RANGE_LOW}
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 2908e94..06a2648 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -47,6 +47,7 @@
 import android.net.Uri;
 import android.os.Binder;
 import android.os.Build;
+import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.ParcelUuid;
@@ -55,6 +56,7 @@
 import android.provider.Telephony.SimInfo;
 import android.telephony.euicc.EuiccManager;
 import android.telephony.ims.ImsMmTelManager;
+import android.util.Base64;
 import android.util.Log;
 import android.util.Pair;
 
@@ -66,6 +68,11 @@
 import com.android.internal.util.Preconditions;
 import com.android.telephony.Rlog;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
@@ -150,6 +157,22 @@
     public static final String CACHE_KEY_SLOT_INDEX_PROPERTY =
             "cache_key.telephony.get_slot_index";
 
+    /** @hide */
+    public static final String GET_SIM_SPECIFIC_SETTINGS_METHOD_NAME = "getSimSpecificSettings";
+
+    /** @hide */
+    public static final String RESTORE_SIM_SPECIFIC_SETTINGS_METHOD_NAME =
+            "restoreSimSpecificSettings";
+
+    /**
+     * Key to the backup & restore data byte array in the Bundle that is returned by {@link
+     * #getAllSimSpecificSettingsForBackup()} or to be pass in to {@link
+     * #restoreAllSimSpecificSettings()}.
+     *
+     * @hide
+     */
+    public static final String KEY_SIM_SPECIFIC_SETTINGS_DATA = "KEY_SIM_SPECIFIC_SETTINGS_DATA";
+
     private static final int MAX_CACHE_SIZE = 4;
 
     private static class VoidPropertyInvalidatedCache<T>
@@ -372,6 +395,28 @@
     public static final Uri WFC_ROAMING_ENABLED_CONTENT_URI = Uri.withAppendedPath(
             CONTENT_URI, "wfc_roaming_enabled");
 
+
+    /**
+     * A content {@link uri} used to call the appropriate backup or restore method for sim-specific
+     * settings
+     * <p>
+     * See {@link #GET_SIM_SPECIFIC_SETTINGS_METHOD_NAME} and {@link
+     * #RESTORE_SIM_SPECIFIC_SETTINGS_METHOD_NAME} for information on what method to call.
+     * @hide
+     */
+    @NonNull
+    public static final Uri SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI = Uri.withAppendedPath(
+            CONTENT_URI, "backup_and_restore");
+
+    /**
+     * A content {@link uri} used to notify contentobservers listening to siminfo restore during
+     * SuW.
+     * @hide
+     */
+    @NonNull
+    public static final Uri SIM_INFO_SUW_RESTORE_CONTENT_URI = Uri.withAppendedPath(
+            SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI, "suw_restore");
+
     /**
      * TelephonyProvider unique key column name is the subscription id.
      * <P>Type: TEXT (String)</P>
@@ -543,6 +588,50 @@
     public @interface SimDisplayNameSource {}
 
     /**
+     * Device status is not shared to a remote party.
+     */
+    public static final int D2D_SHARING_DISABLED = 0;
+
+    /**
+     * Device status is shared with all numbers in the user's contacts.
+     */
+    public static final int D2D_SHARING_ALL_CONTACTS = 1;
+
+    /**
+     * Device status is shared with all selected contacts.
+     */
+    public static final int D2D_SHARING_SELECTED_CONTACTS = 2;
+
+    /**
+     * Device status is shared whenever possible.
+     */
+    public static final int D2D_SHARING_ALL = 3;
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = {"D2D_SHARING_"},
+            value = {
+                    D2D_SHARING_DISABLED,
+                    D2D_SHARING_ALL_CONTACTS,
+                    D2D_SHARING_SELECTED_CONTACTS,
+                    D2D_SHARING_ALL
+            })
+    public @interface DeviceToDeviceStatusSharing {}
+
+    /**
+     * TelephonyProvider column name for device to device sharing status.
+     * <P>Type: INTEGER (int)</P>
+     */
+    public static final String D2D_STATUS_SHARING = SimInfo.COLUMN_D2D_STATUS_SHARING;
+
+    /**
+     * TelephonyProvider column name for contacts information that allow device to device sharing.
+     * <P>Type: TEXT (String)</P>
+     */
+    public static final String D2D_STATUS_SHARING_SELECTED_CONTACTS =
+            SimInfo.COLUMN_D2D_STATUS_SHARING_SELECTED_CONTACTS;
+
+    /**
      * TelephonyProvider column name for the color of a SIM.
      * <P>Type: INTEGER (int)</P>
      */
@@ -832,6 +921,14 @@
     public static final String PROFILE_CLASS = SimInfo.COLUMN_PROFILE_CLASS;
 
     /**
+     * TelephonyProvider column name for VoIMS opt-in status.
+     *
+     * <P>Type: INTEGER (int)</P>
+     * @hide
+     */
+    public static final String VOIMS_OPT_IN_STATUS = SimInfo.COLUMN_VOIMS_OPT_IN_STATUS;
+
+    /**
      * Profile class of the subscription
      * @hide
      */
@@ -2335,6 +2432,57 @@
     }
 
     /**
+     * Serialize list of contacts uri to string
+     * @hide
+     */
+    public static String serializeUriLists(List<Uri> uris) {
+        List<String> contacts = new ArrayList<>();
+        for (Uri uri : uris) {
+            contacts.add(uri.toString());
+        }
+        try {
+            ByteArrayOutputStream bos = new ByteArrayOutputStream();
+            ObjectOutputStream oos = new ObjectOutputStream(bos);
+            oos.writeObject(contacts);
+            oos.flush();
+            return Base64.encodeToString(bos.toByteArray(), Base64.DEFAULT);
+        } catch (IOException e) {
+            logd("serializeUriLists IO exception");
+        }
+        return "";
+    }
+
+    /**
+     * Return list of contacts uri corresponding to query result.
+     * @param subId Subscription Id of Subscription
+     * @param propKey Column name in SubscriptionInfo database
+     * @return list of contacts uri to be returned
+     * @hide
+     */
+    private static List<Uri> getContactsFromSubscriptionProperty(int subId, String propKey,
+            Context context) {
+        String result = getSubscriptionProperty(subId, propKey, context);
+        if (result != null) {
+            try {
+                byte[] b = Base64.decode(result, Base64.DEFAULT);
+                ByteArrayInputStream bis = new ByteArrayInputStream(b);
+                ObjectInputStream ois = new ObjectInputStream(bis);
+                List<String> contacts = ArrayList.class.cast(ois.readObject());
+                List<Uri> uris = new ArrayList<>();
+                for (String contact : contacts) {
+                    uris.add(Uri.parse(contact));
+                }
+                return uris;
+            } catch (IOException e) {
+                logd("getContactsFromSubscriptionProperty IO exception");
+            } catch (ClassNotFoundException e) {
+                logd("getContactsFromSubscriptionProperty ClassNotFound exception");
+            }
+        }
+        return new ArrayList<>();
+    }
+
+    /**
      * Store properties associated with SubscriptionInfo in database
      * @param subId Subscription Id of Subscription
      * @param propKey Column name in SubscriptionInfo database
@@ -3318,6 +3466,70 @@
     }
 
     /**
+     * Set the device to device status sharing user preference for a subscription ID. The setting
+     * app uses this method to indicate with whom they wish to share device to device status
+     * information.
+     * @param sharing the status sharing preference
+     * @param subId the unique Subscription ID in database
+     */
+    @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
+    public void setDeviceToDeviceStatusSharing(@DeviceToDeviceStatusSharing int sharing,
+            int subId) {
+        if (VDBG) {
+            logd("[setDeviceToDeviceStatusSharing] + sharing: " + sharing + " subId: " + subId);
+        }
+        setSubscriptionPropertyHelper(subId, "setDeviceToDeviceSharingStatus",
+                (iSub)->iSub.setDeviceToDeviceStatusSharing(sharing, subId));
+    }
+
+    /**
+     * Returns the user-chosen device to device status sharing preference
+     * @param subId Subscription id of subscription
+     * @return The device to device status sharing preference
+     */
+    public @DeviceToDeviceStatusSharing int getDeviceToDeviceStatusSharing(int subId) {
+        if (VDBG) {
+            logd("[getDeviceToDeviceStatusSharing] + subId: " + subId);
+        }
+        return getIntegerSubscriptionProperty(subId, D2D_STATUS_SHARING, D2D_SHARING_DISABLED,
+                mContext);
+    }
+
+    /**
+     * Set the list of contacts that allow device to device status sharing for a subscription ID.
+     * The setting app uses this method to indicate with whom they wish to share device to device
+     * status information.
+     * @param contacts The list of contacts that allow device to device status sharing
+     * @param subscriptionId The unique Subscription ID in database
+     */
+    @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
+    public void setDeviceToDeviceStatusSharingContacts(@NonNull List<Uri> contacts,
+            int subscriptionId) {
+        String contactString = serializeUriLists(contacts);
+        if (VDBG) {
+            logd("[setDeviceToDeviceStatusSharingContacts] + contacts: " + contactString
+                    + " subId: " + subscriptionId);
+        }
+        setSubscriptionPropertyHelper(subscriptionId, "setDeviceToDeviceSharingStatus",
+                (iSub)->iSub.setDeviceToDeviceStatusSharingContacts(serializeUriLists(contacts),
+                        subscriptionId));
+    }
+
+    /**
+     * Returns the list of contacts that allow device to device status sharing.
+     * @param subscriptionId Subscription id of subscription
+     * @return The list of contacts that allow device to device status sharing
+     */
+    public @NonNull List<Uri> getDeviceToDeviceStatusSharingContacts(
+            int subscriptionId) {
+        if (VDBG) {
+            logd("[getDeviceToDeviceStatusSharingContacts] + subId: " + subscriptionId);
+        }
+        return getContactsFromSubscriptionProperty(subscriptionId,
+                D2D_STATUS_SHARING_SELECTED_CONTACTS, mContext);
+    }
+
+    /**
      * DO NOT USE.
      * This API is designed for features that are not finished at this point. Do not call this API.
      * @hide
@@ -3446,4 +3658,71 @@
         sSlotIndexCache.clear();
         sPhoneIdCache.clear();
     }
+
+    /**
+     * Called to retrieve SIM-specific settings data to be backed up.
+     *
+     * @return data in byte[] to be backed up.
+     *
+     * @hide
+     */
+    @NonNull
+    @SystemApi
+    @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    public byte[] getAllSimSpecificSettingsForBackup() {
+        Bundle bundle =  mContext.getContentResolver().call(
+                SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI,
+                GET_SIM_SPECIFIC_SETTINGS_METHOD_NAME, null, null);
+        return bundle.getByteArray(SubscriptionManager.KEY_SIM_SPECIFIC_SETTINGS_DATA);
+    }
+
+    /**
+     * Called to attempt to restore the backed up sim-specific configs to device for specific sim.
+     * This will try to restore the data that was stored internally when {@link
+     * #restoreAllSimSpecificSettingsFromBackup(byte[] data)} was called during setup wizard.
+     * End result is SimInfoDB is modified to match any backed up configs for the requested
+     * inserted sim.
+     *
+     * <p>
+     * The {@link Uri} {@link #SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI} is notified if any SimInfoDB
+     * entry is updated as the result of this method call.
+     *
+     * @param iccId of the sim that a restore is requested for.
+     *
+     * @hide
+     */
+    @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
+    public void restoreSimSpecificSettingsForIccIdFromBackup(@NonNull String iccId) {
+        mContext.getContentResolver().call(
+                SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI,
+                RESTORE_SIM_SPECIFIC_SETTINGS_METHOD_NAME,
+                iccId, null);
+    }
+
+    /**
+     * Called during setup wizard restore flow to attempt to restore the backed up sim-specific
+     * configs to device for all existing SIMs in SimInfoDB. Internally, it will store the backup
+     * data in an internal file. This file will persist on device for device's lifetime and will be
+     * used later on when a SIM is inserted to restore that specific SIM's settings by calling
+     * {@link #restoreSimSpecificSettingsForIccIdFromBackup(String iccId)}. End result is
+     * SimInfoDB is modified to match any backed up configs for the appropriate inserted SIMs.
+     *
+     * <p>
+     * The {@link Uri} {@link #SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI} is notified if any SimInfoDB
+     * entry is updated as the result of this method call.
+     *
+     * @param data with the sim specific configs to be backed up.
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
+    public void restoreAllSimSpecificSettingsFromBackup(@NonNull byte[] data) {
+        Bundle bundle = new Bundle();
+        bundle.putByteArray(KEY_SIM_SPECIFIC_SETTINGS_DATA, data);
+        mContext.getContentResolver().call(
+                SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI,
+                RESTORE_SIM_SPECIFIC_SETTINGS_METHOD_NAME,
+                null, bundle);
+    }
 }
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 1cfb1d4..ae6a3e8 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -11205,26 +11205,26 @@
     }
 
     /**
-     * Return a list of certs in hex string from loaded carrier privileges access rules.
+     * Return a list of certs as hex strings from loaded carrier privileges access rules.
      *
-     * @return a list of certificate in hex string. return {@code null} if there is no certs
-     * or privilege rules are not loaded yet.
-     *
-     * <p>Requires Permission:
-     * {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE}
+     * @return a list of certificates as hex strings, or an empty list if there are no certs or
+     *     privilege rules are not loaded yet.
      * @hide
      */
+    @TestApi
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @NonNull
     public List<String> getCertsFromCarrierPrivilegeAccessRules() {
+        List<String> certs = null;
         try {
             ITelephony service = getITelephony();
             if (service != null) {
-                return service.getCertsFromCarrierPrivilegeAccessRules(getSubId());
+                certs = service.getCertsFromCarrierPrivilegeAccessRules(getSubId());
             }
         } catch (RemoteException ex) {
             // This could happen if binder process crashes.
         }
-        return null;
+        return certs == null ? Collections.emptyList() : certs;
     }
 
     /**
diff --git a/telephony/java/android/telephony/ims/DelegateMessageCallback.java b/telephony/java/android/telephony/ims/DelegateMessageCallback.java
index 0d82a54..a008cfd 100644
--- a/telephony/java/android/telephony/ims/DelegateMessageCallback.java
+++ b/telephony/java/android/telephony/ims/DelegateMessageCallback.java
@@ -35,12 +35,12 @@
 public interface DelegateMessageCallback {
 
     /**
-     * Send a new incoming SIP message to the remote application for processing.
+     * Sends a new incoming SIP message to the remote application for processing.
      */
     void onMessageReceived(@NonNull SipMessage message);
 
     /**
-     * Notify the remote application that a previous request to send a SIP message using
+     * Notifies the remote application that a previous request to send a SIP message using
      * {@link SipDelegate#sendMessage} has succeeded.
      *
      * @param viaTransactionId The transaction ID found in the via header field of the
@@ -49,7 +49,7 @@
     void onMessageSent(@NonNull String viaTransactionId);
 
     /**
-     * Notify the remote application that a previous request to send a SIP message using
+     * Notifies the remote application that a previous request to send a SIP message using
      * {@link SipDelegate#sendMessage} has failed.
      *
      * @param viaTransactionId The Transaction ID found in the via header field of the previously
diff --git a/telephony/java/android/telephony/ims/ImsMmTelManager.java b/telephony/java/android/telephony/ims/ImsMmTelManager.java
index d1a893f..7403327 100644
--- a/telephony/java/android/telephony/ims/ImsMmTelManager.java
+++ b/telephony/java/android/telephony/ims/ImsMmTelManager.java
@@ -713,15 +713,8 @@
      * @see android.telephony.CarrierConfigManager#KEY_CARRIER_VT_AVAILABLE_BOOL
      * @see android.telephony.CarrierConfigManager#KEY_CARRIER_IMS_GBA_REQUIRED_BOOL
      * @see #isAvailable(int, int)
-     *
-     * @param imsRegTech The IMS registration technology, can be one of the following:
-     *         {@link ImsRegistrationImplBase#REGISTRATION_TECH_LTE},
-     *         {@link ImsRegistrationImplBase#REGISTRATION_TECH_IWLAN}
-     * @param capability The IMS MmTel capability to query, can be one of the following:
-     *         {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_VOICE},
-     *         {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_VIDEO},
-     *         {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_UT},
-     *         {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_SMS}
+     * @param imsRegTech The IMS registration technology.
+     * @param capability The IMS MmTel capability to query.
      * @return {@code true} if the MmTel IMS capability is capable for this subscription, false
      *         otherwise.
      * @hide
@@ -748,14 +741,8 @@
      *
      * @see #isCapable(int, int)
      *
-     * @param imsRegTech The IMS registration technology, can be one of the following:
-     *         {@link ImsRegistrationImplBase#REGISTRATION_TECH_LTE},
-     *         {@link ImsRegistrationImplBase#REGISTRATION_TECH_IWLAN}
-     * @param capability The IMS MmTel capability to query, can be one of the following:
-     *         {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_VOICE},
-     *         {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_VIDEO},
-     *         {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_UT},
-     *         {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_SMS}
+     * @param imsRegTech The IMS registration technology.
+     * @param capability The IMS MmTel capability to query.
      * @return {@code true} if the MmTel IMS capability is available for this subscription, false
      *         otherwise.
      * @hide
diff --git a/telephony/java/android/telephony/ims/ProvisioningManager.java b/telephony/java/android/telephony/ims/ProvisioningManager.java
index 1e80ab7..c420f35 100644
--- a/telephony/java/android/telephony/ims/ProvisioningManager.java
+++ b/telephony/java/android/telephony/ims/ProvisioningManager.java
@@ -866,6 +866,19 @@
     public static final int KEY_VOICE_OVER_WIFI_ENTITLEMENT_ID = 67;
 
     /**
+     * An integer key representing the voice over IMS opt-in provisioning status for the
+     * associated subscription. Determines whether the user can see for voice services over
+     * IMS.
+     * <p>
+     * Use {@link #PROVISIONING_VALUE_ENABLED} to enable VoIMS provisioning and
+     * {@link #PROVISIONING_VALUE_DISABLED} to disable VoIMS  provisioning.
+     * @see #setProvisioningIntValue(int, int)
+     * @see #getProvisioningIntValue(int)
+     * @hide
+     */
+    public static final int KEY_VOIMS_OPT_IN_STATUS = 68;
+
+    /**
      * Callback for IMS provisioning changes.
      */
     public static class Callback {
diff --git a/telephony/java/android/telephony/ims/RcsConfig.java b/telephony/java/android/telephony/ims/RcsConfig.java
index 8a31211..6867c86 100644
--- a/telephony/java/android/telephony/ims/RcsConfig.java
+++ b/telephony/java/android/telephony/ims/RcsConfig.java
@@ -22,10 +22,10 @@
 import android.content.Context;
 import android.database.Cursor;
 import android.os.Build;
-import android.os.Parcel;
-import android.os.Parcelable;
 import android.provider.Telephony.SimInfo;
 import android.text.TextUtils;
+import android.util.ArrayMap;
+import android.util.ArraySet;
 
 import com.android.telephony.Rlog;
 
@@ -36,7 +36,9 @@
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
-import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
 import java.util.zip.GZIPInputStream;
 import java.util.zip.GZIPOutputStream;
 
@@ -44,23 +46,138 @@
  * RCS config data and methods to process the config
  * @hide
  */
-public final class RcsConfig implements Parcelable {
+public final class RcsConfig {
     private static final String LOG_TAG = "RcsConfig";
     private static final boolean DBG = Build.IS_ENG;
 
-    // Tag for Rcs Volte single registration defined in RCC.07 A.1.6.2
-    private static final String TAG_SINGLE_REGISTRATION = "rcsVolteSingleRegistration";
+    // Tag and attribute defined in RCC.07 A.2
+    private static final String TAG_CHARACTERISTIC = "characteristic";
+    private static final String TAG_PARM = "parm";
+    private static final String ATTRIBUTE_TYPE = "type";
+    private static final String ATTRIBUTE_NAME = "name";
+    private static final String ATTRIBUTE_VALUE = "value";
+    // Keyword for Rcs Volte single registration defined in RCC.07 A.1.6.2
+    private static final String PARM_SINGLE_REGISTRATION = "rcsVolteSingleRegistration";
 
-    private final HashMap<String, String> mValues = new HashMap<>();
+    /**
+     * Characteristic of the RCS provisioning config
+     */
+    public static class Characteristic {
+        private String mType;
+        private final Map<String, String> mParms = new ArrayMap<>();
+        private final Set<Characteristic> mSubs = new ArraySet<>();
+        private final Characteristic mParent;
 
-    private RcsConfig(HashMap<String, String> values) {
-        mValues.putAll(values);
+        private Characteristic(String type, Characteristic parent) {
+            mType = type;
+            mParent = parent;
+        }
+
+        private String getType() {
+            return mType;
+        }
+
+        private Map<String, String> getParms() {
+            return mParms;
+        }
+
+        private Set<Characteristic> getSubs() {
+            return mSubs;
+        }
+
+        private Characteristic getParent() {
+            return mParent;
+        }
+
+        private Characteristic getSubByType(String type) {
+            if (TextUtils.equals(mType, type)) {
+                return this;
+            }
+            Characteristic result = null;
+            for (Characteristic sub : mSubs) {
+                result = sub.getSubByType(type);
+                if (result != null) {
+                    break;
+                }
+            }
+            return result;
+        }
+
+        private boolean hasSubByType(String type) {
+            return getSubByType(type) != null;
+        }
+
+        private String getParmValue(String name) {
+            String value = mParms.get(name);
+            if (value == null) {
+                for (Characteristic sub : mSubs) {
+                    value = sub.getParmValue(name);
+                    if (value != null) {
+                        break;
+                    }
+                }
+            }
+            return value;
+        }
+
+        boolean hasParm(String name) {
+            if (mParms.containsKey(name)) {
+                return true;
+            }
+
+            for (Characteristic sub : mSubs) {
+                if (sub.hasParm(name)) {
+                    return true;
+                }
+            }
+
+            return false;
+        }
+
+        @Override
+        public String toString() {
+            final StringBuilder sb = new StringBuilder();
+            sb.append("[" + mType + "]: ");
+            if (DBG) {
+                sb.append(mParms);
+            }
+            for (Characteristic sub : mSubs) {
+                sb.append("\n");
+                sb.append(sub.toString().replace("\n", "\n\t"));
+            }
+            return sb.toString();
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (!(obj instanceof Characteristic)) {
+                return false;
+            }
+
+            Characteristic o = (Characteristic) obj;
+
+            return TextUtils.equals(mType, o.mType) && mParms.equals(o.mParms)
+                    && mSubs.equals(o.mSubs);
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(mType, mParms, mSubs);
+        }
     }
 
+    private final Characteristic mRoot;
+    private Characteristic mCurrent;
+    private final byte[] mData;
+
     public RcsConfig(byte[] data) throws IllegalArgumentException {
         if (data == null || data.length == 0) {
             throw new IllegalArgumentException("Empty data");
         }
+        mRoot = new Characteristic(null, null);
+        mCurrent = mRoot;
+        mData = data;
+        Characteristic current = mRoot;
         ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
         try {
             XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
@@ -69,16 +186,51 @@
             xpp.setInput(inputStream, null);
             int eventType = xpp.getEventType();
             String tag = null;
-            while (eventType != XmlPullParser.END_DOCUMENT) {
+            while (eventType != XmlPullParser.END_DOCUMENT && current != null) {
                 if (eventType == XmlPullParser.START_TAG) {
-                    tag = xpp.getName().trim();
-                } else if (eventType == XmlPullParser.END_TAG) {
-                    tag = null;
-                } else if (eventType == XmlPullParser.TEXT) {
-                    String value = xpp.getText().trim();
-                    if (!TextUtils.isEmpty(tag) && !TextUtils.isEmpty(value)) {
-                        mValues.put(tag, value);
+                    tag = xpp.getName().trim().toLowerCase();
+                    if (TAG_CHARACTERISTIC.equals(tag)) {
+                        int count = xpp.getAttributeCount();
+                        String type = null;
+                        if (count > 0) {
+                            for (int i = 0; i < count; i++) {
+                                String name = xpp.getAttributeName(i).trim().toLowerCase();
+                                if (ATTRIBUTE_TYPE.equals(name)) {
+                                    type = xpp.getAttributeValue(xpp.getAttributeNamespace(i),
+                                            name).trim().toLowerCase();
+                                    break;
+                                }
+                            }
+                        }
+                        Characteristic next = new Characteristic(type, current);
+                        current.getSubs().add(next);
+                        current = next;
+                    } else if (TAG_PARM.equals(tag)) {
+                        int count = xpp.getAttributeCount();
+                        String key = null;
+                        String value = null;
+                        if (count > 1) {
+                            for (int i = 0; i < count; i++) {
+                                String name = xpp.getAttributeName(i).trim().toLowerCase();
+                                if (ATTRIBUTE_NAME.equals(name)) {
+                                    key = xpp.getAttributeValue(xpp.getAttributeNamespace(i),
+                                            name).trim().toLowerCase();
+                                } else if (ATTRIBUTE_VALUE.equals(name)) {
+                                    value = xpp.getAttributeValue(xpp.getAttributeNamespace(i),
+                                            name).trim();
+                                }
+                            }
+                        }
+                        if (key != null && value != null) {
+                            current.getParms().put(key, value);
+                        }
                     }
+                } else if (eventType == XmlPullParser.END_TAG) {
+                    tag = xpp.getName().trim().toLowerCase();
+                    if (TAG_CHARACTERISTIC.equals(tag)) {
+                        current = current.getParent();
+                    }
+                    tag = null;
                 }
                 eventType = xpp.next();
             }
@@ -102,7 +254,8 @@
      * @return Returns the config value if it exists, or defaultVal.
      */
     public @Nullable String getString(@NonNull String tag, @Nullable String defaultVal) {
-        return mValues.containsKey(tag) ? mValues.get(tag) : defaultVal;
+        String value = mCurrent.getParmValue(tag.trim().toLowerCase());
+        return value != null ?  value : defaultVal;
     }
 
     /**
@@ -115,7 +268,7 @@
      */
     public int getInteger(@NonNull String tag, int defaultVal) {
         try {
-            return Integer.parseInt(mValues.get(tag));
+            return Integer.parseInt(getString(tag, null));
         } catch (NumberFormatException e) {
             logd("error to getInteger for " + tag + " due to " + e);
         }
@@ -131,10 +284,8 @@
      * @return Returns the config value if it exists, or defaultVal.
      */
     public boolean getBoolean(@NonNull String tag, boolean defaultVal) {
-        if (!mValues.containsKey(tag)) {
-            return defaultVal;
-        }
-        return Boolean.parseBoolean(mValues.get(tag));
+        String value = getString(tag, null);
+        return value != null ? Boolean.parseBoolean(value) : defaultVal;
     }
 
     /**
@@ -145,15 +296,70 @@
      * @return Returns true if it exists, or false.
      */
     public boolean hasConfig(@NonNull String tag) {
-        return mValues.containsKey(tag);
+        return mCurrent.hasParm(tag.trim().toLowerCase());
+    }
+
+    /**
+     * Return the Characteristic with the given type
+     */
+    public @Nullable Characteristic getCharacteristic(@NonNull String type) {
+        return mCurrent.getSubByType(type.trim().toLowerCase());
+    }
+
+    /**
+     * Check whether the Characteristic with the given type exists
+     */
+    public boolean hasCharacteristic(@NonNull String type) {
+        return mCurrent.getSubByType(type.trim().toLowerCase()) != null;
+    }
+
+    /**
+     * Set current Characteristic to given Characteristic
+     */
+    public void setCurrentCharacteristic(@NonNull Characteristic current) {
+        if (current != null) {
+            mCurrent = current;
+        }
+    }
+
+    /**
+     * Move current Characteristic to parent layer
+     */
+    public boolean moveToParent() {
+        if (mCurrent.getParent() == null) {
+            return false;
+        }
+        mCurrent = mCurrent.getParent();
+        return true;
+    }
+
+    /**
+     * Move current Characteristic to the root
+     */
+    public void moveToRoot() {
+        mCurrent = mRoot;
+    }
+
+    /**
+     * Return root Characteristic
+     */
+    public @NonNull Characteristic getRoot() {
+        return mRoot;
+    }
+
+    /**
+     * Return current Characteristic
+     */
+    public @NonNull Characteristic getCurrentCharacteristic() {
+        return mCurrent;
     }
 
     /**
      * Check whether Rcs Volte single registration is supported by the config.
      */
     public boolean isRcsVolteSingleRegistrationSupported() {
-        return getBoolean(TAG_SINGLE_REGISTRATION, false)
-                || getInteger(TAG_SINGLE_REGISTRATION, 0) != 0;
+        return getBoolean(PARM_SINGLE_REGISTRATION, false)
+                || getInteger(PARM_SINGLE_REGISTRATION, 0) != 0;
     }
 
     @Override
@@ -161,12 +367,10 @@
         final StringBuilder sb = new StringBuilder();
         sb.append("[RCS Config]");
         if (DBG) {
-            mValues.forEach((t, v) -> {
-                sb.append("\n");
-                sb.append(t);
-                sb.append(" : ");
-                sb.append(v);
-            });
+            sb.append("=== Root ===\n");
+            sb.append(mRoot);
+            sb.append("=== Current ===\n");
+            sb.append(mCurrent);
         }
         return sb.toString();
     }
@@ -179,12 +383,12 @@
 
         RcsConfig other = (RcsConfig) obj;
 
-        return mValues.equals(other.mValues);
+        return mRoot.equals(other.mRoot) && mCurrent.equals(other.mCurrent);
     }
 
     @Override
     public int hashCode() {
-        return mValues.hashCode();
+        return Objects.hash(mRoot, mCurrent);
     }
 
     /**
@@ -275,38 +479,6 @@
         return isCompressed ? data : decompressGzip(data);
     }
 
-    /**
-     * {@link Parcelable#writeToParcel}
-     */
-    public void writeToParcel(@NonNull Parcel out, int flags) {
-        out.writeMap(mValues);
-    }
-
-    /**
-     * {@link Parcelable.Creator}
-     *
-     */
-    public static final @NonNull Parcelable.Creator<RcsConfig>
-            CREATOR = new Creator<RcsConfig>() {
-                @Override
-                public RcsConfig createFromParcel(Parcel in) {
-                    HashMap<String, String> values = in.readHashMap(null);
-                    return values == null ? null : new RcsConfig(values);
-                }
-
-                @Override
-                public RcsConfig[] newArray(int size) {
-                    return new RcsConfig[size];
-                }
-            };
-
-    /**
-     * {@link Parcelable#describeContents}
-     */
-    public int describeContents() {
-        return 0;
-    }
-
     private static void logd(String msg) {
         Rlog.d(LOG_TAG, msg);
     }
diff --git a/telephony/java/android/telephony/ims/RegistrationManager.java b/telephony/java/android/telephony/ims/RegistrationManager.java
index c49121f..4713b76 100644
--- a/telephony/java/android/telephony/ims/RegistrationManager.java
+++ b/telephony/java/android/telephony/ims/RegistrationManager.java
@@ -82,6 +82,8 @@
                         AccessNetworkConstants.TRANSPORT_TYPE_INVALID);
                 put(ImsRegistrationImplBase.REGISTRATION_TECH_LTE,
                         AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
+                put(ImsRegistrationImplBase.REGISTRATION_TECH_NR,
+                        AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
                 put(ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN,
                         AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
             }};
diff --git a/telephony/java/android/telephony/ims/SipDelegateImsConfiguration.java b/telephony/java/android/telephony/ims/SipDelegateImsConfiguration.java
index ffbfde6..08513c2 100644
--- a/telephony/java/android/telephony/ims/SipDelegateImsConfiguration.java
+++ b/telephony/java/android/telephony/ims/SipDelegateImsConfiguration.java
@@ -26,6 +26,7 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.PersistableBundle;
+import android.text.TextUtils;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -561,7 +562,12 @@
         builder.setSipCniHeader(getString(KEY_SIP_CONFIG_CELLULAR_NETWORK_INFO_HEADER_STRING));
         builder.setSipAssociatedUriHeader(getString(KEY_SIP_CONFIG_P_ASSOCIATED_URI_HEADER_STRING));
         if (getBoolean(KEY_SIP_CONFIG_IS_GRUU_ENABLED_BOOL, false)) {
-            builder.setPublicGruuUri(Uri.parse(getString(KEY_SIP_CONFIG_UE_PUBLIC_GRUU_STRING)));
+            String uri = getString(KEY_SIP_CONFIG_UE_PUBLIC_GRUU_STRING);
+            Uri gruuUri = null;
+            if (!TextUtils.isEmpty(uri)) {
+                gruuUri = Uri.parse(uri);
+            }
+            builder.setPublicGruuUri(gruuUri);
         }
         if (getBoolean(KEY_SIP_CONFIG_IS_IPSEC_ENABLED_BOOL, false)) {
             builder.setIpSecConfiguration(new SipDelegateConfiguration.IpSecConfiguration(
diff --git a/telephony/java/android/telephony/ims/SipDelegateManager.java b/telephony/java/android/telephony/ims/SipDelegateManager.java
index ee7302a..97be45a 100644
--- a/telephony/java/android/telephony/ims/SipDelegateManager.java
+++ b/telephony/java/android/telephony/ims/SipDelegateManager.java
@@ -33,6 +33,7 @@
 import android.telephony.ims.stub.DelegateConnectionMessageCallback;
 import android.telephony.ims.stub.DelegateConnectionStateCallback;
 import android.telephony.ims.stub.SipDelegate;
+import android.util.ArrayMap;
 
 import com.android.internal.annotations.VisibleForTesting;
 
@@ -79,13 +80,18 @@
     public static final int MESSAGE_FAILURE_REASON_DELEGATE_CLOSED = 2;
 
     /**
-     * The SIP message has an invalid start line and the message can not be sent.
+     * The SIP message has an invalid start line and the message can not be sent or the start line
+     * failed validation due to the request containing a restricted SIP request method.
+     * {@link SipDelegateConnection}s can not send SIP requests for the methods: REGISTER, PUBLISH,
+     * or OPTIONS.
      */
     public static final int MESSAGE_FAILURE_REASON_INVALID_START_LINE = 3;
 
     /**
      * One or more of the header fields in the header section of the outgoing SIP message is invalid
-     * and the SIP message can not be sent.
+     * or contains a restricted header value and the SIP message can not be sent.
+     * {@link SipDelegateConnection}s can not send SIP SUBSCRIBE requests for the "Event" header
+     * value of "presence".
      */
     public static final int MESSAGE_FAILURE_REASON_INVALID_HEADER_FIELDS = 4;
 
@@ -96,7 +102,7 @@
 
     /**
      * The feature tag associated with the outgoing message does not match any known feature tags
-     * and this message can not be sent.
+     * or it matches a denied tag and this message can not be sent.
      */
     public static final int MESSAGE_FAILURE_REASON_INVALID_FEATURE_TAG = 6;
 
@@ -162,6 +168,35 @@
     })
     public @interface MessageFailureReason {}
 
+    /**@hide*/
+    public static final ArrayMap<Integer, String> MESSAGE_FAILURE_REASON_STRING_MAP =
+            new ArrayMap<>(11);
+    static {
+        MESSAGE_FAILURE_REASON_STRING_MAP.append(MESSAGE_FAILURE_REASON_UNKNOWN,
+                "MESSAGE_FAILURE_REASON_UNKNOWN");
+        MESSAGE_FAILURE_REASON_STRING_MAP.append(MESSAGE_FAILURE_REASON_DELEGATE_DEAD,
+                "MESSAGE_FAILURE_REASON_DELEGATE_DEAD");
+        MESSAGE_FAILURE_REASON_STRING_MAP.append(MESSAGE_FAILURE_REASON_DELEGATE_CLOSED,
+                "MESSAGE_FAILURE_REASON_DELEGATE_CLOSED");
+        MESSAGE_FAILURE_REASON_STRING_MAP.append(MESSAGE_FAILURE_REASON_INVALID_HEADER_FIELDS,
+                "MESSAGE_FAILURE_REASON_INVALID_HEADER_FIELDS");
+        MESSAGE_FAILURE_REASON_STRING_MAP.append(MESSAGE_FAILURE_REASON_INVALID_BODY_CONTENT,
+                "MESSAGE_FAILURE_REASON_INVALID_BODY_CONTENT");
+        MESSAGE_FAILURE_REASON_STRING_MAP.append(MESSAGE_FAILURE_REASON_INVALID_FEATURE_TAG,
+                "MESSAGE_FAILURE_REASON_INVALID_FEATURE_TAG");
+        MESSAGE_FAILURE_REASON_STRING_MAP.append(
+                MESSAGE_FAILURE_REASON_TAG_NOT_ENABLED_FOR_DELEGATE,
+                "MESSAGE_FAILURE_REASON_TAG_NOT_ENABLED_FOR_DELEGATE");
+        MESSAGE_FAILURE_REASON_STRING_MAP.append(MESSAGE_FAILURE_REASON_NETWORK_NOT_AVAILABLE,
+                "MESSAGE_FAILURE_REASON_NETWORK_NOT_AVAILABLE");
+        MESSAGE_FAILURE_REASON_STRING_MAP.append(MESSAGE_FAILURE_REASON_NOT_REGISTERED,
+                "MESSAGE_FAILURE_REASON_NOT_REGISTERED");
+        MESSAGE_FAILURE_REASON_STRING_MAP.append(MESSAGE_FAILURE_REASON_STALE_IMS_CONFIGURATION,
+                "MESSAGE_FAILURE_REASON_STALE_IMS_CONFIGURATION");
+        MESSAGE_FAILURE_REASON_STRING_MAP.append(
+                MESSAGE_FAILURE_REASON_INTERNAL_DELEGATE_STATE_TRANSITION,
+                "MESSAGE_FAILURE_REASON_INTERNAL_DELEGATE_STATE_TRANSITION");
+    }
 
     /**
      * Access to use this feature tag has been denied for an unknown reason.
diff --git a/telephony/java/android/telephony/ims/aidl/IImsConfig.aidl b/telephony/java/android/telephony/ims/aidl/IImsConfig.aidl
index 5eee389..1b5e560 100644
--- a/telephony/java/android/telephony/ims/aidl/IImsConfig.aidl
+++ b/telephony/java/android/telephony/ims/aidl/IImsConfig.aidl
@@ -47,4 +47,6 @@
     void removeRcsConfigCallback(IRcsConfigCallback c);
     void triggerRcsReconfiguration();
     void setRcsClientConfiguration(in RcsClientConfiguration rcc);
+    void notifyIntImsConfigChanged(int item, int value);
+    void notifyStringImsConfigChanged(int item, String value);
 }
diff --git a/telephony/java/android/telephony/ims/feature/RcsFeature.java b/telephony/java/android/telephony/ims/feature/RcsFeature.java
index ddd6fbe..18cc37d 100644
--- a/telephony/java/android/telephony/ims/feature/RcsFeature.java
+++ b/telephony/java/android/telephony/ims/feature/RcsFeature.java
@@ -398,16 +398,6 @@
 
     /**
      * Remove the given CapabilityExchangeImplBase instance.
-     * @param capExchangeImpl The {@link RcsCapabilityExchangeImplBase} instance to be removed.
-     * @hide
-     */
-    public void removeCapabilityExchangeImpl(
-            @NonNull RcsCapabilityExchangeImplBase capExchangeImpl) {
-        // Override to implement the process of removing RcsCapabilityExchangeImplBase instance.
-    }
-
-    /**
-     * Remove the given CapabilityExchangeImplBase instance.
      * @param capExchangeImpl The {@link RcsCapabilityExchangeImplBase} instance to be destroyed.
      */
     public void destroyCapabilityExchangeImpl(
@@ -450,7 +440,7 @@
                 // Remove the RcsCapabilityExchangeImplBase instance when the capability exchange
                 // instance has been removed in the framework.
                 if (mCapabilityExchangeImpl != null) {
-                    removeCapabilityExchangeImpl(mCapabilityExchangeImpl);
+                    destroyCapabilityExchangeImpl(mCapabilityExchangeImpl);
                 }
                 mCapabilityExchangeImpl = null;
             }
@@ -468,7 +458,7 @@
         synchronized (mLock) {
             // Remove the original instance
             if (mCapabilityExchangeImpl != null) {
-                removeCapabilityExchangeImpl(mCapabilityExchangeImpl);
+                destroyCapabilityExchangeImpl(mCapabilityExchangeImpl);
             }
             mCapabilityExchangeImpl = createCapabilityExchangeImpl(listener);
         }
diff --git a/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java b/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java
index 4dcb7f5..d75da90 100644
--- a/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java
+++ b/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java
@@ -258,6 +258,16 @@
         public void setRcsClientConfiguration(RcsClientConfiguration rcc) throws RemoteException {
             getImsConfigImpl().setRcsClientConfiguration(rcc);
         }
+
+        @Override
+        public void notifyIntImsConfigChanged(int item, int value) throws RemoteException {
+            notifyImsConfigChanged(item, value);
+        }
+
+        @Override
+        public void notifyStringImsConfigChanged(int item, String value) throws RemoteException {
+            notifyImsConfigChanged(item, value);
+        }
     }
 
     /**
diff --git a/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java b/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java
index 23032f0..35324a3c 100644
--- a/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java
+++ b/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java
@@ -56,7 +56,8 @@
     @IntDef(value = {
                     REGISTRATION_TECH_NONE,
                     REGISTRATION_TECH_LTE,
-                    REGISTRATION_TECH_IWLAN
+                    REGISTRATION_TECH_IWLAN,
+                    REGISTRATION_TECH_NR
             })
     @Retention(RetentionPolicy.SOURCE)
     public @interface ImsRegistrationTech {}
@@ -65,13 +66,18 @@
      */
     public static final int REGISTRATION_TECH_NONE = -1;
     /**
-     * IMS is registered to IMS via LTE.
+     * This ImsService is registered to IMS via LTE.
      */
     public static final int REGISTRATION_TECH_LTE = 0;
     /**
-     * IMS is registered to IMS via IWLAN.
+     * This ImsService is registered to IMS via IWLAN.
      */
     public static final int REGISTRATION_TECH_IWLAN = 1;
+    // REGISTRATION_TECH = 2 omitted purposefully.
+    /**
+     * This ImsService is registered to IMS via NR.
+     */
+    public static final int REGISTRATION_TECH_NR = 3;
 
     // Registration states, used to notify new ImsRegistrationImplBase#Callbacks of the current
     // state.
diff --git a/telephony/java/com/android/internal/telephony/ISub.aidl b/telephony/java/com/android/internal/telephony/ISub.aidl
index 571efce..6493772 100755
--- a/telephony/java/com/android/internal/telephony/ISub.aidl
+++ b/telephony/java/com/android/internal/telephony/ISub.aidl
@@ -300,4 +300,8 @@
     boolean canDisablePhysicalSubscription();
 
     int setUiccApplicationsEnabled(boolean enabled, int subscriptionId);
+
+    int setDeviceToDeviceStatusSharing(int sharing, int subId);
+
+    int setDeviceToDeviceStatusSharingContacts(String contacts, int subscriptionId);
 }
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 97078c3..3c55b7c 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -2398,6 +2398,12 @@
     String getLastUcePidfXmlShell(int subId);
 
     /**
+      * Remove UCE requests cannot be sent to the network status.
+      * Note: This is designed for a SHELL command only.
+      */
+    boolean removeUceRequestDisallowedStatus(int subId);
+
+    /**
      * Set a SignalStrengthUpdateRequest to receive notification when Signal Strength breach the
      * specified thresholds.
      */
diff --git a/test-base/Android.bp b/test-base/Android.bp
index 9bd639b..b58aa11 100644
--- a/test-base/Android.bp
+++ b/test-base/Android.bp
@@ -32,7 +32,7 @@
 java_sdk_library {
     name: "android.test.base",
 
-    srcs: ["src/**/*.java"],
+    srcs: [":android-test-base-sources"],
 
     errorprone: {
         javacflags: ["-Xep:DepAnn:ERROR"],
@@ -66,7 +66,7 @@
     name: "android.test.base_static",
     installable: false,
 
-    srcs: ["src/**/*.java"],
+    srcs: [":android-test-base-sources"],
 
     errorprone: {
         javacflags: ["-Xep:DepAnn:ERROR"],
@@ -114,6 +114,12 @@
     ],
 }
 
+filegroup {
+    name: "android-test-base-sources",
+    srcs: ["src/**/*.java"],
+    path: "src",
+}
+
 // Make the current.txt available for use by the cts/tests/signature tests.
 // ========================================================================
 filegroup {
diff --git a/test-mock/Android.bp b/test-mock/Android.bp
index a2447d7..107292c 100644
--- a/test-mock/Android.bp
+++ b/test-mock/Android.bp
@@ -29,7 +29,7 @@
     name: "android.test.mock",
 
     srcs: [
-        "src/**/*.java",
+        ":android-test-mock-sources",
         // Note: Below are NOT APIs of this library. We only take APIs under
         // the android.test.mock package. They however provide private APIs that
         // android.test.mock APIs references to.
@@ -38,6 +38,7 @@
     ],
     libs: [
         "framework",
+        "framework-annotations-lib",
         "app-compat-annotations",
         "unsupportedappusage",
     ],
@@ -60,3 +61,9 @@
         "api/current.txt",
     ],
 }
+
+filegroup {
+    name: "android-test-mock-sources",
+    srcs: ["src/**/*.java"],
+    path: "src",
+}
diff --git a/test-runner/Android.bp b/test-runner/Android.bp
index fe007e39..c380ae3 100644
--- a/test-runner/Android.bp
+++ b/test-runner/Android.bp
@@ -29,7 +29,7 @@
 java_sdk_library {
     name: "android.test.runner",
 
-    srcs: ["src/**/*.java"],
+    srcs: [":android-test-runner-sources"],
 
     errorprone: {
         javacflags: ["-Xep:DepAnn:ERROR"],
@@ -76,7 +76,7 @@
 java_library_static {
     name: "repackaged.android.test.runner",
 
-    srcs: ["src/**/*.java"],
+    srcs: [":android-test-runner-sources"],
     exclude_srcs: [
         "src/android/test/ActivityUnitTestCase.java",
         "src/android/test/ApplicationTestCase.java",
@@ -108,3 +108,9 @@
         "api/current.txt",
     ],
 }
+
+filegroup {
+    name: "android-test-runner-sources",
+    srcs: ["src/**/*.java"],
+    path: "src",
+}
diff --git a/tests/DynamicCodeLoggerIntegrationTests/Android.mk b/tests/DynamicCodeLoggerIntegrationTests/Android.mk
index bfb5b07..dab8304 100644
--- a/tests/DynamicCodeLoggerIntegrationTests/Android.mk
+++ b/tests/DynamicCodeLoggerIntegrationTests/Android.mk
@@ -89,4 +89,7 @@
     $(dynamiccodeloggertest_jar) \
     $(dynamiccodeloggertest_executable) \
 
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
+LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../../NOTICE
 include $(BUILD_PACKAGE)
diff --git a/tests/backup/Android.mk b/tests/backup/Android.mk
index 9b155c9..b6f3471 100644
--- a/tests/backup/Android.mk
+++ b/tests/backup/Android.mk
@@ -47,4 +47,7 @@
 
 LOCAL_PROGUARD_ENABLED := disabled
 
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
+LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../../NOTICE
 include $(BUILD_PACKAGE)
diff --git a/tests/net/common/java/android/net/NetworkCapabilitiesTest.java b/tests/net/common/java/android/net/NetworkCapabilitiesTest.java
index 33f2c67..b178bad 100644
--- a/tests/net/common/java/android/net/NetworkCapabilitiesTest.java
+++ b/tests/net/common/java/android/net/NetworkCapabilitiesTest.java
@@ -390,9 +390,11 @@
     @Test
     public void testOemPaid() {
         NetworkCapabilities nc = new NetworkCapabilities();
-        // By default OEM_PAID is neither in the unwanted or required lists and the network is not
+        // By default OEM_PAID is neither in the required or forbidden lists and the network is not
         // restricted.
-        assertFalse(nc.hasUnwantedCapability(NET_CAPABILITY_OEM_PAID));
+        if (isAtLeastS()) {
+            assertFalse(nc.hasForbiddenCapability(NET_CAPABILITY_OEM_PAID));
+        }
         assertFalse(nc.hasCapability(NET_CAPABILITY_OEM_PAID));
         nc.maybeMarkCapabilitiesRestricted();
         assertTrue(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED));
@@ -417,9 +419,9 @@
     @Test @IgnoreUpTo(Build.VERSION_CODES.R)
     public void testOemPrivate() {
         NetworkCapabilities nc = new NetworkCapabilities();
-        // By default OEM_PRIVATE is neither in the unwanted or required lists and the network is
+        // By default OEM_PRIVATE is neither in the required or forbidden lists and the network is
         // not restricted.
-        assertFalse(nc.hasUnwantedCapability(NET_CAPABILITY_OEM_PRIVATE));
+        assertFalse(nc.hasForbiddenCapability(NET_CAPABILITY_OEM_PRIVATE));
         assertFalse(nc.hasCapability(NET_CAPABILITY_OEM_PRIVATE));
         nc.maybeMarkCapabilitiesRestricted();
         assertTrue(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED));
@@ -441,8 +443,8 @@
         assertFalse(nr.satisfiedByNetworkCapabilities(new NetworkCapabilities()));
     }
 
-    @Test
-    public void testUnwantedCapabilities() {
+    @Test @IgnoreUpTo(Build.VERSION_CODES.R)
+    public void testForbiddenCapabilities() {
         NetworkCapabilities network = new NetworkCapabilities();
 
         NetworkCapabilities request = new NetworkCapabilities();
@@ -450,19 +452,19 @@
                 request.satisfiedByNetworkCapabilities(network));
 
         // Requesting absence of capabilities that network doesn't have. Request should satisfy.
-        request.addUnwantedCapability(NET_CAPABILITY_WIFI_P2P);
-        request.addUnwantedCapability(NET_CAPABILITY_NOT_METERED);
+        request.addForbiddenCapability(NET_CAPABILITY_WIFI_P2P);
+        request.addForbiddenCapability(NET_CAPABILITY_NOT_METERED);
         assertTrue(request.satisfiedByNetworkCapabilities(network));
-        assertArrayEquals(new int[] {NET_CAPABILITY_WIFI_P2P,
+        assertArrayEquals(new int[]{NET_CAPABILITY_WIFI_P2P,
                         NET_CAPABILITY_NOT_METERED},
-                request.getUnwantedCapabilities());
+                request.getForbiddenCapabilities());
 
         // This is a default capability, just want to make sure its there because we use it below.
         assertTrue(network.hasCapability(NET_CAPABILITY_NOT_RESTRICTED));
 
-        // Verify that adding unwanted capability will effectively remove it from capability list.
-        request.addUnwantedCapability(NET_CAPABILITY_NOT_RESTRICTED);
-        assertTrue(request.hasUnwantedCapability(NET_CAPABILITY_NOT_RESTRICTED));
+        // Verify that adding forbidden capability will effectively remove it from capability list.
+        request.addForbiddenCapability(NET_CAPABILITY_NOT_RESTRICTED);
+        assertTrue(request.hasForbiddenCapability(NET_CAPABILITY_NOT_RESTRICTED));
         assertFalse(request.hasCapability(NET_CAPABILITY_NOT_RESTRICTED));
 
         // Now this request won't be satisfied because network contains NOT_RESTRICTED.
@@ -470,10 +472,10 @@
         network.removeCapability(NET_CAPABILITY_NOT_RESTRICTED);
         assertTrue(request.satisfiedByNetworkCapabilities(network));
 
-        // Verify that adding capability will effectively remove it from unwanted list
+        // Verify that adding capability will effectively remove it from forbidden list
         request.addCapability(NET_CAPABILITY_NOT_RESTRICTED);
         assertTrue(request.hasCapability(NET_CAPABILITY_NOT_RESTRICTED));
-        assertFalse(request.hasUnwantedCapability(NET_CAPABILITY_NOT_RESTRICTED));
+        assertFalse(request.hasForbiddenCapability(NET_CAPABILITY_NOT_RESTRICTED));
 
         assertFalse(request.satisfiedByNetworkCapabilities(network));
         network.addCapability(NET_CAPABILITY_NOT_RESTRICTED);
@@ -512,24 +514,20 @@
         assertTrue(nc1.equalsNetCapabilities(nc2));
         assertEquals(nc1, nc2);
 
-        nc1.addUnwantedCapability(NET_CAPABILITY_INTERNET);
-        assertFalse(nc1.equalsNetCapabilities(nc2));
-        nc2.addUnwantedCapability(NET_CAPABILITY_INTERNET);
-        assertTrue(nc1.equalsNetCapabilities(nc2));
         if (isAtLeastS()) {
-            // Remove a required capability doesn't affect unwanted capabilities.
-            // This is a behaviour change from S.
+            nc1.addForbiddenCapability(NET_CAPABILITY_INTERNET);
+            assertFalse(nc1.equalsNetCapabilities(nc2));
+            nc2.addForbiddenCapability(NET_CAPABILITY_INTERNET);
+            assertTrue(nc1.equalsNetCapabilities(nc2));
+
+            // Remove a required capability doesn't affect forbidden capabilities.
+            // This is a behaviour change from R to S.
             nc1.removeCapability(NET_CAPABILITY_INTERNET);
             assertTrue(nc1.equalsNetCapabilities(nc2));
 
-            nc1.removeUnwantedCapability(NET_CAPABILITY_INTERNET);
+            nc1.removeForbiddenCapability(NET_CAPABILITY_INTERNET);
             assertFalse(nc1.equalsNetCapabilities(nc2));
-            nc2.removeUnwantedCapability(NET_CAPABILITY_INTERNET);
-            assertTrue(nc1.equalsNetCapabilities(nc2));
-        } else {
-            nc1.removeCapability(NET_CAPABILITY_INTERNET);
-            assertFalse(nc1.equalsNetCapabilities(nc2));
-            nc2.removeCapability(NET_CAPABILITY_INTERNET);
+            nc2.removeForbiddenCapability(NET_CAPABILITY_INTERNET);
             assertTrue(nc1.equalsNetCapabilities(nc2));
         }
     }
@@ -581,31 +579,25 @@
         NetworkCapabilities nc1 = new NetworkCapabilities();
         NetworkCapabilities nc2 = new NetworkCapabilities();
 
-        nc1.addUnwantedCapability(NET_CAPABILITY_CAPTIVE_PORTAL);
+        if (isAtLeastS()) {
+            nc1.addForbiddenCapability(NET_CAPABILITY_CAPTIVE_PORTAL);
+        }
         nc1.addCapability(NET_CAPABILITY_NOT_ROAMING);
         assertNotEquals(nc1, nc2);
         nc2.combineCapabilities(nc1);
         assertEquals(nc1, nc2);
         assertTrue(nc2.hasCapability(NET_CAPABILITY_NOT_ROAMING));
-        assertTrue(nc2.hasUnwantedCapability(NET_CAPABILITY_CAPTIVE_PORTAL));
-
-        // This will effectively move NOT_ROAMING capability from required to unwanted for nc1.
-        nc1.addUnwantedCapability(NET_CAPABILITY_NOT_ROAMING);
+        if (isAtLeastS()) {
+            assertTrue(nc2.hasForbiddenCapability(NET_CAPABILITY_CAPTIVE_PORTAL));
+        }
 
         if (isAtLeastS()) {
-            // From S, it is not allowed to have the same capability in both wanted and
-            // unwanted list.
+            // This will effectively move NOT_ROAMING capability from required to forbidden for nc1.
+            nc1.addForbiddenCapability(NET_CAPABILITY_NOT_ROAMING);
+            // It is not allowed to have the same capability in both wanted and forbidden list.
             assertThrows(IllegalArgumentException.class, () -> nc2.combineCapabilities(nc1));
-            // Remove unwanted capability to continue other tests.
-            nc1.removeUnwantedCapability(NET_CAPABILITY_NOT_ROAMING);
-        } else {
-            nc2.combineCapabilities(nc1);
-            // We will get this capability in both requested and unwanted lists thus this request
-            // will never be satisfied.
-            assertTrue(nc2.hasCapability(NET_CAPABILITY_NOT_ROAMING));
-            assertTrue(nc2.hasUnwantedCapability(NET_CAPABILITY_NOT_ROAMING));
-            // For R or below, remove unwanted capability via removeCapability.
-            nc1.removeCapability(NET_CAPABILITY_NOT_ROAMING);
+            // Remove forbidden capability to continue other tests.
+            nc1.removeForbiddenCapability(NET_CAPABILITY_NOT_ROAMING);
         }
 
         nc1.setSSID(TEST_SSID);
@@ -683,14 +675,11 @@
     public void testSetCapabilities() {
         final int[] REQUIRED_CAPABILITIES = new int[] {
                 NET_CAPABILITY_INTERNET, NET_CAPABILITY_NOT_VPN };
-        final int[] UNWANTED_CAPABILITIES = new int[] {
-                NET_CAPABILITY_NOT_RESTRICTED, NET_CAPABILITY_NOT_METERED
-        };
 
         NetworkCapabilities nc1 = new NetworkCapabilities();
         NetworkCapabilities nc2 = new NetworkCapabilities();
 
-        nc1.setCapabilities(REQUIRED_CAPABILITIES, UNWANTED_CAPABILITIES);
+        nc1.setCapabilities(REQUIRED_CAPABILITIES);
         assertArrayEquals(REQUIRED_CAPABILITIES, nc1.getCapabilities());
 
         // Verify that setting and adding capabilities leads to the same object state.
@@ -698,10 +687,25 @@
         for (int cap : REQUIRED_CAPABILITIES) {
             nc2.addCapability(cap);
         }
-        for (int cap : UNWANTED_CAPABILITIES) {
-            nc2.addUnwantedCapability(cap);
-        }
         assertEquals(nc1, nc2);
+
+        if (isAtLeastS()) {
+            final int[] forbiddenCapabilities = new int[]{
+                    NET_CAPABILITY_NOT_METERED, NET_CAPABILITY_NOT_RESTRICTED };
+
+            nc1.setCapabilities(REQUIRED_CAPABILITIES, forbiddenCapabilities);
+            assertArrayEquals(REQUIRED_CAPABILITIES, nc1.getCapabilities());
+            assertArrayEquals(forbiddenCapabilities, nc1.getForbiddenCapabilities());
+
+            nc2.clearAll();
+            for (int cap : REQUIRED_CAPABILITIES) {
+                nc2.addCapability(cap);
+            }
+            for (int cap : forbiddenCapabilities) {
+                nc2.addForbiddenCapability(cap);
+            }
+            assertEquals(nc1, nc2);
+        }
     }
 
     @Test
@@ -769,23 +773,32 @@
         NetworkCapabilities nc1 = new NetworkCapabilities();
         NetworkCapabilities nc2 = new NetworkCapabilities();
 
-        nc1.addUnwantedCapability(NET_CAPABILITY_CAPTIVE_PORTAL);
+        if (isAtLeastS()) {
+            nc1.addForbiddenCapability(NET_CAPABILITY_CAPTIVE_PORTAL);
+        }
         nc1.addCapability(NET_CAPABILITY_NOT_ROAMING);
         assertNotEquals(nc1, nc2);
         nc2.set(nc1);
         assertEquals(nc1, nc2);
         assertTrue(nc2.hasCapability(NET_CAPABILITY_NOT_ROAMING));
-        assertTrue(nc2.hasUnwantedCapability(NET_CAPABILITY_CAPTIVE_PORTAL));
+        if (isAtLeastS()) {
+            assertTrue(nc2.hasForbiddenCapability(NET_CAPABILITY_CAPTIVE_PORTAL));
+        }
 
-        // This will effectively move NOT_ROAMING capability from required to unwanted for nc1.
-        nc1.addUnwantedCapability(NET_CAPABILITY_NOT_ROAMING);
+        if (isAtLeastS()) {
+            // This will effectively move NOT_ROAMING capability from required to forbidden for nc1.
+            nc1.addForbiddenCapability(NET_CAPABILITY_NOT_ROAMING);
+        }
         nc1.setSSID(TEST_SSID);
         nc2.set(nc1);
         assertEquals(nc1, nc2);
-        // Contrary to combineCapabilities, set() will have removed the NOT_ROAMING capability
-        // from nc2.
-        assertFalse(nc2.hasCapability(NET_CAPABILITY_NOT_ROAMING));
-        assertTrue(nc2.hasUnwantedCapability(NET_CAPABILITY_NOT_ROAMING));
+        if (isAtLeastS()) {
+            // Contrary to combineCapabilities, set() will have removed the NOT_ROAMING capability
+            // from nc2.
+            assertFalse(nc2.hasCapability(NET_CAPABILITY_NOT_ROAMING));
+            assertTrue(nc2.hasForbiddenCapability(NET_CAPABILITY_NOT_ROAMING));
+        }
+
         if (isAtLeastR()) {
             assertTrue(TEST_SSID.equals(nc2.getSsid()));
         }
diff --git a/tests/net/integration/src/com/android/server/net/integrationtests/TestNetworkStackService.kt b/tests/net/integration/src/com/android/server/net/integrationtests/TestNetworkStackService.kt
index a44ad1e..eff6658 100644
--- a/tests/net/integration/src/com/android/server/net/integrationtests/TestNetworkStackService.kt
+++ b/tests/net/integration/src/com/android/server/net/integrationtests/TestNetworkStackService.kt
@@ -61,7 +61,6 @@
     private class NetworkMonitorDeps(private val privateDnsBypassNetwork: Network) :
             NetworkMonitor.Dependencies() {
         override fun getPrivateDnsBypassNetwork(network: Network?) = privateDnsBypassNetwork
-        override fun sendNetworkConditionsBroadcast(context: Context, broadcast: Intent) = Unit
     }
 
     private inner class TestNetworkStackConnector(context: Context) : NetworkStackConnector(
@@ -98,4 +97,4 @@
             cb.onNetworkMonitorCreated(NetworkMonitorConnector(nm, TestPermissionChecker()))
         }
     }
-}
\ No newline at end of file
+}
diff --git a/tests/net/java/android/net/ConnectivityManagerTest.java b/tests/net/java/android/net/ConnectivityManagerTest.java
index 19f8843..591e0cc 100644
--- a/tests/net/java/android/net/ConnectivityManagerTest.java
+++ b/tests/net/java/android/net/ConnectivityManagerTest.java
@@ -379,7 +379,7 @@
                 eq(testPkgName), eq(testAttributionTag));
         reset(mService);
 
-        manager.registerDefaultNetworkCallbackAsUid(42, callback, handler);
+        manager.registerDefaultNetworkCallbackForUid(42, callback, handler);
         verify(mService).requestNetwork(eq(42), eq(null),
                 eq(TRACK_DEFAULT.ordinal()), any(), anyInt(), any(), eq(TYPE_NONE), anyInt(),
                 eq(testPkgName), eq(testAttributionTag));
diff --git a/tests/net/java/android/net/NetworkStatsTest.java b/tests/net/java/android/net/NetworkStatsTest.java
index 735fa7c..23d5a7e 100644
--- a/tests/net/java/android/net/NetworkStatsTest.java
+++ b/tests/net/java/android/net/NetworkStatsTest.java
@@ -50,6 +50,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.Arrays;
 import java.util.HashSet;
 
 @RunWith(AndroidJUnit4.class)
@@ -616,7 +617,7 @@
                 .insertEntry(underlyingIface, tunUid, SET_FOREGROUND, TAG_NONE, METERED_NO,
                         ROAMING_NO, DEFAULT_NETWORK_NO, 0L, 0L, 0L, 0L, 0L);
 
-        delta.migrateTun(tunUid, tunIface, new String[]{underlyingIface});
+        delta.migrateTun(tunUid, tunIface, Arrays.asList(underlyingIface));
         assertEquals(20, delta.size());
 
         // tunIface and TEST_IFACE entries are not changed.
@@ -697,7 +698,7 @@
                 .insertEntry(underlyingIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 75500L, 37L, 130000L, 70L, 0L);
 
-        delta.migrateTun(tunUid, tunIface, new String[]{underlyingIface});
+        delta.migrateTun(tunUid, tunIface, Arrays.asList(underlyingIface));
         assertEquals(9, delta.size());
 
         // tunIface entries should not be changed.
diff --git a/tests/net/java/android/net/NetworkTemplateTest.kt b/tests/net/java/android/net/NetworkTemplateTest.kt
index 64b774c..ab6b2f4 100644
--- a/tests/net/java/android/net/NetworkTemplateTest.kt
+++ b/tests/net/java/android/net/NetworkTemplateTest.kt
@@ -31,11 +31,16 @@
 import android.net.NetworkTemplate.MATCH_MOBILE_WILDCARD
 import android.net.NetworkTemplate.MATCH_WIFI
 import android.net.NetworkTemplate.MATCH_WIFI_WILDCARD
+import android.net.NetworkTemplate.WIFI_NETWORKID_ALL
 import android.net.NetworkTemplate.NETWORK_TYPE_5G_NSA
 import android.net.NetworkTemplate.NETWORK_TYPE_ALL
 import android.net.NetworkTemplate.OEM_MANAGED_ALL
 import android.net.NetworkTemplate.OEM_MANAGED_NO
 import android.net.NetworkTemplate.OEM_MANAGED_YES
+import android.net.NetworkTemplate.SUBSCRIBER_ID_MATCH_RULE_EXACT
+import android.net.NetworkTemplate.buildTemplateWifi
+import android.net.NetworkTemplate.buildTemplateWifiWildcard
+import android.net.NetworkTemplate.buildTemplateCarrier
 import android.net.NetworkTemplate.buildTemplateMobileWithRatType
 import android.telephony.TelephonyManager
 import com.android.testutils.assertParcelSane
@@ -53,6 +58,7 @@
 private const val TEST_IMSI1 = "imsi1"
 private const val TEST_IMSI2 = "imsi2"
 private const val TEST_SSID1 = "ssid1"
+private const val TEST_SSID2 = "ssid2"
 
 @RunWith(JUnit4::class)
 class NetworkTemplateTest {
@@ -60,8 +66,8 @@
 
     private fun buildMobileNetworkState(subscriberId: String): NetworkStateSnapshot =
             buildNetworkState(TYPE_MOBILE, subscriberId = subscriberId)
-    private fun buildWifiNetworkState(ssid: String): NetworkStateSnapshot =
-            buildNetworkState(TYPE_WIFI, ssid = ssid)
+    private fun buildWifiNetworkState(subscriberId: String?, ssid: String?): NetworkStateSnapshot =
+            buildNetworkState(TYPE_WIFI, subscriberId = subscriberId, ssid = ssid)
 
     private fun buildNetworkState(
         type: Int,
@@ -94,6 +100,95 @@
     }
 
     @Test
+    fun testWifiWildcardMatches() {
+        val templateWifiWildcard = buildTemplateWifiWildcard()
+
+        val identMobileImsi1 = buildNetworkIdentity(mockContext,
+                buildMobileNetworkState(TEST_IMSI1),
+                false, TelephonyManager.NETWORK_TYPE_UMTS)
+        val identWifiImsiNullSsid1 = buildNetworkIdentity(
+                mockContext, buildWifiNetworkState(null, TEST_SSID1), true, 0)
+        val identWifiImsi1Ssid1 = buildNetworkIdentity(
+                mockContext, buildWifiNetworkState(TEST_IMSI1, TEST_SSID1), true, 0)
+
+        templateWifiWildcard.assertDoesNotMatch(identMobileImsi1)
+        templateWifiWildcard.assertMatches(identWifiImsiNullSsid1)
+        templateWifiWildcard.assertMatches(identWifiImsi1Ssid1)
+    }
+
+    @Test
+    fun testWifiMatches() {
+        val templateWifiSsid1 = buildTemplateWifi(TEST_SSID1)
+        val templateWifiSsid1ImsiNull = buildTemplateWifi(TEST_SSID1, null)
+        val templateWifiSsid1Imsi1 = buildTemplateWifi(TEST_SSID1, TEST_IMSI1)
+        val templateWifiSsidAllImsi1 = buildTemplateWifi(WIFI_NETWORKID_ALL, TEST_IMSI1)
+
+        val identMobile1 = buildNetworkIdentity(mockContext, buildMobileNetworkState(TEST_IMSI1),
+                false, TelephonyManager.NETWORK_TYPE_UMTS)
+        val identWifiImsiNullSsid1 = buildNetworkIdentity(
+                mockContext, buildWifiNetworkState(null, TEST_SSID1), true, 0)
+        val identWifiImsi1Ssid1 = buildNetworkIdentity(
+                mockContext, buildWifiNetworkState(TEST_IMSI1, TEST_SSID1), true, 0)
+        val identWifiImsi2Ssid1 = buildNetworkIdentity(
+                mockContext, buildWifiNetworkState(TEST_IMSI2, TEST_SSID1), true, 0)
+        val identWifiImsi1Ssid2 = buildNetworkIdentity(
+                mockContext, buildWifiNetworkState(TEST_IMSI1, TEST_SSID2), true, 0)
+
+        // Verify that template with SSID only matches any subscriberId and specific SSID.
+        templateWifiSsid1.assertDoesNotMatch(identMobile1)
+        templateWifiSsid1.assertMatches(identWifiImsiNullSsid1)
+        templateWifiSsid1.assertMatches(identWifiImsi1Ssid1)
+        templateWifiSsid1.assertMatches(identWifiImsi2Ssid1)
+        templateWifiSsid1.assertDoesNotMatch(identWifiImsi1Ssid2)
+
+        // Verify that template with SSID1 and null imsi matches any network with
+        // SSID1 and null imsi.
+        templateWifiSsid1ImsiNull.assertDoesNotMatch(identMobile1)
+        templateWifiSsid1ImsiNull.assertMatches(identWifiImsiNullSsid1)
+        templateWifiSsid1ImsiNull.assertDoesNotMatch(identWifiImsi1Ssid1)
+        templateWifiSsid1ImsiNull.assertDoesNotMatch(identWifiImsi2Ssid1)
+        templateWifiSsid1ImsiNull.assertDoesNotMatch(identWifiImsi1Ssid2)
+
+        // Verify that template with SSID1 and imsi1 matches any network with
+        // SSID1 and imsi1.
+        templateWifiSsid1Imsi1.assertDoesNotMatch(identMobile1)
+        templateWifiSsid1Imsi1.assertDoesNotMatch(identWifiImsiNullSsid1)
+        templateWifiSsid1Imsi1.assertMatches(identWifiImsi1Ssid1)
+        templateWifiSsid1Imsi1.assertDoesNotMatch(identWifiImsi2Ssid1)
+        templateWifiSsid1Imsi1.assertDoesNotMatch(identWifiImsi1Ssid2)
+
+        // Verify that template with SSID all and imsi1 matches any network with
+        // any SSID and imsi1.
+        templateWifiSsidAllImsi1.assertDoesNotMatch(identMobile1)
+        templateWifiSsidAllImsi1.assertDoesNotMatch(identWifiImsiNullSsid1)
+        templateWifiSsidAllImsi1.assertMatches(identWifiImsi1Ssid1)
+        templateWifiSsidAllImsi1.assertDoesNotMatch(identWifiImsi2Ssid1)
+        templateWifiSsidAllImsi1.assertMatches(identWifiImsi1Ssid2)
+    }
+
+    @Test
+    fun testCarrierMatches() {
+        val templateCarrierImsi1 = buildTemplateCarrier(TEST_IMSI1)
+
+        val identMobile1 = buildNetworkIdentity(mockContext, buildMobileNetworkState(TEST_IMSI1),
+                false, TelephonyManager.NETWORK_TYPE_UMTS)
+        val identMobile2 = buildNetworkIdentity(mockContext, buildMobileNetworkState(TEST_IMSI2),
+                false, TelephonyManager.NETWORK_TYPE_UMTS)
+        val identWifiSsid1 = buildNetworkIdentity(
+                mockContext, buildWifiNetworkState(null, TEST_SSID1), true, 0)
+        val identCarrierWifiImsi1 = buildNetworkIdentity(
+                mockContext, buildWifiNetworkState(TEST_IMSI1, TEST_SSID1), true, 0)
+        val identCarrierWifiImsi2 = buildNetworkIdentity(
+                mockContext, buildWifiNetworkState(TEST_IMSI2, TEST_SSID1), true, 0)
+
+        templateCarrierImsi1.assertMatches(identCarrierWifiImsi1)
+        templateCarrierImsi1.assertDoesNotMatch(identCarrierWifiImsi2)
+        templateCarrierImsi1.assertDoesNotMatch(identWifiSsid1)
+        templateCarrierImsi1.assertMatches(identMobile1)
+        templateCarrierImsi1.assertDoesNotMatch(identMobile2)
+    }
+
+    @Test
     fun testRatTypeGroupMatches() {
         val stateMobile = buildMobileNetworkState(TEST_IMSI1)
         // Build UMTS template that matches mobile identities with RAT in the same
@@ -117,7 +212,7 @@
         val identImsi2 = buildNetworkIdentity(mockContext, buildMobileNetworkState(TEST_IMSI2),
                 false, TelephonyManager.NETWORK_TYPE_UMTS)
         val identWifi = buildNetworkIdentity(
-                mockContext, buildWifiNetworkState(TEST_SSID1), true, 0)
+                mockContext, buildWifiNetworkState(null, TEST_SSID1), true, 0)
 
         // Assert that identity with the same RAT matches.
         templateUmts.assertMatches(identUmts)
@@ -151,14 +246,16 @@
     fun testParcelUnparcel() {
         val templateMobile = NetworkTemplate(MATCH_MOBILE, TEST_IMSI1, null, null, METERED_ALL,
                 ROAMING_ALL, DEFAULT_NETWORK_ALL, TelephonyManager.NETWORK_TYPE_LTE,
-                OEM_MANAGED_ALL)
+                OEM_MANAGED_ALL, SUBSCRIBER_ID_MATCH_RULE_EXACT)
         val templateWifi = NetworkTemplate(MATCH_WIFI, null, null, TEST_SSID1, METERED_ALL,
-                ROAMING_ALL, DEFAULT_NETWORK_ALL, 0, OEM_MANAGED_ALL)
+                ROAMING_ALL, DEFAULT_NETWORK_ALL, 0, OEM_MANAGED_ALL,
+                SUBSCRIBER_ID_MATCH_RULE_EXACT)
         val templateOem = NetworkTemplate(MATCH_MOBILE, null, null, null, METERED_ALL,
-                ROAMING_ALL, DEFAULT_NETWORK_ALL, 0, OEM_MANAGED_YES)
-        assertParcelSane(templateMobile, 9)
-        assertParcelSane(templateWifi, 9)
-        assertParcelSane(templateOem, 9)
+                ROAMING_ALL, DEFAULT_NETWORK_ALL, 0, OEM_MANAGED_YES,
+                SUBSCRIBER_ID_MATCH_RULE_EXACT)
+        assertParcelSane(templateMobile, 10)
+        assertParcelSane(templateWifi, 10)
+        assertParcelSane(templateOem, 10)
     }
 
     // Verify NETWORK_TYPE_* constants in NetworkTemplate do not conflict with
@@ -207,15 +304,14 @@
         identSsid: String? = null
     ) {
         val oemManagedStates = arrayOf(OEM_NONE, OEM_PAID, OEM_PRIVATE, OEM_PAID or OEM_PRIVATE)
-        // A null subscriberId needs a null matchSubscriberIds argument as well.
-        val matchSubscriberIds = if (subscriberId == null) null else arrayOf(subscriberId)
+        val matchSubscriberIds = arrayOf(subscriberId)
 
         val templateOemYes = NetworkTemplate(matchType, subscriberId, matchSubscriberIds,
                 templateSsid, METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
-                OEM_MANAGED_YES)
+                OEM_MANAGED_YES, SUBSCRIBER_ID_MATCH_RULE_EXACT)
         val templateOemAll = NetworkTemplate(matchType, subscriberId, matchSubscriberIds,
                 templateSsid, METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
-                OEM_MANAGED_ALL)
+                OEM_MANAGED_ALL, SUBSCRIBER_ID_MATCH_RULE_EXACT)
 
         for (identityOemManagedState in oemManagedStates) {
             val ident = buildNetworkIdentity(mockContext, buildNetworkState(networkType,
@@ -226,7 +322,7 @@
             for (templateOemManagedState in oemManagedStates) {
                 val template = NetworkTemplate(matchType, subscriberId, matchSubscriberIds,
                         templateSsid, METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL,
-                        NETWORK_TYPE_ALL, templateOemManagedState)
+                        NETWORK_TYPE_ALL, templateOemManagedState, SUBSCRIBER_ID_MATCH_RULE_EXACT)
                 if (identityOemManagedState == templateOemManagedState) {
                     template.assertMatches(ident)
                 } else {
diff --git a/tests/net/java/android/net/VpnTransportInfoTest.java b/tests/net/java/android/net/VpnTransportInfoTest.java
index fee65f0..ccaa5cf 100644
--- a/tests/net/java/android/net/VpnTransportInfoTest.java
+++ b/tests/net/java/android/net/VpnTransportInfoTest.java
@@ -63,6 +63,6 @@
         assertEquals(v31, v32);
         assertEquals(v11.hashCode(), v13.hashCode());
         assertEquals(REDACT_FOR_NETWORK_SETTINGS, v32.getApplicableRedactions());
-        assertEquals(session1, v15.makeCopy(REDACT_NONE).sessionId);
+        assertEquals(session1, v15.makeCopy(REDACT_NONE).getSessionId());
     }
 }
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 05d5d34..ab50798 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -44,9 +44,6 @@
 import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
 import static android.net.ConnectivityManager.EXTRA_NETWORK_INFO;
 import static android.net.ConnectivityManager.EXTRA_NETWORK_TYPE;
-import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OFF;
-import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC;
-import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME;
 import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_DEFAULT;
 import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE;
 import static android.net.ConnectivityManager.TYPE_ETHERNET;
@@ -57,6 +54,9 @@
 import static android.net.ConnectivityManager.TYPE_PROXY;
 import static android.net.ConnectivityManager.TYPE_VPN;
 import static android.net.ConnectivityManager.TYPE_WIFI;
+import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_OFF;
+import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_OPPORTUNISTIC;
+import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME;
 import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_DNS;
 import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_FALLBACK;
 import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_HTTP;
@@ -1404,7 +1404,7 @@
         final TransportInfo ti = nc.getTransportInfo();
         assertTrue("VPN TransportInfo is not a VpnTransportInfo: " + ti,
                 ti instanceof VpnTransportInfo);
-        assertEquals(type, ((VpnTransportInfo) ti).type);
+        assertEquals(type, ((VpnTransportInfo) ti).getType());
 
     }
 
@@ -1808,7 +1808,7 @@
         assertNull(mCm.getActiveNetworkForUid(Process.myUid()));
         // Test getAllNetworks()
         assertEmpty(mCm.getAllNetworks());
-        assertEmpty(mCm.getAllNetworkStateSnapshot());
+        assertEmpty(mCm.getAllNetworkStateSnapshots());
     }
 
     /**
@@ -2813,8 +2813,9 @@
 
     private void grantUsingBackgroundNetworksPermissionForUid(
             final int uid, final String packageName) throws Exception {
-        when(mPackageManager.getPackageInfo(eq(packageName), eq(GET_PERMISSIONS)))
-                .thenReturn(buildPackageInfo(true, uid));
+        when(mPackageManager.getPackageInfo(
+                eq(packageName), eq(GET_PERMISSIONS | MATCH_ANY_USER)))
+                .thenReturn(buildPackageInfo(true /* hasSystemPermission */, uid));
         mService.mPermissionMonitor.onPackageAdded(packageName, uid);
     }
 
@@ -2942,7 +2943,7 @@
         callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
 
         // Set teardown delay and make sure CS has processed it.
-        mWiFiNetworkAgent.getNetworkAgent().setTeardownDelayMs(300);
+        mWiFiNetworkAgent.getNetworkAgent().setTeardownDelayMillis(300);
         waitForIdle();
 
         // Post the duringTeardown lambda to the handler so it fires while teardown is in progress.
@@ -4230,7 +4231,7 @@
                 () -> mCm.registerSystemDefaultNetworkCallback(callback, handler));
         callback.assertNoCallback();
         assertThrows(SecurityException.class,
-                () -> mCm.registerDefaultNetworkCallbackAsUid(APP1_UID, callback, handler));
+                () -> mCm.registerDefaultNetworkCallbackForUid(APP1_UID, callback, handler));
         callback.assertNoCallback();
 
         mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED);
@@ -4238,7 +4239,7 @@
         callback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent);
         mCm.unregisterNetworkCallback(callback);
 
-        mCm.registerDefaultNetworkCallbackAsUid(APP1_UID, callback, handler);
+        mCm.registerDefaultNetworkCallbackForUid(APP1_UID, callback, handler);
         callback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent);
         mCm.unregisterNetworkCallback(callback);
     }
@@ -4256,10 +4257,9 @@
         waitForIdle();
     }
 
-    private void setPrivateDnsSettings(String mode, String specifier) {
-        final ContentResolver cr = mServiceContext.getContentResolver();
-        Settings.Global.putString(cr, ConnectivitySettingsManager.PRIVATE_DNS_MODE, mode);
-        Settings.Global.putString(cr, ConnectivitySettingsManager.PRIVATE_DNS_SPECIFIER, specifier);
+    private void setPrivateDnsSettings(int mode, String specifier) {
+        ConnectivitySettingsManager.setPrivateDnsMode(mServiceContext, mode);
+        ConnectivitySettingsManager.setPrivateDnsHostname(mServiceContext, specifier);
         mService.updatePrivateDnsSettings();
         waitForIdle();
     }
@@ -5614,7 +5614,7 @@
             for (int i = 0; i < SYSTEM_ONLY_MAX_REQUESTS - 1; i++) {
                 NetworkCallback cb = new NetworkCallback();
                 if (i % 2 == 0) {
-                    mCm.registerDefaultNetworkCallbackAsUid(1000000 + i, cb, handler);
+                    mCm.registerDefaultNetworkCallbackForUid(1000000 + i, cb, handler);
                 } else {
                     mCm.registerNetworkCallback(networkRequest, cb);
                 }
@@ -5623,7 +5623,7 @@
             waitForIdle();
 
             assertThrows(TooManyRequestsException.class, () ->
-                    mCm.registerDefaultNetworkCallbackAsUid(1001042, new NetworkCallback(),
+                    mCm.registerDefaultNetworkCallbackForUid(1001042, new NetworkCallback(),
                             handler));
             assertThrows(TooManyRequestsException.class, () ->
                     mCm.registerNetworkCallback(networkRequest, new NetworkCallback()));
@@ -5676,7 +5676,7 @@
         withPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, () -> {
             for (int i = 0; i < MAX_REQUESTS; i++) {
                 NetworkCallback networkCallback = new NetworkCallback();
-                mCm.registerDefaultNetworkCallbackAsUid(1000000 + i, networkCallback,
+                mCm.registerDefaultNetworkCallbackForUid(1000000 + i, networkCallback,
                         new Handler(ConnectivityThread.getInstanceLooper()));
                 mCm.unregisterNetworkCallback(networkCallback);
             }
@@ -5833,10 +5833,10 @@
         if (vpnUid != null) {
             assertEquals("Should have exactly one VPN:", 1, infos.length);
             UnderlyingNetworkInfo info = infos[0];
-            assertEquals("Unexpected VPN owner:", (int) vpnUid, info.ownerUid);
-            assertEquals("Unexpected VPN interface:", vpnIfname, info.iface);
+            assertEquals("Unexpected VPN owner:", (int) vpnUid, info.getOwnerUid());
+            assertEquals("Unexpected VPN interface:", vpnIfname, info.getIface());
             assertSameElementsNoDuplicates(underlyingIfaces,
-                    info.underlyingIfaces.toArray(new String[0]));
+                    info.getUnderlyingIfaces().toArray(new String[0]));
         } else {
             assertEquals(0, infos.length);
             return;
@@ -5980,8 +5980,8 @@
         // network for the VPN...
         verify(mStatsManager, never()).notifyNetworkStatus(any(List.class),
                 any(List.class), any() /* anyString() doesn't match null */,
-                argThat(infos -> infos.get(0).underlyingIfaces.size() == 1
-                        && WIFI_IFNAME.equals(infos.get(0).underlyingIfaces.get(0))));
+                argThat(infos -> infos.get(0).getUnderlyingIfaces().size() == 1
+                        && WIFI_IFNAME.equals(infos.get(0).getUnderlyingIfaces().get(0))));
         verifyNoMoreInteractions(mStatsManager);
         reset(mStatsManager);
 
@@ -5994,8 +5994,8 @@
         waitForIdle();
         verify(mStatsManager).notifyNetworkStatus(any(List.class),
                 any(List.class), any() /* anyString() doesn't match null */,
-                argThat(vpnInfos -> vpnInfos.get(0).underlyingIfaces.size() == 1
-                        && WIFI_IFNAME.equals(vpnInfos.get(0).underlyingIfaces.get(0))));
+                argThat(vpnInfos -> vpnInfos.get(0).getUnderlyingIfaces().size() == 1
+                        && WIFI_IFNAME.equals(vpnInfos.get(0).getUnderlyingIfaces().get(0))));
         mEthernetNetworkAgent.disconnect();
         waitForIdle();
         reset(mStatsManager);
@@ -7761,7 +7761,7 @@
         registerDefaultNetworkCallbackAsUid(vpnUidDefaultCallback, VPN_UID);
 
         final TestNetworkCallback vpnDefaultCallbackAsUid = new TestNetworkCallback();
-        mCm.registerDefaultNetworkCallbackAsUid(VPN_UID, vpnDefaultCallbackAsUid,
+        mCm.registerDefaultNetworkCallbackForUid(VPN_UID, vpnDefaultCallbackAsUid,
                 new Handler(ConnectivityThread.getInstanceLooper()));
 
         final int uid = Process.myUid();
@@ -10338,7 +10338,7 @@
         assertTrue(mRequests.get(0).hasCapability(NET_CAPABILITY_VALIDATED));
         assertTrue(mRequests.get(1).isRequest());
         assertTrue(mRequests.get(1).hasCapability(NET_CAPABILITY_OEM_PAID));
-        assertTrue(mRequests.get(2).isRequest());
+        assertEquals(NetworkRequest.Type.TRACK_DEFAULT, mRequests.get(2).type);
         assertTrue(mService.getDefaultRequest().networkCapabilities.equalsNetCapabilities(
                 mRequests.get(2).networkCapabilities));
     }
@@ -10850,7 +10850,7 @@
 
         final TestNetworkCallback otherUidDefaultCallback = new TestNetworkCallback();
         withPermission(NETWORK_SETTINGS, () ->
-                mCm.registerDefaultNetworkCallbackAsUid(TEST_PACKAGE_UID, otherUidDefaultCallback,
+                mCm.registerDefaultNetworkCallbackForUid(TEST_PACKAGE_UID, otherUidDefaultCallback,
                         new Handler(ConnectivityThread.getInstanceLooper())));
 
         // Setup the test process to use networkPref for their default network.
@@ -10898,7 +10898,7 @@
 
         final TestNetworkCallback otherUidDefaultCallback = new TestNetworkCallback();
         withPermission(NETWORK_SETTINGS, () ->
-                mCm.registerDefaultNetworkCallbackAsUid(TEST_PACKAGE_UID, otherUidDefaultCallback,
+                mCm.registerDefaultNetworkCallbackForUid(TEST_PACKAGE_UID, otherUidDefaultCallback,
                         new Handler(ConnectivityThread.getInstanceLooper())));
 
         // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID.
@@ -10940,7 +10940,7 @@
 
         final TestNetworkCallback otherUidDefaultCallback = new TestNetworkCallback();
         withPermission(NETWORK_SETTINGS, () ->
-                mCm.registerDefaultNetworkCallbackAsUid(TEST_PACKAGE_UID, otherUidDefaultCallback,
+                mCm.registerDefaultNetworkCallbackForUid(TEST_PACKAGE_UID, otherUidDefaultCallback,
                         new Handler(ConnectivityThread.getInstanceLooper())));
 
         // Setup a process different than the test process to use the default network. This means
@@ -11757,7 +11757,7 @@
     }
 
     @Test
-    public void testGetAllNetworkStateSnapshot() throws Exception {
+    public void testGetAllNetworkStateSnapshots() throws Exception {
         verifyNoNetwork();
 
         // Setup test cellular network with specified LinkProperties and NetworkCapabilities,
@@ -11781,7 +11781,7 @@
         mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp, cellNcTemplate);
         mCellNetworkAgent.connect(true);
         cellCb.expectAvailableCallbacksUnvalidated(mCellNetworkAgent);
-        List<NetworkStateSnapshot> snapshots = mCm.getAllNetworkStateSnapshot();
+        List<NetworkStateSnapshot> snapshots = mCm.getAllNetworkStateSnapshots();
         assertLength(1, snapshots);
 
         // Compose the expected cellular snapshot for verification.
@@ -11803,7 +11803,7 @@
                 mWiFiNetworkAgent.getNetwork(), wifiNc, new LinkProperties(), null,
                 ConnectivityManager.TYPE_WIFI);
 
-        snapshots = mCm.getAllNetworkStateSnapshot();
+        snapshots = mCm.getAllNetworkStateSnapshots();
         assertLength(2, snapshots);
         assertContainsAll(snapshots, cellSnapshot, wifiSnapshot);
 
@@ -11812,20 +11812,20 @@
         //  temporary shortage of connectivity of a connected network.
         mCellNetworkAgent.suspend();
         waitForIdle();
-        snapshots = mCm.getAllNetworkStateSnapshot();
+        snapshots = mCm.getAllNetworkStateSnapshots();
         assertLength(1, snapshots);
         assertEquals(wifiSnapshot, snapshots.get(0));
 
         // Disconnect wifi, verify the snapshots contain nothing.
         mWiFiNetworkAgent.disconnect();
         waitForIdle();
-        snapshots = mCm.getAllNetworkStateSnapshot();
+        snapshots = mCm.getAllNetworkStateSnapshots();
         assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
         assertLength(0, snapshots);
 
         mCellNetworkAgent.resume();
         waitForIdle();
-        snapshots = mCm.getAllNetworkStateSnapshot();
+        snapshots = mCm.getAllNetworkStateSnapshots();
         assertLength(1, snapshots);
         assertEquals(cellSnapshot, snapshots.get(0));
 
diff --git a/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java b/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
index 32c95f1..cf2c9c7 100644
--- a/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
+++ b/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
@@ -16,9 +16,14 @@
 
 package com.android.server;
 
+import static android.content.pm.PackageManager.PERMISSION_DENIED;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.net.INetd.IF_STATE_DOWN;
 import static android.net.INetd.IF_STATE_UP;
+import static android.net.IpSecManager.DIRECTION_FWD;
+import static android.net.IpSecManager.DIRECTION_IN;
+import static android.net.IpSecManager.DIRECTION_OUT;
+import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
 import static android.system.OsConstants.AF_INET;
 import static android.system.OsConstants.AF_INET6;
 
@@ -56,6 +61,7 @@
 import android.os.ParcelFileDescriptor;
 import android.system.Os;
 import android.test.mock.MockContext;
+import android.util.ArraySet;
 
 import androidx.test.filters.SmallTest;
 
@@ -71,6 +77,7 @@
 import java.net.Socket;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Set;
 
 /** Unit tests for {@link IpSecService}. */
 @SmallTest
@@ -119,7 +126,18 @@
     AppOpsManager mMockAppOps = mock(AppOpsManager.class);
     ConnectivityManager mMockConnectivityMgr = mock(ConnectivityManager.class);
 
-    MockContext mMockContext = new MockContext() {
+    TestContext mTestContext = new TestContext();
+
+    private class TestContext extends MockContext {
+        private Set<String> mAllowedPermissions = new ArraySet<>(Arrays.asList(
+                android.Manifest.permission.MANAGE_IPSEC_TUNNELS,
+                android.Manifest.permission.NETWORK_STACK,
+                PERMISSION_MAINLINE_NETWORK_STACK));
+
+        private void setAllowedPermissions(String... permissions) {
+            mAllowedPermissions = new ArraySet<>(permissions);
+        }
+
         @Override
         public Object getSystemService(String name) {
             switch(name) {
@@ -147,20 +165,22 @@
 
         @Override
         public void enforceCallingOrSelfPermission(String permission, String message) {
-            if (permission == android.Manifest.permission.MANAGE_IPSEC_TUNNELS) {
+            if (mAllowedPermissions.contains(permission)) {
                 return;
+            } else {
+                throw new SecurityException("Unavailable permission requested");
             }
-            throw new SecurityException("Unavailable permission requested");
         }
 
         @Override
         public int checkCallingOrSelfPermission(String permission) {
-            if (android.Manifest.permission.NETWORK_STACK.equals(permission)) {
+            if (mAllowedPermissions.contains(permission)) {
                 return PERMISSION_GRANTED;
+            } else {
+                return PERMISSION_DENIED;
             }
-            throw new UnsupportedOperationException();
         }
-    };
+    }
 
     INetd mMockNetd;
     PackageManager mMockPkgMgr;
@@ -194,7 +214,7 @@
         mMockNetd = mock(INetd.class);
         mMockPkgMgr = mock(PackageManager.class);
         mMockIpSecSrvConfig = mock(IpSecService.IpSecServiceConfiguration.class);
-        mIpSecService = new IpSecService(mMockContext, mMockIpSecSrvConfig);
+        mIpSecService = new IpSecService(mTestContext, mMockIpSecSrvConfig);
 
         // Injecting mock netd
         when(mMockIpSecSrvConfig.getNetdInstance()).thenReturn(mMockNetd);
@@ -664,6 +684,21 @@
 
         assertNotNull(createTunnelResp);
         assertEquals(IpSecManager.Status.OK, createTunnelResp.status);
+        for (int direction : new int[] {DIRECTION_IN, DIRECTION_OUT, DIRECTION_FWD}) {
+            for (int selAddrFamily : ADDRESS_FAMILIES) {
+                verify(mMockNetd).ipSecAddSecurityPolicy(
+                        eq(mUid),
+                        eq(selAddrFamily),
+                        eq(direction),
+                        anyString(),
+                        anyString(),
+                        eq(0),
+                        anyInt(), // iKey/oKey
+                        anyInt(), // mask
+                        eq(createTunnelResp.resourceId));
+            }
+        }
+
         return createTunnelResp;
     }
 
@@ -798,16 +833,51 @@
     }
 
     @Test
-    public void testApplyTunnelModeTransform() throws Exception {
-        verifyApplyTunnelModeTransformCommon(false);
+    public void testApplyTunnelModeTransformOutbound() throws Exception {
+        verifyApplyTunnelModeTransformCommon(false /* closeSpiBeforeApply */, DIRECTION_OUT);
     }
 
     @Test
-    public void testApplyTunnelModeTransformReleasedSpi() throws Exception {
-        verifyApplyTunnelModeTransformCommon(true);
+    public void testApplyTunnelModeTransformOutboundNonNetworkStack() throws Exception {
+        mTestContext.setAllowedPermissions(android.Manifest.permission.MANAGE_IPSEC_TUNNELS);
+        verifyApplyTunnelModeTransformCommon(false /* closeSpiBeforeApply */, DIRECTION_OUT);
     }
 
-    public void verifyApplyTunnelModeTransformCommon(boolean closeSpiBeforeApply) throws Exception {
+    @Test
+    public void testApplyTunnelModeTransformOutboundReleasedSpi() throws Exception {
+        verifyApplyTunnelModeTransformCommon(true /* closeSpiBeforeApply */, DIRECTION_OUT);
+    }
+
+    @Test
+    public void testApplyTunnelModeTransformInbound() throws Exception {
+        verifyApplyTunnelModeTransformCommon(true /* closeSpiBeforeApply */, DIRECTION_IN);
+    }
+
+    @Test
+    public void testApplyTunnelModeTransformInboundNonNetworkStack() throws Exception {
+        mTestContext.setAllowedPermissions(android.Manifest.permission.MANAGE_IPSEC_TUNNELS);
+        verifyApplyTunnelModeTransformCommon(true /* closeSpiBeforeApply */, DIRECTION_IN);
+    }
+
+    @Test
+    public void testApplyTunnelModeTransformForward() throws Exception {
+        verifyApplyTunnelModeTransformCommon(true /* closeSpiBeforeApply */, DIRECTION_FWD);
+    }
+
+    @Test
+    public void testApplyTunnelModeTransformForwardNonNetworkStack() throws Exception {
+        mTestContext.setAllowedPermissions(android.Manifest.permission.MANAGE_IPSEC_TUNNELS);
+
+        try {
+            verifyApplyTunnelModeTransformCommon(true /* closeSpiBeforeApply */, DIRECTION_FWD);
+            fail("Expected security exception due to use of forward policies without NETWORK_STACK"
+                     + " or MAINLINE_NETWORK_STACK permission");
+        } catch (SecurityException expected) {
+        }
+    }
+
+    public void verifyApplyTunnelModeTransformCommon(boolean closeSpiBeforeApply, int direction)
+            throws Exception {
         IpSecConfig ipSecConfig = new IpSecConfig();
         ipSecConfig.setMode(IpSecTransform.MODE_TUNNEL);
         addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
@@ -825,17 +895,17 @@
         int transformResourceId = createTransformResp.resourceId;
         int tunnelResourceId = createTunnelResp.resourceId;
         mIpSecService.applyTunnelModeTransform(
-                tunnelResourceId, IpSecManager.DIRECTION_OUT, transformResourceId, BLESSED_PACKAGE);
+                tunnelResourceId, direction, transformResourceId, BLESSED_PACKAGE);
 
         for (int selAddrFamily : ADDRESS_FAMILIES) {
             verify(mMockNetd)
                     .ipSecUpdateSecurityPolicy(
                             eq(mUid),
                             eq(selAddrFamily),
-                            eq(IpSecManager.DIRECTION_OUT),
+                            eq(direction),
                             anyString(),
                             anyString(),
-                            eq(TEST_SPI),
+                            eq(direction == DIRECTION_OUT ? TEST_SPI : 0),
                             anyInt(), // iKey/oKey
                             anyInt(), // mask
                             eq(tunnelResourceId));
diff --git a/tests/net/java/com/android/server/connectivity/DnsManagerTest.java b/tests/net/java/com/android/server/connectivity/DnsManagerTest.java
index 692c50f..0ffeec9 100644
--- a/tests/net/java/com/android/server/connectivity/DnsManagerTest.java
+++ b/tests/net/java/com/android/server/connectivity/DnsManagerTest.java
@@ -16,10 +16,10 @@
 
 package com.android.server.connectivity;
 
-import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OFF;
-import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME;
 import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_DEFAULT_MODE;
 import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE;
+import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_OFF;
+import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME;
 import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_SPECIFIER;
 import static android.net.NetworkCapabilities.MAX_TRANSPORT;
 import static android.net.NetworkCapabilities.MIN_TRANSPORT;
@@ -44,6 +44,7 @@
 
 import android.annotation.NonNull;
 import android.content.Context;
+import android.net.ConnectivitySettingsManager;
 import android.net.IDnsResolver;
 import android.net.IpPrefix;
 import android.net.LinkAddress;
@@ -187,9 +188,8 @@
         lp.addRoute(new RouteInfo((IpPrefix) null, InetAddress.getByName("2001:db8:1::1"),
                 TEST_IFACENAME));
 
-        Settings.Global.putString(mContentResolver,
-                PRIVATE_DNS_MODE, PRIVATE_DNS_MODE_PROVIDER_HOSTNAME);
-        Settings.Global.putString(mContentResolver, PRIVATE_DNS_SPECIFIER, "strictmode.com");
+        ConnectivitySettingsManager.setPrivateDnsMode(mCtx, PRIVATE_DNS_MODE_PROVIDER_HOSTNAME);
+        ConnectivitySettingsManager.setPrivateDnsHostname(mCtx, "strictmode.com");
         mDnsManager.updatePrivateDns(new Network(TEST_NETID),
                 new PrivateDnsConfig("strictmode.com", new InetAddress[] {
                     InetAddress.parseNumericAddress("6.6.6.6"),
@@ -294,7 +294,7 @@
         assertNull(lp.getPrivateDnsServerName());
 
         // Turn private DNS mode off
-        Settings.Global.putString(mContentResolver, PRIVATE_DNS_MODE, PRIVATE_DNS_MODE_OFF);
+        ConnectivitySettingsManager.setPrivateDnsMode(mCtx, PRIVATE_DNS_MODE_OFF);
         mDnsManager.updatePrivateDns(new Network(TEST_NETID),
                 mDnsManager.getPrivateDnsConfig());
         mDnsManager.updateTransportsForNetwork(TEST_NETID, TEST_TRANSPORT_TYPES);
@@ -318,16 +318,15 @@
         assertEquals(new InetAddress[0], cfgAuto.ips);
 
         // Pretend a gservices push sets the default to "off".
-        Settings.Global.putString(mContentResolver, PRIVATE_DNS_DEFAULT_MODE, "off");
+        ConnectivitySettingsManager.setPrivateDnsDefaultMode(mCtx, PRIVATE_DNS_MODE_OFF);
         final PrivateDnsConfig cfgOff = DnsManager.getPrivateDnsConfig(mCtx);
         assertFalse(cfgOff.useTls);
         assertEquals("", cfgOff.hostname);
         assertEquals(new InetAddress[0], cfgOff.ips);
 
         // Strict mode still works.
-        Settings.Global.putString(
-                mContentResolver, PRIVATE_DNS_MODE, PRIVATE_DNS_MODE_PROVIDER_HOSTNAME);
-        Settings.Global.putString(mContentResolver, PRIVATE_DNS_SPECIFIER, "strictmode.com");
+        ConnectivitySettingsManager.setPrivateDnsMode(mCtx, PRIVATE_DNS_MODE_PROVIDER_HOSTNAME);
+        ConnectivitySettingsManager.setPrivateDnsHostname(mCtx, "strictmode.com");
         final PrivateDnsConfig cfgStrict = DnsManager.getPrivateDnsConfig(mCtx);
         assertTrue(cfgStrict.useTls);
         assertEquals("strictmode.com", cfgStrict.hostname);
diff --git a/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java b/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java
index d7535a9..02a5808 100644
--- a/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java
+++ b/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java
@@ -479,13 +479,14 @@
     public void testUidFilteringDuringVpnConnectDisconnectAndUidUpdates() throws Exception {
         when(mPackageManager.getInstalledPackages(eq(GET_PERMISSIONS | MATCH_ANY_USER))).thenReturn(
                 Arrays.asList(new PackageInfo[] {
-                        buildPackageInfo(/* SYSTEM */ true, SYSTEM_UID1, MOCK_USER1),
-                        buildPackageInfo(/* SYSTEM */ false, MOCK_UID1, MOCK_USER1),
-                        buildPackageInfo(/* SYSTEM */ false, MOCK_UID2, MOCK_USER1),
-                        buildPackageInfo(/* SYSTEM */ false, VPN_UID, MOCK_USER1)
+                        buildPackageInfo(true /* hasSystemPermission */, SYSTEM_UID1, MOCK_USER1),
+                        buildPackageInfo(false /* hasSystemPermission */, MOCK_UID1, MOCK_USER1),
+                        buildPackageInfo(false /* hasSystemPermission */, MOCK_UID2, MOCK_USER1),
+                        buildPackageInfo(false /* hasSystemPermission */, VPN_UID, MOCK_USER1)
                 }));
-        when(mPackageManager.getPackageInfo(eq(MOCK_PACKAGE1), eq(GET_PERMISSIONS))).thenReturn(
-                buildPackageInfo(false, MOCK_UID1, MOCK_USER1));
+        when(mPackageManager.getPackageInfo(eq(MOCK_PACKAGE1),
+                eq(GET_PERMISSIONS | MATCH_ANY_USER))).thenReturn(
+                buildPackageInfo(false /* hasSystemPermission */, MOCK_UID1, MOCK_USER1));
         mPermissionMonitor.startMonitoring();
         // Every app on user 0 except MOCK_UID2 are under VPN.
         final Set<UidRange> vpnRange1 = new HashSet<>(Arrays.asList(new UidRange[] {
@@ -530,11 +531,12 @@
     public void testUidFilteringDuringPackageInstallAndUninstall() throws Exception {
         when(mPackageManager.getInstalledPackages(eq(GET_PERMISSIONS | MATCH_ANY_USER))).thenReturn(
                 Arrays.asList(new PackageInfo[] {
-                        buildPackageInfo(true, SYSTEM_UID1, MOCK_USER1),
-                        buildPackageInfo(false, VPN_UID, MOCK_USER1)
+                        buildPackageInfo(true /* hasSystemPermission */, SYSTEM_UID1, MOCK_USER1),
+                        buildPackageInfo(false /* hasSystemPermission */, VPN_UID, MOCK_USER1)
                 }));
-        when(mPackageManager.getPackageInfo(eq(MOCK_PACKAGE1), eq(GET_PERMISSIONS))).thenReturn(
-                        buildPackageInfo(false, MOCK_UID1, MOCK_USER1));
+        when(mPackageManager.getPackageInfo(eq(MOCK_PACKAGE1),
+                eq(GET_PERMISSIONS | MATCH_ANY_USER))).thenReturn(
+                buildPackageInfo(false /* hasSystemPermission */, MOCK_UID1, MOCK_USER1));
 
         mPermissionMonitor.startMonitoring();
         final Set<UidRange> vpnRange = Collections.singleton(UidRange.createForUser(MOCK_USER1));
diff --git a/tests/net/java/com/android/server/connectivity/VpnTest.java b/tests/net/java/com/android/server/connectivity/VpnTest.java
index 6ad4900..b725b82 100644
--- a/tests/net/java/com/android/server/connectivity/VpnTest.java
+++ b/tests/net/java/com/android/server/connectivity/VpnTest.java
@@ -1023,7 +1023,7 @@
         assertNotNull(nc);
         VpnTransportInfo ti = (VpnTransportInfo) nc.getTransportInfo();
         assertNotNull(ti);
-        assertEquals(type, ti.type);
+        assertEquals(type, ti.getType());
     }
 
     public void startRacoon(final String serverAddr, final String expectedAddr)
diff --git a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
index 0ab4d2b..fd374bc 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
@@ -45,6 +45,7 @@
 import static android.net.NetworkTemplate.NETWORK_TYPE_ALL;
 import static android.net.NetworkTemplate.OEM_MANAGED_NO;
 import static android.net.NetworkTemplate.OEM_MANAGED_YES;
+import static android.net.NetworkTemplate.SUBSCRIBER_ID_MATCH_RULE_EXACT;
 import static android.net.NetworkTemplate.buildTemplateMobileAll;
 import static android.net.NetworkTemplate.buildTemplateMobileWithRatType;
 import static android.net.NetworkTemplate.buildTemplateWifi;
@@ -669,24 +670,28 @@
     public void testMobileStatsOemManaged() throws Exception {
         final NetworkTemplate templateOemPaid = new NetworkTemplate(MATCH_MOBILE_WILDCARD,
                 /*subscriberId=*/null, /*matchSubscriberIds=*/null, /*networkId=*/null,
-                METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_PAID);
+                METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_PAID,
+                SUBSCRIBER_ID_MATCH_RULE_EXACT);
 
         final NetworkTemplate templateOemPrivate = new NetworkTemplate(MATCH_MOBILE_WILDCARD,
                 /*subscriberId=*/null, /*matchSubscriberIds=*/null, /*networkId=*/null,
-                METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_PRIVATE);
+                METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_PRIVATE,
+                SUBSCRIBER_ID_MATCH_RULE_EXACT);
 
         final NetworkTemplate templateOemAll = new NetworkTemplate(MATCH_MOBILE_WILDCARD,
                 /*subscriberId=*/null, /*matchSubscriberIds=*/null, /*networkId=*/null,
                 METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
-                OEM_PAID | OEM_PRIVATE);
+                OEM_PAID | OEM_PRIVATE, SUBSCRIBER_ID_MATCH_RULE_EXACT);
 
         final NetworkTemplate templateOemYes = new NetworkTemplate(MATCH_MOBILE_WILDCARD,
                 /*subscriberId=*/null, /*matchSubscriberIds=*/null, /*networkId=*/null,
-                METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_YES);
+                METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_YES,
+                SUBSCRIBER_ID_MATCH_RULE_EXACT);
 
         final NetworkTemplate templateOemNone = new NetworkTemplate(MATCH_MOBILE_WILDCARD,
                 /*subscriberId=*/null, /*matchSubscriberIds=*/null, /*networkId=*/null,
-                METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_NO);
+                METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_NO,
+                SUBSCRIBER_ID_MATCH_RULE_EXACT);
 
         // OEM_PAID network comes online.
         NetworkStateSnapshot[] states = new NetworkStateSnapshot[]{
@@ -889,7 +894,7 @@
         final LinkProperties stackedProp = new LinkProperties();
         stackedProp.setInterfaceName(stackedIface);
         final NetworkStateSnapshot wifiState = buildWifiState();
-        wifiState.linkProperties.addStackedLink(stackedProp);
+        wifiState.getLinkProperties().addStackedLink(stackedProp);
         NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {wifiState};
 
         expectNetworkStatsSummary(buildEmptyStats());
@@ -1580,10 +1585,10 @@
     }
 
     private String getActiveIface(NetworkStateSnapshot... states) throws Exception {
-        if (states == null || states.length == 0 || states[0].linkProperties == null) {
+        if (states == null || states.length == 0 || states[0].getLinkProperties() == null) {
             return null;
         }
-        return states[0].linkProperties.getInterfaceName();
+        return states[0].getLinkProperties().getInterfaceName();
     }
 
     private void expectNetworkStatsSummary(NetworkStats summary) throws Exception {
diff --git a/tests/vcn/java/android/net/vcn/VcnGatewayConnectionConfigTest.java b/tests/vcn/java/android/net/vcn/VcnGatewayConnectionConfigTest.java
index 0d3fd3f..c59dcf8 100644
--- a/tests/vcn/java/android/net/vcn/VcnGatewayConnectionConfigTest.java
+++ b/tests/vcn/java/android/net/vcn/VcnGatewayConnectionConfigTest.java
@@ -16,13 +16,17 @@
 
 package android.net.vcn;
 
+import static android.net.ipsec.ike.IkeSessionParams.IKE_OPTION_MOBIKE;
+
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
 import android.net.NetworkCapabilities;
-import android.net.TunnelConnectionParams;
+import android.net.ipsec.ike.IkeSessionParams;
+import android.net.ipsec.ike.IkeTunnelConnectionParams;
+import android.net.vcn.persistablebundleutils.IkeSessionParamsUtilsTest;
 import android.net.vcn.persistablebundleutils.TunnelConnectionParamsUtilsTest;
 
 import androidx.test.filters.SmallTest;
@@ -60,7 +64,7 @@
             };
     public static final int MAX_MTU = 1360;
 
-    public static final TunnelConnectionParams TUNNEL_CONNECTION_PARAMS =
+    public static final IkeTunnelConnectionParams TUNNEL_CONNECTION_PARAMS =
             TunnelConnectionParamsUtilsTest.buildTestParams();
 
     public static final String GATEWAY_CONNECTION_NAME_PREFIX = "gatewayConnectionName-";
@@ -82,7 +86,7 @@
     // Public for use in VcnGatewayConnectionTest
     public static VcnGatewayConnectionConfig buildTestConfigWithExposedCaps(int... exposedCaps) {
         final VcnGatewayConnectionConfig.Builder builder =
-                newBuilder().setRetryIntervalsMs(RETRY_INTERVALS_MS).setMaxMtu(MAX_MTU);
+                newBuilder().setRetryIntervalsMillis(RETRY_INTERVALS_MS).setMaxMtu(MAX_MTU);
 
         for (int caps : exposedCaps) {
             builder.addExposedCapability(caps);
@@ -120,6 +124,21 @@
     }
 
     @Test
+    public void testBuilderRequiresMobikeEnabled() {
+        try {
+            final IkeSessionParams ikeParams =
+                    IkeSessionParamsUtilsTest.createBuilderMinimum()
+                            .removeIkeOption(IKE_OPTION_MOBIKE)
+                            .build();
+            final IkeTunnelConnectionParams tunnelParams =
+                    TunnelConnectionParamsUtilsTest.buildTestParams(ikeParams);
+            new VcnGatewayConnectionConfig.Builder(GATEWAY_CONNECTION_NAME_PREFIX, tunnelParams);
+            fail("Expected exception due to MOBIKE not enabled");
+        } catch (IllegalArgumentException e) {
+        }
+    }
+
+    @Test
     public void testBuilderRequiresNonEmptyExposedCaps() {
         try {
             newBuilder()
@@ -134,7 +153,7 @@
     @Test
     public void testBuilderRequiresNonNullRetryInterval() {
         try {
-            newBuilder().setRetryIntervalsMs(null);
+            newBuilder().setRetryIntervalsMillis(null);
             fail("Expected exception due to invalid retryIntervalMs");
         } catch (IllegalArgumentException e) {
         }
@@ -143,7 +162,7 @@
     @Test
     public void testBuilderRequiresNonEmptyRetryInterval() {
         try {
-            newBuilder().setRetryIntervalsMs(new long[0]);
+            newBuilder().setRetryIntervalsMillis(new long[0]);
             fail("Expected exception due to invalid retryIntervalMs");
         } catch (IllegalArgumentException e) {
         }
@@ -174,7 +193,7 @@
 
         assertEquals(TUNNEL_CONNECTION_PARAMS, config.getTunnelConnectionParams());
 
-        assertArrayEquals(RETRY_INTERVALS_MS, config.getRetryIntervalsMs());
+        assertArrayEquals(RETRY_INTERVALS_MS, config.getRetryIntervalsMillis());
         assertEquals(MAX_MTU, config.getMaxMtu());
     }
 
diff --git a/tests/vcn/java/android/net/vcn/VcnTransportInfoTest.java b/tests/vcn/java/android/net/vcn/VcnTransportInfoTest.java
index 3156190..582275d 100644
--- a/tests/vcn/java/android/net/vcn/VcnTransportInfoTest.java
+++ b/tests/vcn/java/android/net/vcn/VcnTransportInfoTest.java
@@ -16,6 +16,8 @@
 
 package android.net.vcn;
 
+import static android.net.NetworkCapabilities.REDACT_ALL;
+import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS;
 import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
 
 import static org.junit.Assert.assertEquals;
@@ -37,6 +39,12 @@
     private static final VcnTransportInfo WIFI_UNDERLYING_INFO = new VcnTransportInfo(WIFI_INFO);
 
     @Test
+    public void testRedactionDefaults() {
+        assertEquals(REDACT_ALL, CELL_UNDERLYING_INFO.getRedaction());
+        assertEquals(REDACT_ALL, WIFI_UNDERLYING_INFO.getRedaction());
+    }
+
+    @Test
     public void testGetWifiInfo() {
         assertEquals(WIFI_INFO, WIFI_UNDERLYING_INFO.getWifiInfo());
 
@@ -51,6 +59,18 @@
     }
 
     @Test
+    public void testMakeCopySetsRedactions() {
+        assertEquals(
+                REDACT_FOR_NETWORK_SETTINGS,
+                ((VcnTransportInfo) CELL_UNDERLYING_INFO.makeCopy(REDACT_FOR_NETWORK_SETTINGS))
+                        .getRedaction());
+        assertEquals(
+                REDACT_FOR_NETWORK_SETTINGS,
+                ((VcnTransportInfo) WIFI_UNDERLYING_INFO.makeCopy(REDACT_FOR_NETWORK_SETTINGS))
+                        .getRedaction());
+    }
+
+    @Test
     public void testEquals() {
         assertEquals(CELL_UNDERLYING_INFO, CELL_UNDERLYING_INFO);
         assertEquals(WIFI_UNDERLYING_INFO, WIFI_UNDERLYING_INFO);
@@ -64,8 +84,29 @@
     }
 
     private void verifyParcelingIsNull(VcnTransportInfo vcnTransportInfo) {
+        // Verify redacted by default
         Parcel parcel = Parcel.obtain();
         vcnTransportInfo.writeToParcel(parcel, 0 /* flags */);
+        parcel.setDataPosition(0);
+
         assertNull(VcnTransportInfo.CREATOR.createFromParcel(parcel));
     }
+
+    @Test
+    public void testParcelUnparcelNotRedactedForSysUi() {
+        verifyParcelingForSysUi(CELL_UNDERLYING_INFO);
+        verifyParcelingForSysUi(WIFI_UNDERLYING_INFO);
+    }
+
+    private void verifyParcelingForSysUi(VcnTransportInfo vcnTransportInfo) {
+        // Allow fully unredacted; SysUI will have all the relevant permissions.
+        final VcnTransportInfo unRedacted = (VcnTransportInfo) vcnTransportInfo.makeCopy(0);
+        final Parcel parcel = Parcel.obtain();
+        unRedacted.writeToParcel(parcel, 0 /* flags */);
+        parcel.setDataPosition(0);
+
+        final VcnTransportInfo unparceled = VcnTransportInfo.CREATOR.createFromParcel(parcel);
+        assertEquals(vcnTransportInfo, unparceled);
+        assertEquals(REDACT_ALL, unparceled.getRedaction());
+    }
 }
diff --git a/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtilsTest.java b/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtilsTest.java
index 393787f..f385113 100644
--- a/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtilsTest.java
+++ b/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtilsTest.java
@@ -52,8 +52,8 @@
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class IkeSessionParamsUtilsTest {
-    // Package private for use in EncryptedTunnelParamsUtilsTest
-    static IkeSessionParams.Builder createBuilderMinimum() {
+    // Public for use in VcnGatewayConnectionConfigTest, EncryptedTunnelParamsUtilsTest
+    public static IkeSessionParams.Builder createBuilderMinimum() {
         final InetAddress serverAddress = InetAddresses.parseNumericAddress("192.0.2.100");
 
         // TODO: b/185941731 Make sure all valid IKE_OPTIONS are added and validated.
@@ -63,6 +63,7 @@
                 .setLocalIdentification(new IkeFqdnIdentification("client.test.android.net"))
                 .setRemoteIdentification(new IkeFqdnIdentification("server.test.android.net"))
                 .addIkeOption(IkeSessionParams.IKE_OPTION_FORCE_PORT_4500)
+                .addIkeOption(IkeSessionParams.IKE_OPTION_MOBIKE)
                 .setAuthPsk("psk".getBytes());
     }
 
diff --git a/tests/vcn/java/android/net/vcn/persistablebundleutils/TunnelConnectionParamsUtilsTest.java b/tests/vcn/java/android/net/vcn/persistablebundleutils/TunnelConnectionParamsUtilsTest.java
index 0c8ad32..f9dc9eb 100644
--- a/tests/vcn/java/android/net/vcn/persistablebundleutils/TunnelConnectionParamsUtilsTest.java
+++ b/tests/vcn/java/android/net/vcn/persistablebundleutils/TunnelConnectionParamsUtilsTest.java
@@ -18,6 +18,7 @@
 
 import static org.junit.Assert.assertEquals;
 
+import android.net.ipsec.ike.IkeSessionParams;
 import android.net.ipsec.ike.IkeTunnelConnectionParams;
 
 import androidx.test.filters.SmallTest;
@@ -31,9 +32,13 @@
 public class TunnelConnectionParamsUtilsTest {
     // Public for use in VcnGatewayConnectionConfigTest
     public static IkeTunnelConnectionParams buildTestParams() {
+        return buildTestParams(IkeSessionParamsUtilsTest.createBuilderMinimum().build());
+    }
+
+    // Public for use in VcnGatewayConnectionConfigTest
+    public static IkeTunnelConnectionParams buildTestParams(IkeSessionParams params) {
         return new IkeTunnelConnectionParams(
-                IkeSessionParamsUtilsTest.createBuilderMinimum().build(),
-                TunnelModeChildSessionParamsUtilsTest.createBuilderMinimum().build());
+                params, TunnelModeChildSessionParamsUtilsTest.createBuilderMinimum().build());
     }
 
     @Test
diff --git a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
index aa4b5f8..3360d40 100644
--- a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
+++ b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
@@ -37,6 +37,7 @@
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.CALLS_REAL_METHODS;
@@ -66,6 +67,7 @@
 import android.net.vcn.IVcnUnderlyingNetworkPolicyListener;
 import android.net.vcn.VcnConfig;
 import android.net.vcn.VcnConfigTest;
+import android.net.vcn.VcnGatewayConnectionConfigTest;
 import android.net.vcn.VcnManager;
 import android.net.vcn.VcnUnderlyingNetworkPolicy;
 import android.os.IBinder;
@@ -77,6 +79,7 @@
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
+import android.util.ArraySet;
 
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
@@ -98,6 +101,7 @@
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
 import java.util.Set;
 import java.util.UUID;
 
@@ -195,7 +199,8 @@
                 .newVcnContext(
                         eq(mMockContext),
                         eq(mTestLooper.getLooper()),
-                        any(VcnNetworkProvider.class));
+                        any(VcnNetworkProvider.class),
+                        anyBoolean());
         doReturn(mSubscriptionTracker)
                 .when(mMockDeps)
                 .newTelephonySubscriptionTracker(
@@ -326,6 +331,17 @@
             return subIdToGroupMap.get(invocation.getArgument(0));
         }).when(snapshot).getGroupForSubId(anyInt());
 
+        doAnswer(invocation -> {
+            final ParcelUuid subGrp = invocation.getArgument(0);
+            final Set<Integer> subIds = new ArraySet<>();
+            for (Entry<Integer, ParcelUuid> entry : subIdToGroupMap.entrySet()) {
+                if (entry.getValue().equals(subGrp)) {
+                    subIds.add(entry.getKey());
+                }
+            }
+            return subIds;
+        }).when(snapshot).getAllSubIdsInGroup(any());
+
         final TelephonySubscriptionTrackerCallback cb = getTelephonySubscriptionTrackerCallback();
         cb.onNewSnapshot(snapshot);
 
@@ -358,6 +374,12 @@
         TelephonySubscriptionSnapshot snapshot =
                 triggerSubscriptionTrackerCbAndGetSnapshot(Collections.singleton(TEST_UUID_1));
         verify(mMockDeps)
+                .newVcnContext(
+                        eq(mMockContext),
+                        eq(mTestLooper.getLooper()),
+                        any(VcnNetworkProvider.class),
+                        anyBoolean());
+        verify(mMockDeps)
                 .newVcn(eq(mVcnContext), eq(TEST_UUID_1), eq(TEST_VCN_CONFIG), eq(snapshot), any());
     }
 
@@ -515,6 +537,28 @@
     }
 
     @Test
+    public void testSetVcnConfigTestModeRequiresPermission() throws Exception {
+        doThrow(new SecurityException("Requires MANAGE_TEST_NETWORKS"))
+                .when(mMockContext)
+                .enforceCallingPermission(
+                        eq(android.Manifest.permission.MANAGE_TEST_NETWORKS), any());
+
+        final VcnConfig vcnConfig =
+                new VcnConfig.Builder(mMockContext)
+                        .addGatewayConnectionConfig(
+                                VcnGatewayConnectionConfigTest.buildTestConfig())
+                        .setIsTestModeProfile()
+                        .build();
+
+        try {
+            mVcnMgmtSvc.setVcnConfig(TEST_UUID_2, vcnConfig, TEST_PACKAGE_NAME);
+            fail("Expected exception due to using test-mode without permission");
+        } catch (SecurityException e) {
+            verify(mMockPolicyListener, never()).onPolicyChanged();
+        }
+    }
+
+    @Test
     public void testSetVcnConfigNotifiesStatusCallback() throws Exception {
         triggerSubscriptionTrackerCbAndGetSnapshot(Collections.singleton(TEST_UUID_2));
 
@@ -914,6 +958,18 @@
         verify(mMockPolicyListener).onPolicyChanged();
     }
 
+    @Test
+    public void testVcnSubIdChangeUpdatesPolicyListener() throws Exception {
+        startAndGetVcnInstance(TEST_UUID_2);
+        mVcnMgmtSvc.addVcnUnderlyingNetworkPolicyListener(mMockPolicyListener);
+
+        triggerSubscriptionTrackerCbAndGetSnapshot(
+                Collections.singleton(TEST_UUID_2),
+                Collections.singletonMap(TEST_SUBSCRIPTION_ID, TEST_UUID_2));
+
+        verify(mMockPolicyListener).onPolicyChanged();
+    }
+
     private void triggerVcnSafeMode(
             @NonNull ParcelUuid subGroup,
             @NonNull TelephonySubscriptionSnapshot snapshot,
diff --git a/tests/vcn/java/com/android/server/vcn/UnderlyingNetworkTrackerTest.java b/tests/vcn/java/com/android/server/vcn/UnderlyingNetworkTrackerTest.java
index 8289e85..0b72cd9 100644
--- a/tests/vcn/java/com/android/server/vcn/UnderlyingNetworkTrackerTest.java
+++ b/tests/vcn/java/com/android/server/vcn/UnderlyingNetworkTrackerTest.java
@@ -26,6 +26,7 @@
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -112,8 +113,14 @@
         MockitoAnnotations.initMocks(this);
 
         mTestLooper = new TestLooper();
-        mVcnContext = spy(new VcnContext(mContext, mTestLooper.getLooper(), mVcnNetworkProvider));
-        doNothing().when(mVcnContext).ensureRunningOnLooperThread();
+        mVcnContext =
+                spy(
+                        new VcnContext(
+                                mContext,
+                                mTestLooper.getLooper(),
+                                mVcnNetworkProvider,
+                                false /* isInTestMode */));
+        resetVcnContext();
 
         setupSystemService(
                 mContext,
@@ -132,6 +139,11 @@
                         mNetworkTrackerCb);
     }
 
+    private void resetVcnContext() {
+        reset(mVcnContext);
+        doNothing().when(mVcnContext).ensureRunningOnLooperThread();
+    }
+
     private static LinkProperties getLinkPropertiesWithName(String iface) {
         LinkProperties linkProperties = new LinkProperties();
         linkProperties.setInterfaceName(iface);
@@ -149,6 +161,31 @@
         verifyNetworkRequestsRegistered(INITIAL_SUB_IDS);
     }
 
+    @Test
+    public void testNetworkCallbacksRegisteredOnStartupForTestMode() {
+        final VcnContext vcnContext =
+                spy(
+                        new VcnContext(
+                                mContext,
+                                mTestLooper.getLooper(),
+                                mVcnNetworkProvider,
+                                true /* isInTestMode */));
+
+        mUnderlyingNetworkTracker =
+                new UnderlyingNetworkTracker(
+                        vcnContext,
+                        SUB_GROUP,
+                        mSubscriptionSnapshot,
+                        Collections.singleton(NetworkCapabilities.NET_CAPABILITY_INTERNET),
+                        mNetworkTrackerCb);
+
+        verify(mConnectivityManager)
+                .requestBackgroundNetwork(
+                        eq(getTestNetworkRequest(INITIAL_SUB_IDS)),
+                        any(RouteSelectionCallback.class),
+                        any());
+    }
+
     private void verifyNetworkRequestsRegistered(Set<Integer> expectedSubIds) {
         verify(mConnectivityManager)
                 .requestBackgroundNetwork(
@@ -165,7 +202,8 @@
         verify(mConnectivityManager)
                 .requestBackgroundNetwork(
                         eq(getRouteSelectionRequest(expectedSubIds)),
-                        any(RouteSelectionCallback.class), any());
+                        any(RouteSelectionCallback.class),
+                        any());
     }
 
     @Test
@@ -204,6 +242,14 @@
         return getExpectedRequestBase().setSubscriptionIds(netCapsSubIds).build();
     }
 
+    private NetworkRequest getTestNetworkRequest(Set<Integer> netCapsSubIds) {
+        return new NetworkRequest.Builder()
+                .clearCapabilities()
+                .addTransportType(NetworkCapabilities.TRANSPORT_TEST)
+                .setSubscriptionIds(netCapsSubIds)
+                .build();
+    }
+
     private NetworkRequest.Builder getExpectedRequestBase() {
         final NetworkRequest.Builder builder =
                 new NetworkRequest.Builder()
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
index 530e636..39f7386 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
@@ -16,8 +16,11 @@
 
 package com.android.server.vcn;
 
+import static android.net.IpSecManager.DIRECTION_FWD;
 import static android.net.IpSecManager.DIRECTION_IN;
 import static android.net.IpSecManager.DIRECTION_OUT;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
 import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
 import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_AUTHENTICATION_FAILED;
@@ -51,10 +54,11 @@
 import android.net.NetworkAgent;
 import android.net.NetworkCapabilities;
 import android.net.ipsec.ike.ChildSaProposal;
-import android.net.ipsec.ike.IkeTunnelConnectionParams;
 import android.net.ipsec.ike.exceptions.IkeException;
 import android.net.ipsec.ike.exceptions.IkeInternalException;
 import android.net.ipsec.ike.exceptions.IkeProtocolException;
+import android.net.vcn.VcnGatewayConnectionConfig;
+import android.net.vcn.VcnGatewayConnectionConfigTest;
 import android.net.vcn.VcnManager.VcnErrorCode;
 
 import androidx.test.filters.SmallTest;
@@ -144,8 +148,9 @@
         assertEquals(mGatewayConnection.mConnectedState, mGatewayConnection.getCurrentState());
     }
 
-    @Test
-    public void testCreatedTransformsAreApplied() throws Exception {
+    private void verifyVcnTransformsApplied(
+            VcnGatewayConnection vcnGatewayConnection, boolean expectForwardTransform)
+            throws Exception {
         for (int direction : new int[] {DIRECTION_IN, DIRECTION_OUT}) {
             getChildSessionCallback().onIpSecTransformCreated(makeDummyIpSecTransform(), direction);
             mTestLooper.dispatchAll();
@@ -155,7 +160,40 @@
                             eq(TEST_IPSEC_TUNNEL_RESOURCE_ID), eq(direction), anyInt(), any());
         }
 
-        assertEquals(mGatewayConnection.mConnectedState, mGatewayConnection.getCurrentState());
+        verify(mIpSecSvc, expectForwardTransform ? times(1) : never())
+                .applyTunnelModeTransform(
+                        eq(TEST_IPSEC_TUNNEL_RESOURCE_ID), eq(DIRECTION_FWD), anyInt(), any());
+
+        assertEquals(vcnGatewayConnection.mConnectedState, vcnGatewayConnection.getCurrentState());
+    }
+
+    @Test
+    public void testCreatedTransformsAreApplied() throws Exception {
+        verifyVcnTransformsApplied(mGatewayConnection, false /* expectForwardTransform */);
+    }
+
+    @Test
+    public void testCreatedTransformsAreAppliedWithDun() throws Exception {
+        VcnGatewayConnectionConfig gatewayConfig =
+                VcnGatewayConnectionConfigTest.buildTestConfigWithExposedCaps(
+                        NET_CAPABILITY_INTERNET, NET_CAPABILITY_DUN);
+        VcnGatewayConnection gatewayConnection =
+                new VcnGatewayConnection(
+                        mVcnContext,
+                        TEST_SUB_GRP,
+                        TEST_SUBSCRIPTION_SNAPSHOT,
+                        gatewayConfig,
+                        mGatewayStatusCallback,
+                        true /* isMobileDataEnabled */,
+                        mDeps);
+        gatewayConnection.setUnderlyingNetwork(TEST_UNDERLYING_NETWORK_RECORD_1);
+        final VcnIkeSession session =
+                gatewayConnection.buildIkeSession(TEST_UNDERLYING_NETWORK_RECORD_1.network);
+        gatewayConnection.setIkeSession(session);
+        gatewayConnection.transitionTo(gatewayConnection.mConnectedState);
+        mTestLooper.dispatchAll();
+
+        verifyVcnTransformsApplied(gatewayConnection, true /* expectForwardTransform */);
     }
 
     @Test
@@ -181,7 +219,7 @@
         assertEquals(mGatewayConnection.mConnectedState, mGatewayConnection.getCurrentState());
 
         final List<ChildSaProposal> saProposals =
-                ((IkeTunnelConnectionParams) mConfig.getTunnelConnectionParams())
+                mConfig.getTunnelConnectionParams()
                         .getTunnelModeChildSessionParams()
                         .getSaProposals();
         final int expectedMtu =
@@ -344,6 +382,31 @@
         assertFalse(mGatewayConnection.isInSafeMode());
     }
 
+    @Test
+    public void testSubsequentFailedValidationTriggersSafeMode() throws Exception {
+        triggerChildOpened();
+        mTestLooper.dispatchAll();
+
+        triggerValidation(NetworkAgent.VALIDATION_STATUS_VALID);
+        assertFalse(mGatewayConnection.isInSafeMode());
+
+        // Trigger a failed validation, and the subsequent safemode timeout.
+        triggerValidation(NetworkAgent.VALIDATION_STATUS_NOT_VALID);
+        mTestLooper.dispatchAll();
+
+        final ArgumentCaptor<Runnable> runnableCaptor = ArgumentCaptor.forClass(Runnable.class);
+        verify(mDeps, times(2))
+                .newWakeupMessage(
+                        eq(mVcnContext),
+                        any(),
+                        eq(VcnGatewayConnection.SAFEMODE_TIMEOUT_ALARM),
+                        runnableCaptor.capture());
+        runnableCaptor.getValue().run();
+        mTestLooper.dispatchAll();
+
+        assertTrue(mGatewayConnection.isInSafeMode());
+    }
+
     private Consumer<VcnNetworkAgent> setupNetworkAndGetUnwantedCallback() {
         triggerChildOpened();
         mTestLooper.dispatchAll();
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionRetryTimeoutStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionRetryTimeoutStateTest.java
index 044bef5..a88f112 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionRetryTimeoutStateTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionRetryTimeoutStateTest.java
@@ -38,7 +38,7 @@
     public void setUp() throws Exception {
         super.setUp();
 
-        mFirstRetryInterval = mConfig.getRetryIntervalsMs()[0];
+        mFirstRetryInterval = mConfig.getRetryIntervalsMillis()[0];
 
         mGatewayConnection.setUnderlyingNetwork(TEST_UNDERLYING_NETWORK_RECORD_1);
         mGatewayConnection.transitionTo(mGatewayConnection.mRetryTimeoutState);
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTestBase.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTestBase.java
index 284f1f8..1ecb4c9 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTestBase.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTestBase.java
@@ -220,7 +220,7 @@
     protected VcnChildSessionCallback getChildSessionCallback() {
         ArgumentCaptor<ChildSessionCallback> captor =
                 ArgumentCaptor.forClass(ChildSessionCallback.class);
-        verify(mDeps).newIkeSession(any(), any(), any(), any(), captor.capture());
+        verify(mDeps, atLeastOnce()).newIkeSession(any(), any(), any(), any(), captor.capture());
         return (VcnChildSessionCallback) captor.getValue();
     }
 
diff --git a/tests/vcn/java/com/android/server/vcn/VcnTest.java b/tests/vcn/java/com/android/server/vcn/VcnTest.java
index 736fabd..f681ee1 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnTest.java
@@ -388,8 +388,9 @@
         final ContentObserver contentObserver = captor.getValue();
 
         // Start VcnGatewayConnections
+        final NetworkRequestListener requestListener = verifyAndGetRequestListener();
         mVcn.setMobileDataEnabled(startingToggleState);
-        triggerVcnRequestListeners(verifyAndGetRequestListener());
+        triggerVcnRequestListeners(requestListener);
         final Map<VcnGatewayConnectionConfig, VcnGatewayConnection> gateways =
                 mVcn.getVcnGatewayConnectionConfigMap();
 
@@ -411,6 +412,9 @@
             }
         }
 
+        if (startingToggleState != endingToggleState) {
+            verify(mVcnNetworkProvider).resendAllRequests(requestListener);
+        }
         assertEquals(endingToggleState, mVcn.isMobileDataEnabled());
     }