Merge changes Ib3c9affb,I1dbe3d02,I88681f21

* changes:
  Keystore 2.0 SPI: Adding the keystore AIDL interface to frameworks
  Keystore 2.0: KeyProperties SignaturePadding is now public but hidden
  Keystore SPI: Add SecurityLevelEnum to KeyProperties
diff --git a/Android.bp b/Android.bp
index 8dc2655..8c8b29b 100644
--- a/Android.bp
+++ b/Android.bp
@@ -555,6 +555,7 @@
         "framework-platform-compat-config",
         // TODO: remove gps_debug and protolog.conf.json when the build system propagates "required" properly.
         "gps_debug.conf",
+        "icu4j-platform-compat-config",
         "libcore-platform-compat-config",
         "protolog.conf.json.gz",
         "services-platform-compat-config",
diff --git a/StubLibraries.bp b/StubLibraries.bp
index 9047df5..7060347 100644
--- a/StubLibraries.bp
+++ b/StubLibraries.bp
@@ -225,7 +225,7 @@
 }
 
 droidstubs {
-    name: "test-api-stubs-docs",
+    name: "test-api-stubs-docs-non-updatable",
     defaults: ["metalava-non-updatable-api-stubs-default"],
     arg_files: [
         "core/res/AndroidManifest.xml",
@@ -237,12 +237,12 @@
         + "\\)",
     check_api: {
         current: {
-            api_file: "api/test-current.txt",
-            removed_api_file: "api/test-removed.txt",
+            api_file: "core/api/test-current.txt",
+            removed_api_file: "core/api/test-removed.txt",
         },
         api_lint: {
             enabled: true,
-            baseline_file: "api/test-lint-baseline.txt",
+            baseline_file: "core/api/test-lint-baseline.txt",
         },
     },
     dist: {
@@ -312,14 +312,7 @@
 }
 
 java_library_static {
-    name: "android_monolith_stubs_current",
-    srcs: [ ":api-stubs-docs" ],
-    static_libs: [ "private-stub-annotations-jar" ],
-    defaults: ["android_defaults_stubs_current"],
-}
-
-java_library_static {
-    name: "android_merged_stubs_current",
+    name: "android_stubs_current",
     srcs: [ ":api-stubs-docs-non-updatable" ],
     static_libs: [
         "conscrypt.module.public.api.stubs",
@@ -332,19 +325,6 @@
         "framework-wifi.stubs",
         "private-stub-annotations-jar",
     ],
-    defaults: ["android_defaults_stubs_current"],
-}
-
-java_library_static {
-    name: "android_stubs_current",
-    static_libs: ["android_merged_stubs_current"],
-    defaults: ["android_defaults_stubs_current"],
-}
-
-java_library_static {
-    name: "android_system_monolith_stubs_current",
-    srcs: [ ":system-api-stubs-docs" ],
-    static_libs: [ "private-stub-annotations-jar" ],
     defaults: [
         "android_defaults_stubs_current",
         "android_stubs_dists_default",
@@ -363,7 +343,7 @@
 }
 
 java_library_static {
-    name: "android_system_merged_stubs_current",
+    name: "android_system_stubs_current",
     srcs: [ ":system-api-stubs-docs-non-updatable" ],
     static_libs: [
         "conscrypt.module.public.api.stubs",
@@ -380,14 +360,8 @@
 }
 
 java_library_static {
-    name: "android_system_stubs_current",
-    static_libs: ["android_system_merged_stubs_current"],
-    defaults: ["android_defaults_stubs_current"],
-}
-
-java_library_static {
     name: "android_test_stubs_current",
-    srcs: [ ":test-api-stubs-docs" ],
+    srcs: [ ":test-api-stubs-docs-non-updatable" ],
     static_libs: [
         // Modules do not have test APIs, but we want to include their SystemApis, like we include
         // the SystemApi of framework-non-updatable-sources.
diff --git a/apex/Android.bp b/apex/Android.bp
index cabed3b..0a535a8 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -112,6 +112,8 @@
     ],
     stubs_source_visibility: ["//visibility:private"],
 
+    defaults_visibility: ["//visibility:private"],
+
     // Collates API usages from each module for further analysis.
     plugins: ["java_api_finder"],
 
@@ -147,141 +149,6 @@
 }
 
 stubs_defaults {
-    name: "framework-module-stubs-defaults-publicapi",
-    args: mainline_framework_stubs_args,
-    installable: false,
-    sdk_version: "module_current",
-    annotations_enabled: true,
-    merge_annotations_dirs: [
-        "metalava-manual",
-    ],
-    filter_packages: framework_packages_to_document,
-    check_api: {
-        current: {
-            api_file: "api/current.txt",
-            removed_api_file: "api/removed.txt",
-        },
-        api_lint: {
-            enabled: true,
-        },
-    },
-    dist: {
-        targets: ["sdk", "win_sdk"],
-        dir: "apistubs/android/public/api",
-    },
-}
-
-stubs_defaults {
-    name: "framework-module-stubs-defaults-systemapi",
-    args: mainline_framework_stubs_args + priv_apps,
-    libs: ["framework-annotations-lib"],
-    installable: false,
-    sdk_version: "module_current",
-    annotations_enabled: true,
-    merge_annotations_dirs: [
-        "metalava-manual",
-    ],
-    filter_packages: framework_packages_to_document,
-    check_api: {
-        current: {
-            api_file: "api/system-current.txt",
-            removed_api_file: "api/system-removed.txt",
-        },
-        api_lint: {
-            enabled: true,
-        },
-    },
-    dist: {
-        targets: ["sdk", "win_sdk"],
-        dir: "apistubs/android/system/api",
-    },
-}
-
-java_defaults {
-    name: "framework-module-stubs-lib-defaults-publicapi",
-    installable: false,
-    sdk_version: "module_current",
-    libs: [ "stub-annotations" ],
-    java_version: "1.8",
-    dist: {
-        targets: ["sdk", "win_sdk"],
-        dir: "apistubs/android/public",
-    },
-}
-
-java_defaults {
-    name: "framework-module-stubs-lib-defaults-systemapi",
-    installable: false,
-    sdk_version: "module_current",
-    libs: [ "stub-annotations" ],
-    java_version: "1.8",
-    dist: {
-        targets: ["sdk", "win_sdk"],
-        dir: "apistubs/android/system",
-    },
-}
-
-java_defaults {
-    name: "framework-module-stubs-lib-defaults-module_libs_api",
-    installable: false,
-    sdk_version: "module_current",
-    libs: [ "stub-annotations" ],
-    java_version: "1.8",
-    dist: {
-        targets: ["sdk", "win_sdk"],
-        dir: "apistubs/android/module-lib",
-    },
-}
-
-// The defaults for module_libs comes in two parts - defaults for API checks
-// and defaults for stub generation. This is because we want the API txt
-// files to *only* include the module_libs_api, but the stubs to include
-// module_libs_api as well as priv_apps.
-
-stubs_defaults {
-    name: "framework-module-api-defaults-module_libs_api",
-    args: mainline_framework_stubs_args + module_libs,
-    libs: ["framework-annotations-lib"],
-    installable: false,
-    sdk_version: "module_current",
-    annotations_enabled: true,
-    merge_annotations_dirs: [
-        "metalava-manual",
-    ],
-    filter_packages: framework_packages_to_document,
-
-    // Do not generate stubs as they are not needed
-    generate_stubs: false,
-
-    check_api: {
-        current: {
-            api_file: "api/module-lib-current.txt",
-            removed_api_file: "api/module-lib-removed.txt",
-        },
-        api_lint: {
-            enabled: true,
-        },
-    },
-    dist: {
-        targets: ["sdk", "win_sdk"],
-        dir: "apistubs/android/module-lib/api",
-    },
-}
-
-stubs_defaults {
-    name: "framework-module-stubs-defaults-module_libs_api",
-    args: mainline_framework_stubs_args + module_libs + priv_apps,
-    libs: ["framework-annotations-lib"],
-    installable: false,
-    sdk_version: "module_current",
-    annotations_enabled: true,
-    merge_annotations_dirs: [
-        "metalava-manual",
-    ],
-    filter_packages: framework_packages_to_document,
-}
-
-stubs_defaults {
     name: "service-module-stubs-srcs-defaults",
     args: mainline_service_stubs_args,
     installable: false,
diff --git a/apex/extservices/Android.bp b/apex/extservices/Android.bp
deleted file mode 100644
index 0c6c4c2..0000000
--- a/apex/extservices/Android.bp
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (C) 2020 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.
-
-apex {
-    name: "com.android.extservices",
-    defaults: ["com.android.extservices-defaults"],
-    manifest: "apex_manifest.json",
-}
-
-apex_defaults {
-    name: "com.android.extservices-defaults",
-    updatable: true,
-    min_sdk_version: "current",
-    key: "com.android.extservices.key",
-    certificate: ":com.android.extservices.certificate",
-    apps: ["ExtServices"],
-}
-
-apex_key {
-    name: "com.android.extservices.key",
-    public_key: "com.android.extservices.avbpubkey",
-    private_key: "com.android.extservices.pem",
-}
-
-android_app_certificate {
-    name: "com.android.extservices.certificate",
-    certificate: "com.android.extservices",
-}
diff --git a/apex/extservices/apex_manifest.json b/apex/extservices/apex_manifest.json
deleted file mode 100644
index c0b59cc..0000000
--- a/apex/extservices/apex_manifest.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
-  "name": "com.android.extservices",
-  "version": 300900700
-}
diff --git a/apex/extservices/com.android.extservices.avbpubkey b/apex/extservices/com.android.extservices.avbpubkey
deleted file mode 100644
index f37d3e4..0000000
--- a/apex/extservices/com.android.extservices.avbpubkey
+++ /dev/null
Binary files differ
diff --git a/apex/extservices/com.android.extservices.pem b/apex/extservices/com.android.extservices.pem
deleted file mode 100644
index 7bfbd34..0000000
--- a/apex/extservices/com.android.extservices.pem
+++ /dev/null
@@ -1,51 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIJKAIBAAKCAgEAuYshVDiRkt3tmBhqcWkKOm5GcviKpLbHSPpYQDHGDwS0dqqL
-SqAd1/BgT/bVVtUkAciFApPnXn96WhNYCypptyC5FHCxM21uBCGmow+3WermD++w
-5dQk4QP2ONPIpG+KzOWBl9SiBud4SpOHDyr0JycBsrXS89Tln9kAsTDuDEFfXL/J
-8cX/S3IUwhPV0pAlgUIHdDp0DGFjZaJlEZBZ+HmImriC/AUNUMVb5lfbczXOEZPF
-0A9+JzYschfXUxn8nu1N7RN5GDbq+chszx1FMVhuFUheukkd4dLNSDl0O0RlUnD+
-C/xz1ilDzEVZhnMtMnxS9oJ8bA/HUVMfsFnaQbgGmQ0CcxFxnfbYyGXGG1H+b8vA
-MTVQi5rZXG2p+VgHIAKVrYmpETVnRPgoMqp18KuGtp5SDngi13G3YEzS7iFbqfYh
-6iW2G974nD/Dq0cSire8Oljd9PEaMCMZiP5PTFJp0G/mtw7ROoyZqsSM6rX3XVTo
-Y5dBmBMctSJ8rgDMi0ZNvRH+rq/E5+RT6yMAJ7DDbOJzBnQ3IIoGn8NzUT3P1FCB
-HYEp1U2N7QNirIQMAuVz3IlHae9N1kl3eGAO6f2CjV7vZmFpDeWw+KSYs71mRkOb
-WBgl6D9FFq4u1azrU3AwV0dj3x1eU6yVnKUy1J7ppF/mcR+VzH7ThzTdV7cCAwEA
-AQKCAgEApWFU2Mv/PYhg0bPZlLLKsiA+3RWaBo0AfpTd+oIjBpnr/OWweFjVoPcZ
-8cyShe4/RPOlUxHgJcO8m/MoA/PO/LLHJWf5GlzMthQEgs1sYVJVtBiydXitUn+E
-hUyIR8FAV7et1lZqAXtqJhbvSF7B9u/2vIMCv+GgtuTmkAmL9RKD3Jj6eG1CS84o
-oICrkx52v4rKOBgt/icEQMAKFCi1eRti3n3eCqK6JqdzbZIcAcoQnmw34mccy/im
-jx+fBuxf1oywa8NyqVmyAehazBVL6lrm7ENwY9zuLK4H2fuUFYu2QFCEsMxZt6da
-TgX2cTfSLnDQRfcyzeMWhu9vjHHabjpLNjiCKhIhGyO0rO1rtea8ajZHgM/2sxXq
-6gLynW0dlatlxmjANlN9WQPGNdzvcIFJ0TLnI4mlJnWpqCsN9iW1d4ey13WiZUVR
-DgtnR60zao+LRCCM4D3cuVLq0DjL2BlHGXnOPK/LpQG1LbI1TroZpgSEHSZlQRzT
-ql9txgNqTHxijXuPL2VhhwhW7cqDoO8sLwV3BqDMIH56U0cbUBiSA/G9fKeI/DEG
-i7LcrMgrBk+xnuAWoFHuzfBMAdD9i3kYyk+41tOmcza2TNJgxadVYp5woHFvYvS/
-GKaNiRz0XmcijO5Ir0yxgCq21BdkWzo5zVrTFABiKeR7YXiee8kCggEBAOeULWgR
-spolJJrACWJspRvKb9FGnbGiYOnCGJoAc751kuXmNxoyWnEwgcjrSEoayNPUfOtz
-IgA+twqjgl0Zec2XFPfUcgWUBrrvvUEV4NIH5ibaR7ezHGeovCWs9XoDyzHHvhDr
-c6T5kXFZ60rS5h6LGUnE1hkHFJoHuTIBbn9j7eIbri8S71i7HWQ04s4KuQ+Bwbxm
-UnkEhbc+zMWHXfXy7rx4/eEZcZwtEybIORcHXYNPGeqMfOlcEMHpKEOi+NvDA6cp
-vTaTSwJ6ZBgYh7Tw3bNgRxSknaIhcGwMD0ojStjC5xzXT1Zr2Z3GXwYvOGcq3MeZ
-z+V2cx5xuwyp7R0CggEBAM0cKKNZEZwi/1zBPUDMFB4iJoX12BxQX6e5wdlHGXgF
-XeZwCnaIxOxMDxH79M5Svmpdu/jkUijI/pRvcE1iohFyIBvTUSDmlAoy4keXqMEQ
-M2hA+TwVA3JLmMcV8HKy/MFlwwKJB1JDcoxGjnXsM5UjVTD2jilO7vlJZs3+0ws0
-R7qzRT3ED25QTpZyDYcKE2otc5bzIZG3yAaJtWd3NugWsKpxDgr2RFUGJiHBq72n
-48FkSjfgaDTn83zYcPvS0Uykb2ho8G/N+EurstL41n3nQo0I7FLbyptOopDDwsSp
-Ndejn08NVAQ+xFAafOyqHkA3Ytpl0QCZDpMBuLdvw+MCggEAOVMt1kgjPRMat4/4
-ArxANtvqyBRB7vnyIYthiaW5ARmbrntJgpuaVdCbIABWGbn9oqpD7gjHDuZ3axPE
-roUi6KiQkTSusQDOlbHI2Haw+2znJRD9ldSpoGNdh7oD3htYTk9Sll+ideEthrCq
-lRAV1NO8A83M7c8Z43Mr/dvq3XAAL+uIN7DpPL687NRGnJh87QDC039ExR5Ad3b9
-O5xhvwNO46rTtcgVnoJt7ji8IR46oMmQ8cWrGh0nLMkppWyPS98/ZT7ozryxYcCo
-TGquFTVWvBOGJO8G8l5ytNxbYI/R9Exy52nJAuyZpvu3BBHmVWt/0Y0asIOcxZmD
-owPhZQKCAQAfWAFBzReq05JQe1s/7q/YVwGqEQKgeQvVFsbvzDSxKajK0S5YJNhq
-/8iByA4GBZEBsidKhqGjh+uXhVwVB1Ca9+S+O9G3BGV1FYeMxzlLn40rjlpH+zIW
-okTLj6e5724+o61kUspioNn9Y77beGf9j3OyUsswttZAFB54tktL+AZKGqEnKjHt
-eqo3xWAZ1clXvXBfjfIAUaRok1y8XfRvDSCcO0CZHj8c+x6SpAT5q5FbeVb6KPnj
-s9p6ppzFbtb7Llm0C+1KOKCL98YRBWPJw7Bg2w86LkpM53xiQPgfk3gd5uwuaWwA
-ZhMb5qBWjjynNY+OrmZ8/+bBQk8XASZfAoIBAFkHOnZOD1JJQ0QvaJ9tuCgHi216
-I8QPMMTdm3ZEDHSYMNwl7ayeseBcmB2zaqBKYz75qcU0SK4lnZkR2wIpbsHZNSVM
-J0WpN6r9G4JdnVi11J04RsfSMjCUr/PTVMmPvw8xPHrCxkJmB+d56olSE80I1Jrx
-djCv1LtSsT10W7FIcY82/cOi4xxGLOA70lDCf+szofQgVP8WvuOA1YaFw98ca8zc
-A401CyNexk24/c3d6C19YW/MppdE0uGMxL/oHsPgwkZAf6LmvF/UF71PsBUEniLc
-YFaJl3wn1cPfBBo9L4sZzyP2qokL8YHdg+wW7b4IOsYwbeqceBvqPtcUUPs=
------END RSA PRIVATE KEY-----
diff --git a/apex/extservices/com.android.extservices.pk8 b/apex/extservices/com.android.extservices.pk8
deleted file mode 100644
index 59585a2..0000000
--- a/apex/extservices/com.android.extservices.pk8
+++ /dev/null
Binary files differ
diff --git a/apex/extservices/com.android.extservices.x509.pem b/apex/extservices/com.android.extservices.x509.pem
deleted file mode 100644
index e0343b8..0000000
--- a/apex/extservices/com.android.extservices.x509.pem
+++ /dev/null
@@ -1,36 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIGLTCCBBWgAwIBAgIUdqdMmx/5OsCP3Ew3/hcr7+1ACHEwDQYJKoZIhvcNAQEL
-BQAwgaQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQH
-DA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdBbmRyb2lkMRAwDgYDVQQLDAdBbmRy
-b2lkMSAwHgYDVQQDDBdjb20uYW5kcm9pZC5leHRzZXJ2aWNlczEiMCAGCSqGSIb3
-DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTAgFw0yMDAxMTcxMDIxMzZaGA80NzU3
-MTIxMzEwMjEzNlowgaQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlh
-MRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdBbmRyb2lkMRAwDgYD
-VQQLDAdBbmRyb2lkMSAwHgYDVQQDDBdjb20uYW5kcm9pZC5leHRzZXJ2aWNlczEi
-MCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTCCAiIwDQYJKoZIhvcN
-AQEBBQADggIPADCCAgoCggIBANKaSeLGaFRRt779vAtTfG3t2aQZrWOByUYc7yUN
-RdmJqWxU47OL5urYmanWPbz2f972Q9oi8x+8y4ny9SEY3wg0pUbzvKNTXpkxWyG1
-HE2C2zTfzuDDLpDIf2usWynt1wLVhpYC3k+7Yv2vOIK5dKkezh6PfdKmsbDae5DE
-d22tTSYZ5KwNpIWrgQle26cRG5sqhAFdkpgGMF00Huz06cjUoTjs2sNSlXTRBOTP
-CCy8UoRjBivQZkwHbddfsn+Z22ARPG8JDg/n4mEi8C0T6bJeQeirSPkBCkD6Djgq
-7RddJ2eLYZII8l8r6A6x+6cnTkXHaV5g3LUwPvi8XEn9IUuT9WJNRje/vfYLycTQ
-kP415CZMxDvsi1Ul4YsbL3enE89ryGMTpVZPogch/36DG5Sye28yISItNUy3urJa
-OXbg7mh+MwPd4bQaW4CJk+AUweKaF4aV0SZFT+nCewL4xLdGdy889KazlW98NqtK
-hOSxIg1jHkZq48ajuq2A+ns1yDKt1l0f9IYCz3mz/IXInokbkjPvHahJTJ+OMHXO
-THD8e5gBzcK841jJk+H3EsIYOHsp66uy2IgEHN+9pAS6vI0xfrXOYuKzuSL3oxcV
-FlVTimt4xokMMerdcW4KD+MC5NFEip4DUS4JKCyG0wRI3ffEs9Zcpxi3QSibrjLW
-rz+hAgMBAAGjUzBRMB0GA1UdDgQWBBTP2AhZzEUUgtAFlkaMaq+RvY06fDAfBgNV
-HSMEGDAWgBTP2AhZzEUUgtAFlkaMaq+RvY06fDAPBgNVHRMBAf8EBTADAQH/MA0G
-CSqGSIb3DQEBCwUAA4ICAQCbwtfo37j62Sudmt32PCfRN/r5ZNDNNA2JhR8uDUmX
-xXfF5YfDvSKsNLiQKcDagu6a+0C+QnzXHXCBlXZFrTJ8NAVMlmqdHGwoFoYMfJZH
-R1lCTidyFMoMLJ8GRGPJjzDkKnOeAqKMCtKvXoH2r12+JB2/ov4ooLREu/wPkEXT
-OymkyWNP5XLQTKWqfEQyXXFpuwZ+m35Wkr0Fm92mZeJpVeIZPK7M7aK3zyoj7XJP
-YLMsR/AQs8OULdpfNMddAuN3ndlYu03LZlsF6LG5bduaDDcESJ5hdJrgBa/NBKRU
-IbS+q/6WAjYKMNRT/fPGew4wUzlWKi1Ihdk79oaqKKijE1b2JSJD1/SEYiBf+JPE
-bXobUrMbBwFpdhT+YLMF9FsuPQKsUIONaWiO4QcQoY/rQwGxPP6fV8ZbBrUWJewj
-MpSdU9foZNa/TmOAgfS/JxH+nXnG4+H1m8mdNBsxvsYmF2ZuGb/jdEeA2cuHIJDZ
-FJeWwCFxzlCGZJaUsxsnZByADBuufUVaO/9gGs0YQC/JP1i9hK4DyZdKwZpXdLi2
-Nw27Qma4WEIZnMb6Rgk1nTV+7ALcOSIhGgFOOeDTuCGfnEcz2coai5fbD/K6Q7Xu
-IRNyxHQjheZPdei2x912Ex/KqKGfaFaZJxrvCSKdhzxcTFIsO4JuZs+SDpRTKcI7
-Cw==
------END CERTIFICATE-----
diff --git a/apex/extservices/testing/Android.bp b/apex/extservices/testing/Android.bp
deleted file mode 100644
index 88a4724..0000000
--- a/apex/extservices/testing/Android.bp
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright (C) 2020 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.
-
-apex_test {
-    name: "test_com.android.extservices",
-    visibility: [
-        "//system/apex/tests",
-    ],
-    defaults: ["com.android.extservices-defaults"],
-    manifest: "test_manifest.json",
-    file_contexts: ":com.android.extservices-file_contexts",
-    // Test APEX, should never be installed
-    installable: false,
-}
diff --git a/apex/extservices/testing/test_manifest.json b/apex/extservices/testing/test_manifest.json
deleted file mode 100644
index 23a50e3..0000000
--- a/apex/extservices/testing/test_manifest.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
-  "name": "com.android.extservices",
-  "version": 2147483647
-}
diff --git a/api/Android.bp b/api/Android.bp
index 9f99b78c..ae0d596 100644
--- a/api/Android.bp
+++ b/api/Android.bp
@@ -16,36 +16,17 @@
     default_visibility: ["//visibility:private"],
 }
 
-// *-current.txt files for use by modules in other directories like cts
-filegroup {
-    name: "frameworks-base-api-current.txt",
-    srcs: ["current.txt"],
-    visibility: ["//visibility:public"],
-}
-
-filegroup {
-    name: "frameworks-base-api-system-current.txt",
-    srcs: ["system-current.txt"],
-    visibility: ["//visibility:public"],
-}
-
-filegroup {
-    name: "frameworks-base-api-system-removed.txt",
-    srcs: ["system-removed.txt"],
-    visibility: ["//visibility:public"],
-}
-
 genrule {
     name: "current-api-xml",
     tools: ["metalava"],
-    srcs: ["current.txt"],
+    srcs: [":frameworks-base-api-current.txt"],
     out: ["current.api"],
     cmd: "$(location metalava) --no-banner -convert2xmlnostrip $(in) $(out)",
     visibility: ["//visibility:public"],
 }
 
 genrule {
-    name: "frameworks-base-api-current-merged.txt",
+    name: "frameworks-base-api-current.txt",
     srcs: [
         ":conscrypt.module.public.api{.public.api.txt}",
         ":framework-media{.public.api.txt}",
@@ -72,10 +53,11 @@
             dest: "android.txt",
         },
     ],
+    visibility: ["//visibility:public"],
 }
 
 genrule {
-    name: "frameworks-base-api-removed-merged.txt",
+    name: "frameworks-base-api-removed.txt",
     srcs: [
         ":conscrypt.module.public.api{.public.removed-api.txt}",
         ":framework-media{.public.removed-api.txt}",
@@ -100,7 +82,7 @@
 }
 
 genrule {
-    name: "frameworks-base-api-system-current-merged.txt",
+    name: "frameworks-base-api-system-current.txt",
     srcs: [
         ":framework-media{.system.api.txt}",
         ":framework-mediaprovider{.system.api.txt}",
@@ -126,10 +108,11 @@
             dest: "android.txt",
         },
     ],
+    visibility: ["//visibility:public"],
 }
 
 genrule {
-    name: "frameworks-base-api-system-removed-merged.txt",
+    name: "frameworks-base-api-system-removed.txt",
     srcs: [
         ":framework-media{.system.removed-api.txt}",
         ":framework-mediaprovider{.system.removed-api.txt}",
@@ -150,10 +133,11 @@
             dest: "system-removed.txt",
         },
     ],
+    visibility: ["//visibility:public"],
 }
 
 genrule {
-    name: "frameworks-base-api-module-lib-current-merged.txt",
+    name: "frameworks-base-api-module-lib-current.txt",
     srcs: [
         ":framework-media{.module-lib.api.txt}",
         ":framework-mediaprovider{.module-lib.api.txt}",
@@ -182,7 +166,7 @@
 }
 
 genrule {
-    name: "frameworks-base-api-module-lib-removed-merged.txt",
+    name: "frameworks-base-api-module-lib-removed.txt",
     srcs: [
         ":framework-media{.module-lib.removed-api.txt}",
         ":framework-mediaprovider{.module-lib.removed-api.txt}",
@@ -208,8 +192,8 @@
 genrule {
     name: "combined-removed-dex",
     srcs: [
-        ":frameworks-base-api-removed-merged.txt",
-        ":frameworks-base-api-system-removed-merged.txt",
+        ":frameworks-base-api-removed.txt",
+        ":frameworks-base-api-system-removed.txt",
         ":android.car-stubs-docs{.removed-api.txt}",
         ":android.car-system-stubs-docs{.removed-api.txt}",
     ],
diff --git a/api/current.txt b/api/current.txt
index 560b5f6..5d46a68 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -38641,6 +38641,9 @@
     ctor public CallLog.Calls();
     method public static String getLastOutgoingCall(android.content.Context);
     field public static final int ANSWERED_EXTERNALLY_TYPE = 7; // 0x7
+    field public static final long AUTO_MISSED_EMERGENCY_CALL = 1L; // 0x1L
+    field public static final long AUTO_MISSED_MAXIMUM_DIALING = 4L; // 0x4L
+    field public static final long AUTO_MISSED_MAXIMUM_RINGING = 2L; // 0x2L
     field public static final int BLOCKED_TYPE = 6; // 0x6
     field public static final String BLOCK_REASON = "block_reason";
     field public static final int BLOCK_REASON_BLOCKED_NUMBER = 3; // 0x3
@@ -38686,6 +38689,8 @@
     field public static final String IS_READ = "is_read";
     field public static final String LAST_MODIFIED = "last_modified";
     field public static final String LIMIT_PARAM_KEY = "limit";
+    field public static final String MISSED_REASON = "missed_reason";
+    field public static final long MISSED_REASON_NOT_MISSED = 0L; // 0x0L
     field public static final int MISSED_TYPE = 3; // 0x3
     field public static final String NEW = "new";
     field public static final String NUMBER = "number";
@@ -38702,6 +38707,13 @@
     field public static final int REJECTED_TYPE = 5; // 0x5
     field public static final String TRANSCRIPTION = "transcription";
     field public static final String TYPE = "type";
+    field public static final long USER_MISSED_CALL_FILTERS_TIMEOUT = 4194304L; // 0x400000L
+    field public static final long USER_MISSED_CALL_SCREENING_SERVICE_SILENCED = 2097152L; // 0x200000L
+    field public static final long USER_MISSED_DND_MODE = 262144L; // 0x40000L
+    field public static final long USER_MISSED_LOW_RING_VOLUME = 524288L; // 0x80000L
+    field public static final long USER_MISSED_NO_ANSWER = 65536L; // 0x10000L
+    field public static final long USER_MISSED_NO_VIBRATE = 1048576L; // 0x100000L
+    field public static final long USER_MISSED_SHORT_RING = 131072L; // 0x20000L
     field public static final String VIA_NUMBER = "via_number";
     field public static final int VOICEMAIL_TYPE = 4; // 0x4
     field public static final String VOICEMAIL_URI = "voicemail_uri";
diff --git a/api/module-lib-current.txt b/api/module-lib-current.txt
deleted file mode 100644
index 3b32b53..0000000
--- a/api/module-lib-current.txt
+++ /dev/null
@@ -1,93 +0,0 @@
-// Signature format: 2.0
-package android.net {
-
-  public final class TetheringConstants {
-    field public static final String EXTRA_ADD_TETHER_TYPE = "extraAddTetherType";
-    field public static final String EXTRA_PROVISION_CALLBACK = "extraProvisionCallback";
-    field public static final String EXTRA_REM_TETHER_TYPE = "extraRemTetherType";
-    field public static final String EXTRA_RUN_PROVISION = "extraRunProvision";
-    field public static final String EXTRA_SET_ALARM = "extraSetAlarm";
-  }
-
-  public class TetheringManager {
-    ctor public TetheringManager(@NonNull android.content.Context, @NonNull java.util.function.Supplier<android.os.IBinder>);
-    method public int getLastTetherError(@NonNull String);
-    method @NonNull public String[] getTetherableBluetoothRegexs();
-    method @NonNull public String[] getTetherableIfaces();
-    method @NonNull public String[] getTetherableUsbRegexs();
-    method @NonNull public String[] getTetherableWifiRegexs();
-    method @NonNull public String[] getTetheredIfaces();
-    method @NonNull public String[] getTetheringErroredIfaces();
-    method public boolean isTetheringSupported();
-    method public boolean isTetheringSupported(@NonNull String);
-    method public void requestLatestTetheringEntitlementResult(int, @NonNull android.os.ResultReceiver, boolean);
-    method @Deprecated public int setUsbTethering(boolean);
-    method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public void startTethering(int, @NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.StartTetheringCallback);
-    method @Deprecated public int tether(@NonNull String);
-    method @Deprecated public int untether(@NonNull String);
-  }
-
-  public static interface TetheringManager.TetheringEventCallback {
-    method public default void onTetherableInterfaceRegexpsChanged(@NonNull android.net.TetheringManager.TetheringInterfaceRegexps);
-  }
-
-  public static class TetheringManager.TetheringInterfaceRegexps {
-    method @NonNull public java.util.List<java.lang.String> getTetherableBluetoothRegexs();
-    method @NonNull public java.util.List<java.lang.String> getTetherableUsbRegexs();
-    method @NonNull public java.util.List<java.lang.String> getTetherableWifiRegexs();
-  }
-
-}
-
-package android.os {
-
-  public class Binder implements android.os.IBinder {
-    method public final void markVintfStability();
-  }
-
-  public interface Parcelable {
-    method public default int getStability();
-  }
-
-  public class StatsFrameworkInitializer {
-    method public static void registerServiceWrappers();
-    method public static void setStatsServiceManager(@NonNull android.os.StatsServiceManager);
-  }
-
-  public class StatsServiceManager {
-    method @NonNull public android.os.StatsServiceManager.ServiceRegisterer getStatsCompanionServiceRegisterer();
-    method @NonNull public android.os.StatsServiceManager.ServiceRegisterer getStatsManagerServiceRegisterer();
-    method @NonNull public android.os.StatsServiceManager.ServiceRegisterer getStatsdServiceRegisterer();
-  }
-
-  public static class StatsServiceManager.ServiceNotFoundException extends java.lang.Exception {
-    ctor public StatsServiceManager.ServiceNotFoundException(@NonNull String);
-  }
-
-  public static final class StatsServiceManager.ServiceRegisterer {
-    method @Nullable public android.os.IBinder get();
-    method @Nullable public android.os.IBinder getOrThrow() throws android.os.StatsServiceManager.ServiceNotFoundException;
-  }
-
-}
-
-package android.telephony {
-
-  public abstract class CellSignalStrength {
-    method public static int getNumSignalStrengthLevels();
-  }
-
-  public class TelephonyManager {
-    method @NonNull public static int[] getAllNetworkTypes();
-  }
-
-}
-
-package android.util {
-
-  public final class Log {
-    method public static int logToRadioBuffer(int, @Nullable String, @Nullable String);
-  }
-
-}
-
diff --git a/api/module-lib-lint-baseline.txt b/api/module-lib-lint-baseline.txt
deleted file mode 100644
index 56f7a02..0000000
--- a/api/module-lib-lint-baseline.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-// Baseline format: 1.0
-ActionValue: android.net.TetheringConstants#EXTRA_ADD_TETHER_TYPE:
-    Inconsistent extra value; expected `android.net.extra.ADD_TETHER_TYPE`, was `extraAddTetherType`
-ActionValue: android.net.TetheringConstants#EXTRA_PROVISION_CALLBACK:
-    Inconsistent extra value; expected `android.net.extra.PROVISION_CALLBACK`, was `extraProvisionCallback`
-ActionValue: android.net.TetheringConstants#EXTRA_REM_TETHER_TYPE:
-    Inconsistent extra value; expected `android.net.extra.REM_TETHER_TYPE`, was `extraRemTetherType`
-ActionValue: android.net.TetheringConstants#EXTRA_RUN_PROVISION:
-    Inconsistent extra value; expected `android.net.extra.RUN_PROVISION`, was `extraRunProvision`
-ActionValue: android.net.TetheringConstants#EXTRA_SET_ALARM:
-    Inconsistent extra value; expected `android.net.extra.SET_ALARM`, was `extraSetAlarm`
-ActionValue: android.net.TetheringManager#ACTION_TETHER_STATE_CHANGED:
-    Inconsistent action value; expected `android.net.action.TETHER_STATE_CHANGED`, was `android.net.conn.TETHER_STATE_CHANGED`
-ActionValue: android.net.TetheringManager#EXTRA_ACTIVE_TETHER:
-    Inconsistent extra value; expected `android.net.extra.ACTIVE_TETHER`, was `tetherArray`
-ActionValue: android.net.TetheringManager#EXTRA_AVAILABLE_TETHER:
-    Inconsistent extra value; expected `android.net.extra.AVAILABLE_TETHER`, was `availableArray`
-ActionValue: android.net.TetheringManager#EXTRA_ERRORED_TETHER:
-    Inconsistent extra value; expected `android.net.extra.ERRORED_TETHER`, was `erroredArray`
-
-
-ManagerConstructor: android.net.TetheringManager#TetheringManager(android.content.Context, java.util.function.Supplier<android.os.IBinder>):
-    Managers must always be obtained from Context; no direct constructors
-
-
-PrivateSuperclass: android.location.GnssAntennaInfo.PhaseCenterVariationCorrections:
-    Public class android.location.GnssAntennaInfo.PhaseCenterVariationCorrections extends private class android.location.GnssAntennaInfo.SphericalCorrections
-PrivateSuperclass: android.location.GnssAntennaInfo.SignalGainCorrections:
-    Public class android.location.GnssAntennaInfo.SignalGainCorrections extends private class android.location.GnssAntennaInfo.SphericalCorrections
diff --git a/api/module-lib-removed.txt b/api/module-lib-removed.txt
deleted file mode 100644
index d802177..0000000
--- a/api/module-lib-removed.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/api/system-current.txt b/api/system-current.txt
index 85d7930..55cc12e 100755
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -369,6 +369,7 @@
     field public static final String OPSTR_ACCEPT_HANDOVER = "android:accept_handover";
     field public static final String OPSTR_ACCESS_ACCESSIBILITY = "android:access_accessibility";
     field public static final String OPSTR_ACCESS_NOTIFICATIONS = "android:access_notifications";
+    field public static final String OPSTR_ACTIVATE_PLATFORM_VPN = "android:activate_platform_vpn";
     field public static final String OPSTR_ACTIVATE_VPN = "android:activate_vpn";
     field public static final String OPSTR_ASSIST_SCREENSHOT = "android:assist_screenshot";
     field public static final String OPSTR_ASSIST_STRUCTURE = "android:assist_structure";
@@ -8992,6 +8993,7 @@
     field public static final String NAMESPACE_PACKAGE_MANAGER_SERVICE = "package_manager_service";
     field public static final String NAMESPACE_PERMISSIONS = "permissions";
     field public static final String NAMESPACE_PRIVACY = "privacy";
+    field public static final String NAMESPACE_PROFCOLLECT_NATIVE_BOOT = "profcollect_native_boot";
     field public static final String NAMESPACE_ROLLBACK = "rollback";
     field public static final String NAMESPACE_ROLLBACK_BOOT = "rollback_boot";
     field public static final String NAMESPACE_RUNTIME = "runtime";
@@ -11254,6 +11256,7 @@
     method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isIdle();
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isLteCdmaEvdoGsmWcdmaEnabled();
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isMobileDataPolicyEnabled(int);
+    method public boolean isNrDualConnectivityEnabled();
     method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isOffhook();
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isOpportunisticNetworkEnabled();
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isPotentialEmergencyNumber(@NonNull String);
@@ -11286,6 +11289,7 @@
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataRoamingEnabled(boolean);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setMobileDataPolicyEnabledStatus(int, boolean);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setMultiSimCarrierRestriction(boolean);
+    method public int setNrDualConnectivityState(int);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setOpportunisticNetworkState(boolean);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setPreferredNetworkTypeBitmask(long);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setRadio(boolean);
@@ -11325,6 +11329,11 @@
     field public static final int CARRIER_PRIVILEGE_STATUS_HAS_ACCESS = 1; // 0x1
     field public static final int CARRIER_PRIVILEGE_STATUS_NO_ACCESS = 0; // 0x0
     field public static final int CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED = -1; // 0xffffffff
+    field public static final int ENABLE_NR_DUAL_CONNECTIVITY_INVALID_STATE = 4; // 0x4
+    field public static final int ENABLE_NR_DUAL_CONNECTIVITY_NOT_SUPPORTED = 1; // 0x1
+    field public static final int ENABLE_NR_DUAL_CONNECTIVITY_RADIO_ERROR = 3; // 0x3
+    field public static final int ENABLE_NR_DUAL_CONNECTIVITY_RADIO_NOT_AVAILABLE = 2; // 0x2
+    field public static final int ENABLE_NR_DUAL_CONNECTIVITY_SUCCESS = 0; // 0x0
     field public static final String EXTRA_ANOMALY_DESCRIPTION = "android.telephony.extra.ANOMALY_DESCRIPTION";
     field public static final String EXTRA_ANOMALY_ID = "android.telephony.extra.ANOMALY_ID";
     field public static final String EXTRA_PHONE_IN_ECM_STATE = "android.telephony.extra.PHONE_IN_ECM_STATE";
@@ -11357,6 +11366,9 @@
     field public static final long NETWORK_TYPE_BITMASK_TD_SCDMA = 65536L; // 0x10000L
     field public static final long NETWORK_TYPE_BITMASK_UMTS = 4L; // 0x4L
     field public static final long NETWORK_TYPE_BITMASK_UNKNOWN = 0L; // 0x0L
+    field public static final int NR_DUAL_CONNECTIVITY_DISABLE = 2; // 0x2
+    field public static final int NR_DUAL_CONNECTIVITY_DISABLE_IMMEDIATE = 3; // 0x3
+    field public static final int NR_DUAL_CONNECTIVITY_ENABLE = 1; // 0x1
     field public static final int RADIO_POWER_OFF = 0; // 0x0
     field public static final int RADIO_POWER_ON = 1; // 0x1
     field public static final int RADIO_POWER_UNAVAILABLE = 2; // 0x2
@@ -11734,6 +11746,17 @@
 
 package android.telephony.ims {
 
+  public final class AudioCodecAttributes implements android.os.Parcelable {
+    ctor public AudioCodecAttributes(float, @NonNull android.util.Range<java.lang.Float>, float, @NonNull android.util.Range<java.lang.Float>);
+    method public int describeContents();
+    method public float getBandwidthKhz();
+    method @NonNull public android.util.Range<java.lang.Float> getBandwidthRangeKhz();
+    method public float getBitrateKbps();
+    method @NonNull public android.util.Range<java.lang.Float> getBitrateRangeKbps();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.AudioCodecAttributes> CREATOR;
+  }
+
   public final class ImsCallForwardInfo implements android.os.Parcelable {
     ctor public ImsCallForwardInfo(int, int, int, int, @NonNull String, int);
     method public int describeContents();
@@ -11763,6 +11786,7 @@
     ctor public ImsCallProfile(int, int);
     ctor public ImsCallProfile(int, int, android.os.Bundle, android.telephony.ims.ImsStreamMediaProfile);
     method public int describeContents();
+    method @NonNull public java.util.Set<android.telephony.ims.RtpHeaderExtensionType> getAcceptedRtpHeaderExtensionTypes();
     method public String getCallExtra(String);
     method public String getCallExtra(String, String);
     method public boolean getCallExtraBoolean(String);
@@ -11777,6 +11801,7 @@
     method public int getEmergencyServiceCategories();
     method @NonNull public java.util.List<java.lang.String> getEmergencyUrns();
     method public android.telephony.ims.ImsStreamMediaProfile getMediaProfile();
+    method @NonNull public java.util.Set<android.telephony.ims.RtpHeaderExtensionType> getOfferedRtpHeaderExtensionTypes();
     method @NonNull public android.os.Bundle getProprietaryCallExtras();
     method public int getRestrictCause();
     method public int getServiceType();
@@ -11787,6 +11812,7 @@
     method public boolean isVideoCall();
     method public boolean isVideoPaused();
     method public static int presentationToOir(int);
+    method public void setAcceptedRtpHeaderExtensionTypes(@NonNull java.util.Set<android.telephony.ims.RtpHeaderExtensionType>);
     method public void setCallExtra(String, String);
     method public void setCallExtraBoolean(String, boolean);
     method public void setCallExtraInt(String, int);
@@ -11797,6 +11823,7 @@
     method public void setEmergencyServiceCategories(int);
     method public void setEmergencyUrns(@NonNull java.util.List<java.lang.String>);
     method public void setHasKnownUserIntentEmergency(boolean);
+    method public void setOfferedRtpHeaderExtensionTypes(@NonNull java.util.Set<android.telephony.ims.RtpHeaderExtensionType>);
     method public void updateCallExtras(android.telephony.ims.ImsCallProfile);
     method public void updateCallType(android.telephony.ims.ImsCallProfile);
     method public void updateMediaProfile(android.telephony.ims.ImsCallProfile);
@@ -11856,6 +11883,7 @@
     method public void callSessionConferenceExtendReceived(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile);
     method public void callSessionConferenceExtended(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile);
     method public void callSessionConferenceStateUpdated(android.telephony.ims.ImsConferenceState);
+    method public void callSessionDtmfReceived(char);
     method @Deprecated public void callSessionHandover(int, int, android.telephony.ims.ImsReasonInfo);
     method @Deprecated public void callSessionHandoverFailed(int, int, android.telephony.ims.ImsReasonInfo);
     method public void callSessionHeld(android.telephony.ims.ImsCallProfile);
@@ -11876,6 +11904,7 @@
     method public void callSessionResumeFailed(android.telephony.ims.ImsReasonInfo);
     method public void callSessionResumeReceived(android.telephony.ims.ImsCallProfile);
     method public void callSessionResumed(android.telephony.ims.ImsCallProfile);
+    method public void callSessionRtpHeaderExtensionsReceived(@NonNull java.util.Set<android.telephony.ims.RtpHeaderExtension>);
     method public void callSessionRttAudioIndicatorChanged(@NonNull android.telephony.ims.ImsStreamMediaProfile);
     method public void callSessionRttMessageReceived(String);
     method public void callSessionRttModifyRequestReceived(android.telephony.ims.ImsCallProfile);
@@ -12102,6 +12131,7 @@
     ctor public ImsStreamMediaProfile(int, int, int, int, int);
     method public void copyFrom(android.telephony.ims.ImsStreamMediaProfile);
     method public int describeContents();
+    method @Nullable public android.telephony.ims.AudioCodecAttributes getAudioCodecAttributes();
     method public int getAudioDirection();
     method public int getAudioQuality();
     method public int getRttMode();
@@ -12109,6 +12139,7 @@
     method public int getVideoQuality();
     method public boolean isReceivingRttAudio();
     method public boolean isRttCall();
+    method public void setAudioCodecAttributes(@NonNull android.telephony.ims.AudioCodecAttributes);
     method public void setReceivingRttAudio(boolean);
     method public void setRttMode(int);
     method public void writeToParcel(android.os.Parcel, int);
@@ -12230,6 +12261,24 @@
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setUceSettingEnabled(boolean) throws android.telephony.ims.ImsException;
   }
 
+  public final class RtpHeaderExtension implements android.os.Parcelable {
+    ctor public RtpHeaderExtension(@IntRange(from=1, to=14) int, @NonNull byte[]);
+    method public int describeContents();
+    method @NonNull public byte[] getExtensionData();
+    method @IntRange(from=1, to=14) public int getLocalIdentifier();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.RtpHeaderExtension> CREATOR;
+  }
+
+  public final class RtpHeaderExtensionType implements android.os.Parcelable {
+    ctor public RtpHeaderExtensionType(@IntRange(from=1, to=14) int, @NonNull android.net.Uri);
+    method public int describeContents();
+    method @IntRange(from=1, to=14) public int getLocalIdentifier();
+    method @NonNull public android.net.Uri getUri();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.RtpHeaderExtensionType> CREATOR;
+  }
+
   public class SipDelegateManager {
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isSupported() throws android.telephony.ims.ImsException;
   }
@@ -12346,6 +12395,7 @@
     method public void removeParticipants(String[]);
     method public void resume(android.telephony.ims.ImsStreamMediaProfile);
     method public void sendDtmf(char, android.os.Message);
+    method public void sendRtpHeaderExtensions(@NonNull java.util.Set<android.telephony.ims.RtpHeaderExtension>);
     method public void sendRttMessage(String);
     method public void sendRttModifyRequest(android.telephony.ims.ImsCallProfile);
     method public void sendRttModifyResponse(boolean);
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 12ef9ba..cca6299 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -58,6 +58,7 @@
 import "frameworks/base/core/proto/android/stats/storage/storage_enums.proto";
 import "frameworks/base/core/proto/android/stats/style/style_enums.proto";
 import "frameworks/base/core/proto/android/stats/sysui/notification_enums.proto";
+import "frameworks/base/core/proto/android/stats/tls/enums.proto";
 import "frameworks/base/core/proto/android/telecomm/enums.proto";
 import "frameworks/base/core/proto/android/telephony/enums.proto";
 import "frameworks/base/core/proto/android/view/enums.proto";
@@ -485,6 +486,7 @@
         NetworkTetheringReported  network_tethering_reported =
             303 [(module) = "network_tethering"];
         ImeTouchReported ime_touch_reported = 304 [(module) = "sysui"];
+        TlsHandshakeReported tls_handshake_reported = 317 [(module) = "conscrypt"];
 
         // StatsdStats tracks platform atoms with ids upto 500.
         // Update StatsdStats::kMaxPushedAtomId when atom ids here approach that value.
@@ -11197,3 +11199,19 @@
     // List of leasees of this Blob
     optional BlobLeaseeListProto leasees = 5;
 }
+
+/**
+  * Pushes TLS handshake counters from Conscrypt.
+  * Pulled from:
+  *   external/conscrypt/common/src/main/java/org/conscrypt/ConscryptEngineSocket.java
+  *   external/conscrypt/common/src/main/java/org/conscrypt/ConscryptFileDescriptorSocket.java
+  */
+  message TlsHandshakeReported {
+    optional bool success = 1;
+
+    optional android.stats.tls.Protocol protocol = 2;
+
+    optional android.stats.tls.CipherSuite cipher_suite = 3;
+
+    optional int32 handshake_duration_millis = 4;
+}
diff --git a/core/api/current.txt b/core/api/current.txt
index 0aa24cf..b3561a3 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -37208,6 +37208,9 @@
     ctor public CallLog.Calls();
     method public static String getLastOutgoingCall(android.content.Context);
     field public static final int ANSWERED_EXTERNALLY_TYPE = 7; // 0x7
+    field public static final long AUTO_MISSED_EMERGENCY_CALL = 1L; // 0x1L
+    field public static final long AUTO_MISSED_MAXIMUM_DIALING = 4L; // 0x4L
+    field public static final long AUTO_MISSED_MAXIMUM_RINGING = 2L; // 0x2L
     field public static final int BLOCKED_TYPE = 6; // 0x6
     field public static final String BLOCK_REASON = "block_reason";
     field public static final int BLOCK_REASON_BLOCKED_NUMBER = 3; // 0x3
@@ -37253,6 +37256,8 @@
     field public static final String IS_READ = "is_read";
     field public static final String LAST_MODIFIED = "last_modified";
     field public static final String LIMIT_PARAM_KEY = "limit";
+    field public static final String MISSED_REASON = "missed_reason";
+    field public static final long MISSED_REASON_NOT_MISSED = 0L; // 0x0L
     field public static final int MISSED_TYPE = 3; // 0x3
     field public static final String NEW = "new";
     field public static final String NUMBER = "number";
@@ -37269,6 +37274,13 @@
     field public static final int REJECTED_TYPE = 5; // 0x5
     field public static final String TRANSCRIPTION = "transcription";
     field public static final String TYPE = "type";
+    field public static final long USER_MISSED_CALL_FILTERS_TIMEOUT = 4194304L; // 0x400000L
+    field public static final long USER_MISSED_CALL_SCREENING_SERVICE_SILENCED = 2097152L; // 0x200000L
+    field public static final long USER_MISSED_DND_MODE = 262144L; // 0x40000L
+    field public static final long USER_MISSED_LOW_RING_VOLUME = 524288L; // 0x80000L
+    field public static final long USER_MISSED_NO_ANSWER = 65536L; // 0x10000L
+    field public static final long USER_MISSED_NO_VIBRATE = 1048576L; // 0x100000L
+    field public static final long USER_MISSED_SHORT_RING = 131072L; // 0x20000L
     field public static final String VIA_NUMBER = "via_number";
     field public static final int VOICEMAIL_TYPE = 4; // 0x4
     field public static final String VOICEMAIL_URI = "voicemail_uri";
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 25f72bd..dc9789f 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -369,6 +369,7 @@
     field public static final String OPSTR_ACCEPT_HANDOVER = "android:accept_handover";
     field public static final String OPSTR_ACCESS_ACCESSIBILITY = "android:access_accessibility";
     field public static final String OPSTR_ACCESS_NOTIFICATIONS = "android:access_notifications";
+    field public static final String OPSTR_ACTIVATE_PLATFORM_VPN = "android:activate_platform_vpn";
     field public static final String OPSTR_ACTIVATE_VPN = "android:activate_vpn";
     field public static final String OPSTR_ASSIST_SCREENSHOT = "android:assist_screenshot";
     field public static final String OPSTR_ASSIST_STRUCTURE = "android:assist_structure";
@@ -7883,6 +7884,7 @@
     field public static final String NAMESPACE_PACKAGE_MANAGER_SERVICE = "package_manager_service";
     field public static final String NAMESPACE_PERMISSIONS = "permissions";
     field public static final String NAMESPACE_PRIVACY = "privacy";
+    field public static final String NAMESPACE_PROFCOLLECT_NATIVE_BOOT = "profcollect_native_boot";
     field public static final String NAMESPACE_ROLLBACK = "rollback";
     field public static final String NAMESPACE_ROLLBACK_BOOT = "rollback_boot";
     field public static final String NAMESPACE_RUNTIME = "runtime";
@@ -10136,6 +10138,7 @@
     method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isIdle();
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isLteCdmaEvdoGsmWcdmaEnabled();
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isMobileDataPolicyEnabled(int);
+    method public boolean isNrDualConnectivityEnabled();
     method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isOffhook();
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isOpportunisticNetworkEnabled();
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isPotentialEmergencyNumber(@NonNull String);
@@ -10168,6 +10171,7 @@
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataRoamingEnabled(boolean);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setMobileDataPolicyEnabledStatus(int, boolean);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setMultiSimCarrierRestriction(boolean);
+    method public int setNrDualConnectivityState(int);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setOpportunisticNetworkState(boolean);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setPreferredNetworkTypeBitmask(long);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setRadio(boolean);
@@ -10207,6 +10211,11 @@
     field public static final int CARRIER_PRIVILEGE_STATUS_HAS_ACCESS = 1; // 0x1
     field public static final int CARRIER_PRIVILEGE_STATUS_NO_ACCESS = 0; // 0x0
     field public static final int CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED = -1; // 0xffffffff
+    field public static final int ENABLE_NR_DUAL_CONNECTIVITY_INVALID_STATE = 4; // 0x4
+    field public static final int ENABLE_NR_DUAL_CONNECTIVITY_NOT_SUPPORTED = 1; // 0x1
+    field public static final int ENABLE_NR_DUAL_CONNECTIVITY_RADIO_ERROR = 3; // 0x3
+    field public static final int ENABLE_NR_DUAL_CONNECTIVITY_RADIO_NOT_AVAILABLE = 2; // 0x2
+    field public static final int ENABLE_NR_DUAL_CONNECTIVITY_SUCCESS = 0; // 0x0
     field public static final String EXTRA_ANOMALY_DESCRIPTION = "android.telephony.extra.ANOMALY_DESCRIPTION";
     field public static final String EXTRA_ANOMALY_ID = "android.telephony.extra.ANOMALY_ID";
     field public static final String EXTRA_PHONE_IN_ECM_STATE = "android.telephony.extra.PHONE_IN_ECM_STATE";
@@ -10239,6 +10248,9 @@
     field public static final long NETWORK_TYPE_BITMASK_TD_SCDMA = 65536L; // 0x10000L
     field public static final long NETWORK_TYPE_BITMASK_UMTS = 4L; // 0x4L
     field public static final long NETWORK_TYPE_BITMASK_UNKNOWN = 0L; // 0x0L
+    field public static final int NR_DUAL_CONNECTIVITY_DISABLE = 2; // 0x2
+    field public static final int NR_DUAL_CONNECTIVITY_DISABLE_IMMEDIATE = 3; // 0x3
+    field public static final int NR_DUAL_CONNECTIVITY_ENABLE = 1; // 0x1
     field public static final int RADIO_POWER_OFF = 0; // 0x0
     field public static final int RADIO_POWER_ON = 1; // 0x1
     field public static final int RADIO_POWER_UNAVAILABLE = 2; // 0x2
@@ -10616,6 +10628,17 @@
 
 package android.telephony.ims {
 
+  public final class AudioCodecAttributes implements android.os.Parcelable {
+    ctor public AudioCodecAttributes(float, @NonNull android.util.Range<java.lang.Float>, float, @NonNull android.util.Range<java.lang.Float>);
+    method public int describeContents();
+    method public float getBandwidthKhz();
+    method @NonNull public android.util.Range<java.lang.Float> getBandwidthRangeKhz();
+    method public float getBitrateKbps();
+    method @NonNull public android.util.Range<java.lang.Float> getBitrateRangeKbps();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.AudioCodecAttributes> CREATOR;
+  }
+
   public final class ImsCallForwardInfo implements android.os.Parcelable {
     ctor public ImsCallForwardInfo(int, int, int, int, @NonNull String, int);
     method public int describeContents();
@@ -10645,6 +10668,7 @@
     ctor public ImsCallProfile(int, int);
     ctor public ImsCallProfile(int, int, android.os.Bundle, android.telephony.ims.ImsStreamMediaProfile);
     method public int describeContents();
+    method @NonNull public java.util.Set<android.telephony.ims.RtpHeaderExtensionType> getAcceptedRtpHeaderExtensionTypes();
     method public String getCallExtra(String);
     method public String getCallExtra(String, String);
     method public boolean getCallExtraBoolean(String);
@@ -10659,6 +10683,7 @@
     method public int getEmergencyServiceCategories();
     method @NonNull public java.util.List<java.lang.String> getEmergencyUrns();
     method public android.telephony.ims.ImsStreamMediaProfile getMediaProfile();
+    method @NonNull public java.util.Set<android.telephony.ims.RtpHeaderExtensionType> getOfferedRtpHeaderExtensionTypes();
     method @NonNull public android.os.Bundle getProprietaryCallExtras();
     method public int getRestrictCause();
     method public int getServiceType();
@@ -10669,6 +10694,7 @@
     method public boolean isVideoCall();
     method public boolean isVideoPaused();
     method public static int presentationToOir(int);
+    method public void setAcceptedRtpHeaderExtensionTypes(@NonNull java.util.Set<android.telephony.ims.RtpHeaderExtensionType>);
     method public void setCallExtra(String, String);
     method public void setCallExtraBoolean(String, boolean);
     method public void setCallExtraInt(String, int);
@@ -10679,6 +10705,7 @@
     method public void setEmergencyServiceCategories(int);
     method public void setEmergencyUrns(@NonNull java.util.List<java.lang.String>);
     method public void setHasKnownUserIntentEmergency(boolean);
+    method public void setOfferedRtpHeaderExtensionTypes(@NonNull java.util.Set<android.telephony.ims.RtpHeaderExtensionType>);
     method public void updateCallExtras(android.telephony.ims.ImsCallProfile);
     method public void updateCallType(android.telephony.ims.ImsCallProfile);
     method public void updateMediaProfile(android.telephony.ims.ImsCallProfile);
@@ -10738,6 +10765,7 @@
     method public void callSessionConferenceExtendReceived(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile);
     method public void callSessionConferenceExtended(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile);
     method public void callSessionConferenceStateUpdated(android.telephony.ims.ImsConferenceState);
+    method public void callSessionDtmfReceived(char);
     method @Deprecated public void callSessionHandover(int, int, android.telephony.ims.ImsReasonInfo);
     method @Deprecated public void callSessionHandoverFailed(int, int, android.telephony.ims.ImsReasonInfo);
     method public void callSessionHeld(android.telephony.ims.ImsCallProfile);
@@ -10758,6 +10786,7 @@
     method public void callSessionResumeFailed(android.telephony.ims.ImsReasonInfo);
     method public void callSessionResumeReceived(android.telephony.ims.ImsCallProfile);
     method public void callSessionResumed(android.telephony.ims.ImsCallProfile);
+    method public void callSessionRtpHeaderExtensionsReceived(@NonNull java.util.Set<android.telephony.ims.RtpHeaderExtension>);
     method public void callSessionRttAudioIndicatorChanged(@NonNull android.telephony.ims.ImsStreamMediaProfile);
     method public void callSessionRttMessageReceived(String);
     method public void callSessionRttModifyRequestReceived(android.telephony.ims.ImsCallProfile);
@@ -10984,6 +11013,7 @@
     ctor public ImsStreamMediaProfile(int, int, int, int, int);
     method public void copyFrom(android.telephony.ims.ImsStreamMediaProfile);
     method public int describeContents();
+    method @Nullable public android.telephony.ims.AudioCodecAttributes getAudioCodecAttributes();
     method public int getAudioDirection();
     method public int getAudioQuality();
     method public int getRttMode();
@@ -10991,6 +11021,7 @@
     method public int getVideoQuality();
     method public boolean isReceivingRttAudio();
     method public boolean isRttCall();
+    method public void setAudioCodecAttributes(@NonNull android.telephony.ims.AudioCodecAttributes);
     method public void setReceivingRttAudio(boolean);
     method public void setRttMode(int);
     method public void writeToParcel(android.os.Parcel, int);
@@ -11112,6 +11143,24 @@
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setUceSettingEnabled(boolean) throws android.telephony.ims.ImsException;
   }
 
+  public final class RtpHeaderExtension implements android.os.Parcelable {
+    ctor public RtpHeaderExtension(@IntRange(from=1, to=14) int, @NonNull byte[]);
+    method public int describeContents();
+    method @NonNull public byte[] getExtensionData();
+    method @IntRange(from=1, to=14) public int getLocalIdentifier();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.RtpHeaderExtension> CREATOR;
+  }
+
+  public final class RtpHeaderExtensionType implements android.os.Parcelable {
+    ctor public RtpHeaderExtensionType(@IntRange(from=1, to=14) int, @NonNull android.net.Uri);
+    method public int describeContents();
+    method @IntRange(from=1, to=14) public int getLocalIdentifier();
+    method @NonNull public android.net.Uri getUri();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.RtpHeaderExtensionType> CREATOR;
+  }
+
   public class SipDelegateManager {
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isSupported() throws android.telephony.ims.ImsException;
   }
@@ -11228,6 +11277,7 @@
     method public void removeParticipants(String[]);
     method public void resume(android.telephony.ims.ImsStreamMediaProfile);
     method public void sendDtmf(char, android.os.Message);
+    method public void sendRtpHeaderExtensions(@NonNull java.util.Set<android.telephony.ims.RtpHeaderExtension>);
     method public void sendRttMessage(String);
     method public void sendRttModifyRequest(android.telephony.ims.ImsCallProfile);
     method public void sendRttModifyResponse(boolean);
diff --git a/api/test-current.txt b/core/api/test-current.txt
similarity index 100%
rename from api/test-current.txt
rename to core/api/test-current.txt
diff --git a/api/test-lint-baseline.txt b/core/api/test-lint-baseline.txt
similarity index 100%
rename from api/test-lint-baseline.txt
rename to core/api/test-lint-baseline.txt
diff --git a/api/test-removed.txt b/core/api/test-removed.txt
similarity index 100%
rename from api/test-removed.txt
rename to core/api/test-removed.txt
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 0d5bb11..1c8c6c1 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -1439,6 +1439,7 @@
     @SystemApi
     public static final String OPSTR_INTERACT_ACROSS_PROFILES = "android:interact_across_profiles";
     /** @hide Start Platform VPN without user intervention */
+    @SystemApi
     public static final String OPSTR_ACTIVATE_PLATFORM_VPN = "android:activate_platform_vpn";
     /** @hide */
     @SystemApi
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 93bff3c..7391b0c 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -207,7 +207,7 @@
      * <p>
      * Avoids spamming the system with overly large strings such as full e-mails.
      */
-    private static final int MAX_CHARSEQUENCE_LENGTH = 5 * 1024;
+    private static final int MAX_CHARSEQUENCE_LENGTH = 1024;
 
     /**
      * Maximum entries of reply text that are accepted by Builder and friends.
@@ -7830,7 +7830,7 @@
              */
             public Message(@NonNull CharSequence text, long timestamp, @Nullable Person sender,
                     boolean remoteInputHistory) {
-                mText = text;
+                mText = safeCharSequence(text);
                 mTimestamp = timestamp;
                 mSender = sender;
                 mRemoteInputHistory = remoteInputHistory;
@@ -7944,7 +7944,7 @@
                 bundle.putLong(KEY_TIMESTAMP, mTimestamp);
                 if (mSender != null) {
                     // Legacy listeners need this
-                    bundle.putCharSequence(KEY_SENDER, mSender.getName());
+                    bundle.putCharSequence(KEY_SENDER, safeCharSequence(mSender.getName()));
                     bundle.putParcelable(KEY_SENDER_PERSON, mSender);
                 }
                 if (mDataMimeType != null) {
diff --git a/core/java/android/app/admin/DevicePolicyManagerInternal.java b/core/java/android/app/admin/DevicePolicyManagerInternal.java
index 19242ba..ffa537e 100644
--- a/core/java/android/app/admin/DevicePolicyManagerInternal.java
+++ b/core/java/android/app/admin/DevicePolicyManagerInternal.java
@@ -88,6 +88,26 @@
     public abstract boolean isActiveAdminWithPolicy(int uid, int reqPolicy);
 
     /**
+     * Checks if an app with given uid is an active device owner of its user.
+     *
+     * <p>This takes the DPMS lock.  DO NOT call from PM/UM/AM with their lock held.
+     *
+     * @param uid App uid.
+     * @return true if the uid is an active device owner.
+     */
+    public abstract boolean isActiveDeviceOwner(int uid);
+
+    /**
+     * Checks if an app with given uid is an active profile owner of its user.
+     *
+     * <p>This takes the DPMS lock.  DO NOT call from PM/UM/AM with their lock held.
+     *
+     * @param uid App uid.
+     * @return true if the uid is an active profile owner.
+     */
+    public abstract boolean isActiveProfileOwner(int uid);
+
+    /**
      * Checks if an app with given uid is the active supervision admin.
      *
      * <p>This takes the DPMS lock. DO NOT call from PM/UM/AM with their lock held.
diff --git a/core/java/android/content/pm/OWNERS b/core/java/android/content/pm/OWNERS
new file mode 100644
index 0000000..a16bb4f
--- /dev/null
+++ b/core/java/android/content/pm/OWNERS
@@ -0,0 +1 @@
+per-file PackageParser.java = chiuwinson@google.com
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 0adb66c..a30a652 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -143,8 +143,14 @@
  * <li>All installations must contain a single base APK.
  * </ul>
  *
+ * @deprecated This class is mostly unused and no new changes should be added to it. Use
+ * {@link android.content.pm.parsing.ParsingPackageUtils} and related parsing v2 infrastructure in
+ * the core/services parsing subpackages. Or for a quick parse of a provided APK, use
+ * {@link PackageManager#getPackageArchiveInfo(String, int)}.
+ *
  * @hide
  */
+@Deprecated
 public class PackageParser {
 
     public static final boolean DEBUG_JAR = false;
diff --git a/core/java/android/content/pm/parsing/OWNERS b/core/java/android/content/pm/parsing/OWNERS
new file mode 100644
index 0000000..8049d5c
--- /dev/null
+++ b/core/java/android/content/pm/parsing/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 36137
+
+chiuwinson@google.com
+patb@google.com
+toddke@google.com
diff --git a/core/java/android/os/LocaleList.java b/core/java/android/os/LocaleList.java
index ab4bb0b..9c0bc45 100644
--- a/core/java/android/os/LocaleList.java
+++ b/core/java/android/os/LocaleList.java
@@ -25,6 +25,7 @@
 
 import com.android.internal.annotations.GuardedBy;
 
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashSet;
@@ -151,18 +152,18 @@
     /**
      * Creates a new {@link LocaleList}.
      *
+     * If two or more same locales are passed, the repeated locales will be dropped.
      * <p>For empty lists of {@link Locale} items it is better to use {@link #getEmptyLocaleList()},
      * which returns a pre-constructed empty list.</p>
      *
      * @throws NullPointerException if any of the input locales is <code>null</code>.
-     * @throws IllegalArgumentException if any of the input locales repeat.
      */
     public LocaleList(@NonNull Locale... list) {
         if (list.length == 0) {
             mList = sEmptyList;
             mStringRepresentation = "";
         } else {
-            final Locale[] localeList = new Locale[list.length];
+            final ArrayList<Locale> localeList = new ArrayList<>();
             final HashSet<Locale> seenLocales = new HashSet<Locale>();
             final StringBuilder sb = new StringBuilder();
             for (int i = 0; i < list.length; i++) {
@@ -170,10 +171,10 @@
                 if (l == null) {
                     throw new NullPointerException("list[" + i + "] is null");
                 } else if (seenLocales.contains(l)) {
-                    throw new IllegalArgumentException("list[" + i + "] is a repetition");
+                    // Dropping duplicated locale entries.
                 } else {
                     final Locale localeClone = (Locale) l.clone();
-                    localeList[i] = localeClone;
+                    localeList.add(localeClone);
                     sb.append(localeClone.toLanguageTag());
                     if (i < list.length - 1) {
                         sb.append(',');
@@ -181,7 +182,7 @@
                     seenLocales.add(localeClone);
                 }
             }
-            mList = localeList;
+            mList = localeList.toArray(new Locale[localeList.size()]);
             mStringRepresentation = sb.toString();
         }
     }
diff --git a/core/java/android/provider/CallLog.java b/core/java/android/provider/CallLog.java
index 276f162..65132f0 100644
--- a/core/java/android/provider/CallLog.java
+++ b/core/java/android/provider/CallLog.java
@@ -17,6 +17,7 @@
 
 package android.provider;
 
+import android.annotation.LongDef;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.ContentProvider;
 import android.content.ContentResolver;
@@ -43,6 +44,8 @@
 import android.text.TextUtils;
 import android.util.Log;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.List;
 
 /**
@@ -611,6 +614,144 @@
          */
         public static final String BLOCK_REASON = "block_reason";
 
+        /** @hide */
+        @LongDef(flag = true, value = {
+                MISSED_REASON_NOT_MISSED,
+                AUTO_MISSED_EMERGENCY_CALL,
+                AUTO_MISSED_MAXIMUM_RINGING,
+                AUTO_MISSED_MAXIMUM_DIALING,
+                USER_MISSED_NO_ANSWER,
+                USER_MISSED_SHORT_RING,
+                USER_MISSED_DND_MODE,
+                USER_MISSED_LOW_RING_VOLUME,
+                USER_MISSED_NO_VIBRATE,
+                USER_MISSED_CALL_SCREENING_SERVICE_SILENCED,
+                USER_MISSED_CALL_FILTERS_TIMEOUT
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface MissedReason {}
+
+        /**
+         * Value for {@link CallLog.Calls#MISSED_REASON}, set as the default value when a call was
+         * not missed.
+         */
+        public static final long MISSED_REASON_NOT_MISSED = 0;
+
+        /**
+         * Value for {@link CallLog.Calls#MISSED_REASON}, set when {@link CallLog.Calls#TYPE} is
+         * {@link CallLog.Calls#MISSED_TYPE} to indicate that a call was automatically rejected by
+         * system because an ongoing emergency call.
+         */
+        public static final long AUTO_MISSED_EMERGENCY_CALL = 1 << 0;
+
+        /**
+         * Value for {@link CallLog.Calls#MISSED_REASON}, set when {@link CallLog.Calls#TYPE} is
+         * {@link CallLog.Calls#MISSED_TYPE} to indicate that a call was automatically rejected by
+         * system because the system cannot support any more ringing calls.
+         */
+        public static final long AUTO_MISSED_MAXIMUM_RINGING = 1 << 1;
+
+        /**
+         * Value for {@link CallLog.Calls#MISSED_REASON}, set when {@link CallLog.Calls#TYPE} is
+         * {@link CallLog.Calls#MISSED_TYPE} to indicate that a call was automatically rejected by
+         * system because the system cannot support any more dialing calls.
+         */
+        public static final long AUTO_MISSED_MAXIMUM_DIALING = 1 << 2;
+
+        /**
+         * When {@link CallLog.Calls#TYPE} is {@link CallLog.Calls#MISSED_TYPE}, set this bit when
+         * the call was missed just because user didn't answer it.
+         */
+        public static final long USER_MISSED_NO_ANSWER = 1 << 16;
+
+        /**
+         * When {@link CallLog.Calls#TYPE} is {@link CallLog.Calls#MISSED_TYPE}, set this bit when
+         * this call rang for a short period of time.
+         */
+        public static final long USER_MISSED_SHORT_RING = 1 << 17;
+
+        /**
+         * When {@link CallLog.Calls#TYPE} is {@link CallLog.Calls#MISSED_TYPE}, when this call
+         * rings less than this defined time in millisecond, set
+         * {@link CallLog.Calls#USER_MISSED_SHORT_RING} bit.
+         * @hide
+         */
+        public static final long SHORT_RING_THRESHOLD = 5000L;
+
+        /**
+         * When {@link CallLog.Calls#TYPE} is {@link CallLog.Calls#MISSED_TYPE}, set this bit when
+         * this call is silenced because the phone is in 'do not disturb mode'.
+         */
+        public static final long USER_MISSED_DND_MODE = 1 << 18;
+
+        /**
+         * When {@link CallLog.Calls#TYPE} is {@link CallLog.Calls#MISSED_TYPE}, set this bit when
+         * this call rings with a low ring volume.
+         */
+        public static final long USER_MISSED_LOW_RING_VOLUME = 1 << 19;
+
+        /**
+         * When {@link CallLog.Calls#TYPE} is {@link CallLog.Calls#MISSED_TYPE}, when this call
+         * rings in volume less than this defined volume threshold, set
+         * {@link CallLog.Calls#USER_MISSED_LOW_RING_VOLUME} bit.
+         * @hide
+         */
+        public static final int LOW_RING_VOLUME = 0;
+
+        /**
+         * When {@link CallLog.Calls#TYPE} is {@link CallLog.Calls#MISSED_TYPE} set this bit when
+         * this call rings without vibration.
+         */
+        public static final long USER_MISSED_NO_VIBRATE = 1 << 20;
+
+        /**
+         * When {@link CallLog.Calls#TYPE} is {@link CallLog.Calls#MISSED_TYPE}, set this bit when
+         * this call is silenced by the call screening service.
+         */
+        public static final long USER_MISSED_CALL_SCREENING_SERVICE_SILENCED = 1 << 21;
+
+        /**
+         * When {@link CallLog.Calls#TYPE} is {@link CallLog.Calls#MISSED_TYPE}, set this bit when
+         * the call filters timed out.
+         */
+        public static final long USER_MISSED_CALL_FILTERS_TIMEOUT = 1 << 22;
+
+        /**
+         * Where the {@link CallLog.Calls#TYPE} is {@link CallLog.Calls#MISSED_TYPE},
+         * indicates factors which may have lead the user to miss the call.
+         * <P>Type: INTEGER</P>
+         *
+         * <p>
+         * There are two main cases. Auto missed cases and user missed cases. Default value is:
+         * <ul>
+         * <li>{@link CallLog.Calls#MISSED_REASON_NOT_MISSED}</li>
+         * </ul>
+         * </p>
+         * <P>
+         * Auto missed cases are those where a call was missed because it was not possible for the
+         * incoming call to be presented to the user at all. Possible values are:
+         * <ul>
+         * <li>{@link CallLog.Calls#AUTO_MISSED_EMERGENCY_CALL}</li>
+         * <li>{@link CallLog.Calls#AUTO_MISSED_MAXIMUM_RINGING}</li>
+         * <li>{@link CallLog.Calls#AUTO_MISSED_MAXIMUM_DIALING}</li>
+         * </ul>
+         * </P>
+         * <P>
+         * User missed cases are those where the incoming call was presented to the user, but
+         * factors such as a low ringing volume may have contributed to the call being missed.
+         * Following bits can be set to indicate possible reasons for this:
+         * <ul>
+         * <li>{@link CallLog.Calls#USER_MISSED_SHORT_RING}</li>
+         * <li>{@link CallLog.Calls#USER_MISSED_DND_MODE}</li>
+         * <li>{@link CallLog.Calls#USER_MISSED_LOW_RING_VOLUME}</li>
+         * <li>{@link CallLog.Calls#USER_MISSED_NO_VIBRATE}</li>
+         * <li>{@link CallLog.Calls#USER_MISSED_CALL_SCREENING_SERVICE_SILENCED}</li>
+         * <li>{@link CallLog.Calls#USER_MISSED_CALL_FILTERS_TIMEOUT}</li>
+         * </ul>
+         * </P>
+         */
+        public static final String MISSED_REASON = "missed_reason";
+
         /**
          * Adds a call to the call log.
          *
@@ -635,12 +776,13 @@
         public static Uri addCall(CallerInfo ci, Context context, String number,
                 int presentation, int callType, int features,
                 PhoneAccountHandle accountHandle,
-                long start, int duration, Long dataUsage) {
+                long start, int duration, Long dataUsage, long missedReason) {
             return addCall(ci, context, number, "" /* postDialDigits */, "" /* viaNumber */,
                 presentation, callType, features, accountHandle, start, duration,
                 dataUsage, false /* addForAllUsers */, null /* userToBeInsertedTo */,
                 false /* isRead */, Calls.BLOCK_REASON_NOT_BLOCKED /* callBlockReason */,
-                null /* callScreeningAppName */, null /* callScreeningComponentName */);
+                null /* callScreeningAppName */, null /* callScreeningComponentName */,
+                    missedReason);
         }
 
 
@@ -675,12 +817,13 @@
         public static Uri addCall(CallerInfo ci, Context context, String number,
                 String postDialDigits, String viaNumber, int presentation, int callType,
                 int features, PhoneAccountHandle accountHandle, long start, int duration,
-                Long dataUsage, boolean addForAllUsers, UserHandle userToBeInsertedTo) {
+                Long dataUsage, boolean addForAllUsers, UserHandle userToBeInsertedTo,
+                long missedReason) {
             return addCall(ci, context, number, postDialDigits, viaNumber, presentation, callType,
                 features, accountHandle, start, duration, dataUsage, addForAllUsers,
                 userToBeInsertedTo, false /* isRead */ , Calls.BLOCK_REASON_NOT_BLOCKED
                 /* callBlockReason */, null /* callScreeningAppName */,
-                null /* callScreeningComponentName */);
+                null /* callScreeningComponentName */, missedReason);
         }
 
         /**
@@ -714,6 +857,7 @@
          * @param callBlockReason The reason why the call is blocked.
          * @param callScreeningAppName The call screening application name which block the call.
          * @param callScreeningComponentName The call screening component name which block the call.
+         * @param missedReason The encoded missed information of the call.
          *
          * @result The URI of the call log entry belonging to the user that made or received this
          *        call.  This could be of the shadow provider.  Do not return it to non-system apps,
@@ -726,7 +870,7 @@
                 int features, PhoneAccountHandle accountHandle, long start, int duration,
                 Long dataUsage, boolean addForAllUsers, UserHandle userToBeInsertedTo,
                 boolean isRead, int callBlockReason, CharSequence callScreeningAppName,
-                String callScreeningComponentName) {
+                String callScreeningComponentName, long missedReason) {
             if (VERBOSE_LOG) {
                 Log.v(LOG_TAG, String.format("Add call: number=%s, user=%s, for all=%s",
                         number, userToBeInsertedTo, addForAllUsers));
@@ -779,6 +923,7 @@
             values.put(BLOCK_REASON, callBlockReason);
             values.put(CALL_SCREENING_APP_NAME, charSequenceToString(callScreeningAppName));
             values.put(CALL_SCREENING_COMPONENT_NAME, callScreeningComponentName);
+            values.put(MISSED_REASON, Long.valueOf(missedReason));
 
             if ((ci != null) && (ci.getContactId() > 0)) {
                 // Update usage information for the number associated with the contact ID.
@@ -1114,5 +1259,19 @@
             }
             return countryIso;
         }
+
+        /**
+         * Check if the missedReason code indicate that the call was user missed or automatically
+         * rejected by system.
+         *
+         * @param missedReason
+         * The result is true if the call was user missed, false if the call was automatically
+         * rejected by system.
+         *
+         * @hide
+         */
+        public static boolean isUserMissed(long missedReason) {
+            return missedReason >= (USER_MISSED_NO_ANSWER);
+        }
     }
 }
diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java
index 000cb2a..4d67d46 100644
--- a/core/java/android/provider/DeviceConfig.java
+++ b/core/java/android/provider/DeviceConfig.java
@@ -218,6 +218,15 @@
     public static final String NAMESPACE_PACKAGE_MANAGER_SERVICE = "package_manager_service";
 
     /**
+     * Namespace for features related to the Profcollect native Service.
+     * These features are applied at reboot.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String NAMESPACE_PROFCOLLECT_NATIVE_BOOT = "profcollect_native_boot";
+
+    /**
      * Namespace for Rollback flags that are applied immediately.
      *
      * @hide
diff --git a/core/java/android/timezone/TzDataSetVersion.java b/core/java/android/timezone/TzDataSetVersion.java
index e1fb932..52e1e58 100644
--- a/core/java/android/timezone/TzDataSetVersion.java
+++ b/core/java/android/timezone/TzDataSetVersion.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 
+import com.android.i18n.timezone.TimeZoneDataFiles;
 import com.android.internal.annotations.VisibleForTesting;
 
 import java.io.IOException;
@@ -75,8 +76,7 @@
     @NonNull
     public static TzDataSetVersion read() throws IOException, TzDataSetException {
         try {
-            return new TzDataSetVersion(
-                    com.android.i18n.timezone.TzDataSetVersion.readTimeZoneModuleVersion());
+            return new TzDataSetVersion(TimeZoneDataFiles.readTimeZoneModuleVersion());
         } catch (com.android.i18n.timezone.TzDataSetVersion.TzDataSetException e) {
             throw new TzDataSetException(e.getMessage(), e);
         }
diff --git a/core/java/android/uwb/AngleMeasurement.java b/core/java/android/uwb/AngleMeasurement.java
index c3e2ecc..33bc121 100644
--- a/core/java/android/uwb/AngleMeasurement.java
+++ b/core/java/android/uwb/AngleMeasurement.java
@@ -17,6 +17,10 @@
 package android.uwb;
 
 import android.annotation.FloatRange;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Objects;
 
 /**
  * Angle measurement
@@ -26,7 +30,7 @@
  *
  * @hide
  */
-public final class AngleMeasurement {
+public final class AngleMeasurement implements Parcelable {
     private final double mRadians;
     private final double mErrorRadians;
     private final double mConfidenceLevel;
@@ -39,7 +43,7 @@
 
     /**
      * Angle measurement in radians
-    *
+     *
      * @return angle in radians
      */
     @FloatRange(from = -Math.PI, to = +Math.PI)
@@ -74,6 +78,61 @@
     }
 
     /**
+     * @hide
+    */
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+
+        if (obj instanceof AngleMeasurement) {
+            AngleMeasurement other = (AngleMeasurement) obj;
+            return mRadians == other.getRadians()
+                    && mErrorRadians == other.getErrorRadians()
+                    && mConfidenceLevel == other.getConfidenceLevel();
+        }
+        return false;
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public int hashCode() {
+        return Objects.hash(mRadians, mErrorRadians, mConfidenceLevel);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeDouble(mRadians);
+        dest.writeDouble(mErrorRadians);
+        dest.writeDouble(mConfidenceLevel);
+    }
+
+    public static final @android.annotation.NonNull Creator<AngleMeasurement> CREATOR =
+            new Creator<AngleMeasurement>() {
+                @Override
+                public AngleMeasurement createFromParcel(Parcel in) {
+                    Builder builder = new Builder();
+                    builder.setRadians(in.readDouble());
+                    builder.setErrorRadians(in.readDouble());
+                    builder.setConfidenceLevel(in.readDouble());
+                    return builder.build();
+                }
+
+                @Override
+                public AngleMeasurement[] newArray(int size) {
+                    return new AngleMeasurement[size];
+                }
+    };
+
+    /**
      * Builder class for {@link AngleMeasurement}.
      */
     public static final class Builder {
diff --git a/core/java/android/uwb/AngleOfArrivalMeasurement.java b/core/java/android/uwb/AngleOfArrivalMeasurement.java
index a7b5eae..cd5af69 100644
--- a/core/java/android/uwb/AngleOfArrivalMeasurement.java
+++ b/core/java/android/uwb/AngleOfArrivalMeasurement.java
@@ -18,13 +18,17 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Objects;
 
 /**
  * Represents an angle of arrival measurement between two devices using Ultra Wideband
  *
  * @hide
  */
-public final class AngleOfArrivalMeasurement {
+public final class AngleOfArrivalMeasurement implements Parcelable {
     private final AngleMeasurement mAzimuthAngleMeasurement;
     private final AngleMeasurement mAltitudeAngleMeasurement;
 
@@ -71,6 +75,63 @@
     }
 
     /**
+     * @hide
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+
+        if (obj instanceof AngleOfArrivalMeasurement) {
+            AngleOfArrivalMeasurement other = (AngleOfArrivalMeasurement) obj;
+            return mAzimuthAngleMeasurement.equals(other.getAzimuth())
+                    && mAltitudeAngleMeasurement.equals(other.getAltitude());
+        }
+        return false;
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public int hashCode() {
+        return Objects.hash(mAzimuthAngleMeasurement, mAltitudeAngleMeasurement);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeParcelable(mAzimuthAngleMeasurement, flags);
+        dest.writeParcelable(mAltitudeAngleMeasurement, flags);
+    }
+
+    public static final @android.annotation.NonNull Creator<AngleOfArrivalMeasurement> CREATOR =
+            new Creator<AngleOfArrivalMeasurement>() {
+                @Override
+                public AngleOfArrivalMeasurement createFromParcel(Parcel in) {
+                    Builder builder = new Builder();
+
+                    builder.setAzimuthAngleMeasurement(
+                            in.readParcelable(AngleMeasurement.class.getClassLoader()));
+
+                    builder.setAltitudeAngleMeasurement(
+                            in.readParcelable(AngleMeasurement.class.getClassLoader()));
+
+                    return builder.build();
+                }
+
+                @Override
+                public AngleOfArrivalMeasurement[] newArray(int size) {
+                    return new AngleOfArrivalMeasurement[size];
+                }
+            };
+
+    /**
      * Builder class for {@link AngleOfArrivalMeasurement}.
      */
     public static final class Builder {
diff --git a/core/java/android/uwb/DistanceMeasurement.java b/core/java/android/uwb/DistanceMeasurement.java
index 4cd5d83..c959840 100644
--- a/core/java/android/uwb/DistanceMeasurement.java
+++ b/core/java/android/uwb/DistanceMeasurement.java
@@ -17,6 +17,11 @@
 package android.uwb;
 
 import android.annotation.FloatRange;
+import android.annotation.Nullable;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Objects;
 
 /**
  * A data point for the distance measurement
@@ -26,7 +31,7 @@
  *
  * @hide
  */
-public final class DistanceMeasurement {
+public final class DistanceMeasurement implements Parcelable {
     private final double mMeters;
     private final double mErrorMeters;
     private final double mConfidenceLevel;
@@ -70,6 +75,61 @@
     }
 
     /**
+     * @hide
+     */
+    @Override
+    public boolean equals(@Nullable Object obj) {
+        if (this == obj) {
+            return true;
+        }
+
+        if (obj instanceof DistanceMeasurement) {
+            DistanceMeasurement other = (DistanceMeasurement) obj;
+            return mMeters == other.getMeters()
+                    && mErrorMeters == other.getErrorMeters()
+                    && mConfidenceLevel == other.getConfidenceLevel();
+        }
+        return false;
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public int hashCode() {
+        return Objects.hash(mMeters, mErrorMeters, mConfidenceLevel);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeDouble(mMeters);
+        dest.writeDouble(mErrorMeters);
+        dest.writeDouble(mConfidenceLevel);
+    }
+
+    public static final @android.annotation.NonNull Creator<DistanceMeasurement> CREATOR =
+            new Creator<DistanceMeasurement>() {
+                @Override
+                public DistanceMeasurement createFromParcel(Parcel in) {
+                    Builder builder = new Builder();
+                    builder.setMeters(in.readDouble());
+                    builder.setErrorMeters(in.readDouble());
+                    builder.setConfidenceLevel(in.readDouble());
+                    return builder.build();
+                }
+
+                @Override
+                public DistanceMeasurement[] newArray(int size) {
+                    return new DistanceMeasurement[size];
+                }
+    };
+
+    /**
      * Builder to get a {@link DistanceMeasurement} object.
      */
     public static final class Builder {
diff --git a/core/java/android/uwb/RangingMeasurement.java b/core/java/android/uwb/RangingMeasurement.java
index 33a34e3..f1c3162 100644
--- a/core/java/android/uwb/RangingMeasurement.java
+++ b/core/java/android/uwb/RangingMeasurement.java
@@ -20,17 +20,20 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SuppressLint;
+import android.os.Parcel;
+import android.os.Parcelable;
 import android.os.SystemClock;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
 
 /**
  * Representation of a ranging measurement between the local device and a remote device
  *
  * @hide
  */
-public final class RangingMeasurement {
+public final class RangingMeasurement implements Parcelable {
     private final UwbAddress mRemoteDeviceAddress;
     private final @Status int mStatus;
     private final long mElapsedRealtimeNanos;
@@ -128,6 +131,71 @@
     }
 
     /**
+     * @hide
+     */
+    @Override
+    public boolean equals(@Nullable Object obj) {
+        if (this == obj) {
+            return true;
+        }
+
+        if (obj instanceof RangingMeasurement) {
+            RangingMeasurement other = (RangingMeasurement) obj;
+            return mRemoteDeviceAddress.equals(other.getRemoteDeviceAddress())
+                    && mStatus == other.getStatus()
+                    && mElapsedRealtimeNanos == other.getElapsedRealtimeNanos()
+                    && mDistanceMeasurement.equals(other.getDistance())
+                    && mAngleOfArrivalMeasurement.equals(other.getAngleOfArrival());
+        }
+        return false;
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public int hashCode() {
+        return Objects.hash(mRemoteDeviceAddress, mStatus, mElapsedRealtimeNanos,
+                mDistanceMeasurement, mAngleOfArrivalMeasurement);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeParcelable(mRemoteDeviceAddress, flags);
+        dest.writeInt(mStatus);
+        dest.writeLong(mElapsedRealtimeNanos);
+        dest.writeParcelable(mDistanceMeasurement, flags);
+        dest.writeParcelable(mAngleOfArrivalMeasurement, flags);
+    }
+
+    public static final @android.annotation.NonNull Creator<RangingMeasurement> CREATOR =
+            new Creator<RangingMeasurement>() {
+                @Override
+                public RangingMeasurement createFromParcel(Parcel in) {
+                    Builder builder = new Builder();
+                    builder.setRemoteDeviceAddress(
+                            in.readParcelable(UwbAddress.class.getClassLoader()));
+                    builder.setStatus(in.readInt());
+                    builder.setElapsedRealtimeNanos(in.readLong());
+                    builder.setDistanceMeasurement(
+                            in.readParcelable(DistanceMeasurement.class.getClassLoader()));
+                    builder.setAngleOfArrivalMeasurement(
+                            in.readParcelable(AngleOfArrivalMeasurement.class.getClassLoader()));
+                    return builder.build();
+                }
+
+                @Override
+                public RangingMeasurement[] newArray(int size) {
+                    return new RangingMeasurement[size];
+                }
+    };
+
+    /**
      * Builder for a {@link RangingMeasurement} object.
      */
     public static final class Builder {
diff --git a/core/java/android/uwb/RangingParams.java b/core/java/android/uwb/RangingParams.java
index a50de3e6..f23d9ed 100644
--- a/core/java/android/uwb/RangingParams.java
+++ b/core/java/android/uwb/RangingParams.java
@@ -19,15 +19,18 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.os.Parcel;
+import android.os.Parcelable;
 import android.os.PersistableBundle;
-import android.util.Duration;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.time.Duration;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Objects;
 import java.util.Set;
 
 /**
@@ -36,7 +39,7 @@
  *
  *  @hide
  */
-public final class RangingParams {
+public final class RangingParams implements Parcelable {
     private final boolean mIsInitiator;
     private final boolean mIsController;
     private final Duration mSamplePeriod;
@@ -200,6 +203,99 @@
     }
 
     /**
+     * @hide
+     */
+    @Override
+    public boolean equals(@Nullable Object obj) {
+        if (this == obj) {
+            return true;
+        }
+
+        if (obj instanceof RangingParams) {
+            RangingParams other = (RangingParams) obj;
+
+            return mIsInitiator == other.mIsInitiator
+                    && mIsController == other.mIsController
+                    && mSamplePeriod.equals(other.mSamplePeriod)
+                    && mLocalDeviceAddress.equals(other.mLocalDeviceAddress)
+                    && mRemoteDeviceAddresses.equals(other.mRemoteDeviceAddresses)
+                    && mChannelNumber == other.mChannelNumber
+                    && mTransmitPreambleCodeIndex == other.mTransmitPreambleCodeIndex
+                    && mReceivePreambleCodeIndex == other.mReceivePreambleCodeIndex
+                    && mStsPhyPacketType == other.mStsPhyPacketType
+                    && mSpecificationParameters.size() == other.mSpecificationParameters.size()
+                    && mSpecificationParameters.kindofEquals(other.mSpecificationParameters);
+        }
+        return false;
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public int hashCode() {
+        return Objects.hash(mIsInitiator, mIsController, mSamplePeriod, mLocalDeviceAddress,
+                mRemoteDeviceAddresses, mChannelNumber, mTransmitPreambleCodeIndex,
+                mReceivePreambleCodeIndex, mStsPhyPacketType, mSpecificationParameters);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeBoolean(mIsInitiator);
+        dest.writeBoolean(mIsController);
+        dest.writeLong(mSamplePeriod.getSeconds());
+        dest.writeInt(mSamplePeriod.getNano());
+        dest.writeParcelable(mLocalDeviceAddress, flags);
+
+        UwbAddress[] remoteAddresses = new UwbAddress[mRemoteDeviceAddresses.size()];
+        mRemoteDeviceAddresses.toArray(remoteAddresses);
+        dest.writeParcelableArray(remoteAddresses, flags);
+
+        dest.writeInt(mChannelNumber);
+        dest.writeInt(mTransmitPreambleCodeIndex);
+        dest.writeInt(mReceivePreambleCodeIndex);
+        dest.writeInt(mStsPhyPacketType);
+        dest.writePersistableBundle(mSpecificationParameters);
+    }
+
+    public static final @android.annotation.NonNull Creator<RangingParams> CREATOR =
+            new Creator<RangingParams>() {
+                @Override
+                public RangingParams createFromParcel(Parcel in) {
+                    Builder builder = new Builder();
+                    builder.setIsInitiator(in.readBoolean());
+                    builder.setIsController(in.readBoolean());
+                    builder.setSamplePeriod(Duration.ofSeconds(in.readLong(), in.readInt()));
+                    builder.setLocalDeviceAddress(
+                            in.readParcelable(UwbAddress.class.getClassLoader()));
+
+                    UwbAddress[] remoteAddresses =
+                            in.readParcelableArray(null, UwbAddress.class);
+                    for (UwbAddress remoteAddress : remoteAddresses) {
+                        builder.addRemoteDeviceAddress(remoteAddress);
+                    }
+
+                    builder.setChannelNumber(in.readInt());
+                    builder.setTransmitPreambleCodeIndex(in.readInt());
+                    builder.setReceivePreambleCodeIndex(in.readInt());
+                    builder.setStsPhPacketType(in.readInt());
+                    builder.setSpecificationParameters(in.readPersistableBundle());
+
+                    return builder.build();
+                }
+
+                @Override
+                public RangingParams[] newArray(int size) {
+                    return new RangingParams[size];
+                }
+    };
+
+    /**
      * Builder class for {@link RangingParams}.
      */
     public static final class Builder {
diff --git a/core/java/android/uwb/RangingReport.java b/core/java/android/uwb/RangingReport.java
index 5aca12a..45180bf 100644
--- a/core/java/android/uwb/RangingReport.java
+++ b/core/java/android/uwb/RangingReport.java
@@ -17,16 +17,20 @@
 package android.uwb;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Parcel;
+import android.os.Parcelable;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Objects;
 
 /**
  * This class contains the UWB ranging data
  *
  * @hide
  */
-public final class RangingReport {
+public final class RangingReport implements Parcelable {
     private final List<RangingMeasurement> mRangingMeasurements;
 
     private RangingReport(@NonNull List<RangingMeasurement> rangingMeasurements) {
@@ -49,6 +53,56 @@
     }
 
     /**
+     * @hide
+     */
+    @Override
+    public boolean equals(@Nullable Object obj) {
+        if (this == obj) {
+            return true;
+        }
+
+        if (obj instanceof RangingReport) {
+            RangingReport other = (RangingReport) obj;
+            return mRangingMeasurements.equals(other.getMeasurements());
+        }
+
+        return false;
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public int hashCode() {
+        return Objects.hash(mRangingMeasurements);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeTypedList(mRangingMeasurements);
+    }
+
+    public static final @android.annotation.NonNull Creator<RangingReport> CREATOR =
+            new Creator<RangingReport>() {
+                @Override
+                public RangingReport createFromParcel(Parcel in) {
+                    Builder builder = new Builder();
+                    builder.addMeasurements(in.createTypedArrayList(RangingMeasurement.CREATOR));
+                    return builder.build();
+                }
+
+                @Override
+                public RangingReport[] newArray(int size) {
+                    return new RangingReport[size];
+                }
+    };
+
+    /**
      * Builder for {@link RangingReport} object
      */
     public static final class Builder {
diff --git a/core/java/android/uwb/TEST_MAPPING b/core/java/android/uwb/TEST_MAPPING
new file mode 100644
index 0000000..9e50bd6
--- /dev/null
+++ b/core/java/android/uwb/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "presubmit": [
+    {
+      "name": "UwbManagerTests"
+    }
+  ]
+}
\ No newline at end of file
diff --git a/core/java/android/uwb/UwbAddress.java b/core/java/android/uwb/UwbAddress.java
index 48fcb10e..828324c 100644
--- a/core/java/android/uwb/UwbAddress.java
+++ b/core/java/android/uwb/UwbAddress.java
@@ -18,16 +18,26 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Arrays;
 
 /**
  * A class representing a UWB address
  *
  * @hide
  */
-public final class UwbAddress {
+public final class UwbAddress implements Parcelable {
     public static final int SHORT_ADDRESS_BYTE_LENGTH = 2;
     public static final int EXTENDED_ADDRESS_BYTE_LENGTH = 8;
 
+    private final byte[] mAddressBytes;
+
+    private UwbAddress(byte[] address) {
+        mAddressBytes = address;
+    }
+
     /**
      * Create a {@link UwbAddress} from a byte array.
      *
@@ -37,12 +47,16 @@
      *
      * @param address a byte array to convert to a {@link UwbAddress}
      * @return a {@link UwbAddress} created from the input byte array
-     * @throw IllegableArumentException when the length is not one of
+     * @throws IllegalArgumentException when the length is not one of
      *       {@link #SHORT_ADDRESS_BYTE_LENGTH} or {@link #EXTENDED_ADDRESS_BYTE_LENGTH} bytes
      */
     @NonNull
-    public static UwbAddress fromBytes(byte[] address) throws IllegalArgumentException {
-        throw new UnsupportedOperationException();
+    public static UwbAddress fromBytes(@NonNull byte[] address) throws IllegalArgumentException {
+        if (address.length != SHORT_ADDRESS_BYTE_LENGTH
+                && address.length != EXTENDED_ADDRESS_BYTE_LENGTH) {
+            throw new IllegalArgumentException("Invalid UwbAddress length " + address.length);
+        }
+        return new UwbAddress(address);
     }
 
     /**
@@ -52,7 +66,7 @@
      */
     @NonNull
     public byte[] toBytes() {
-        throw new UnsupportedOperationException();
+        return mAddressBytes;
     }
 
     /**
@@ -61,22 +75,55 @@
      * {@link #EXTENDED_ADDRESS_BYTE_LENGTH}.
      */
     public int size() {
-        throw new UnsupportedOperationException();
+        return mAddressBytes.length;
     }
 
     @NonNull
     @Override
     public String toString() {
-        throw new UnsupportedOperationException();
+        StringBuilder builder = new StringBuilder("0x");
+        for (byte addressByte : mAddressBytes) {
+            builder.append(String.format("%02X", addressByte));
+        }
+        return builder.toString();
     }
 
     @Override
     public boolean equals(@Nullable Object obj) {
-        throw new UnsupportedOperationException();
+        if (obj instanceof UwbAddress) {
+            return Arrays.equals(mAddressBytes, ((UwbAddress) obj).toBytes());
+        }
+        return false;
     }
 
     @Override
     public int hashCode() {
-        throw new UnsupportedOperationException();
+        return Arrays.hashCode(mAddressBytes);
     }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(mAddressBytes.length);
+        dest.writeByteArray(mAddressBytes);
+    }
+
+    public static final @android.annotation.NonNull Creator<UwbAddress> CREATOR =
+            new Creator<UwbAddress>() {
+                @Override
+                public UwbAddress createFromParcel(Parcel in) {
+                    byte[] address = new byte[in.readInt()];
+                    in.readByteArray(address);
+                    return UwbAddress.fromBytes(address);
+                }
+
+                @Override
+                public UwbAddress[] newArray(int size) {
+                    return new UwbAddress[size];
+                }
+    };
 }
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index c383bc7..985829f 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -1134,15 +1134,14 @@
         if (invokeCallback) {
             control.cancel();
         }
+        boolean stateChanged = false;
         for (int i = mRunningAnimations.size() - 1; i >= 0; i--) {
             RunningAnimation runningAnimation = mRunningAnimations.get(i);
             if (runningAnimation.runner == control) {
                 mRunningAnimations.remove(i);
                 ArraySet<Integer> types = toInternalType(control.getTypes());
                 for (int j = types.size() - 1; j >= 0; j--) {
-                    if (getSourceConsumer(types.valueAt(j)).notifyAnimationFinished()) {
-                        mHost.notifyInsetsChanged();
-                    }
+                    stateChanged |= getSourceConsumer(types.valueAt(j)).notifyAnimationFinished();
                 }
                 if (invokeCallback && runningAnimation.startDispatched) {
                     dispatchAnimationEnd(runningAnimation.runner.getAnimation());
@@ -1150,6 +1149,10 @@
                 break;
             }
         }
+        if (stateChanged) {
+            mHost.notifyInsetsChanged();
+            updateRequestedState();
+        }
     }
 
     private void applyLocalVisibilityOverride() {
diff --git a/core/proto/android/stats/tls/enums.proto b/core/proto/android/stats/tls/enums.proto
new file mode 100644
index 0000000..1777d69
--- /dev/null
+++ b/core/proto/android/stats/tls/enums.proto
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+syntax = "proto2";
+package android.stats.tls;
+
+// Keep in sync with
+// external/conscrypt/{android,platform}/src/main/java/org/conscrypt/Platform.java
+enum Protocol {
+    UNKNOWN_PROTO = 0;
+    SSL_V3 = 1;
+    TLS_V1 = 2;
+    TLS_V1_1 = 3;
+    TLS_V1_2 = 4;
+    TLS_V1_3 = 5;
+}
+
+// Cipher suites' ids are based on IANA's database:
+// https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-4
+//
+// If you add new cipher suite, make sure id is the same as in  IANA's database (see link above)
+//
+// Keep in sync with
+// external/conscrypt/{android,platform}/src/main/java/org/conscrypt/Platform.java
+enum CipherSuite {
+    UNKNOWN_CIPHER_SUITE = 0x0000;
+
+    TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA = 0xC00A;
+    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = 0xC014;
+    TLS_RSA_WITH_AES_256_CBC_SHA = 0x0035;
+    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA = 0xC009;
+    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA = 0xC013;
+    TLS_RSA_WITH_AES_128_CBC_SHA = 0x002F;
+    TLS_RSA_WITH_3DES_EDE_CBC_SHA = 0x000A;
+
+    // TLSv1.2 cipher suites
+    TLS_RSA_WITH_AES_128_GCM_SHA256 = 0x009C;
+    TLS_RSA_WITH_AES_256_GCM_SHA384 = 0x009D;
+    TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0xC02F;
+    TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 = 0xC030;
+    TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 = 0xC02B;
+    TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 = 0xC02C;
+    TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCA9;
+    TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCA8;
+
+    // Pre-Shared Key (PSK) cipher suites
+    TLS_PSK_WITH_AES_128_CBC_SHA = 0x008C;
+    TLS_PSK_WITH_AES_256_CBC_SHA = 0x008D;
+    TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA = 0xC035;
+    TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA = 0xC036;
+    TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 = 0xCCAC;
+
+    // TLS 1.3 cipher suites
+    TLS_AES_128_GCM_SHA256 = 0x1301;
+    TLS_AES_256_GCM_SHA384 = 0x1302;
+    TLS_CHACHA20_POLY1305_SHA256 = 0x1303;
+}
\ No newline at end of file
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 781bb2a..2b2bf8d 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1671,7 +1671,7 @@
          to be explicitly declared in this resource to be enabled.
              * SDK level 28 makes the following algorithms mandatory : "cbc(aes)", "hmac(md5)",
                "hmac(sha1)", "hmac(sha256)", "hmac(sha384)", "hmac(sha512)", "rfc4106(gcm(aes))"
-             * SDK level 30 makes the following algorithms mandatory : "rfc3686(ctr(aes))",
+             * SDK level 31 makes the following algorithms mandatory : "rfc3686(ctr(aes))",
                "xcbc(aes)", "rfc7539esp(chacha20,poly1305)"
      -->
     <string-array name="config_optionalIpSecAlgorithms" translatable="false">
@@ -2792,6 +2792,7 @@
         <item>power</item>
         <item>restart</item>
         <item>logout</item>
+        <item>screenshot</item>
         <item>bugreport</item>
     </string-array>
 
@@ -3506,6 +3507,7 @@
      mode -->
     <string-array translatable="false" name="config_priorityOnlyDndExemptPackages">
         <item>com.android.dialer</item>
+        <item>com.android.server.telecom</item>
         <item>com.android.systemui</item>
         <item>android</item>
     </string-array>
diff --git a/core/tests/coretests/src/android/view/InsetsControllerTest.java b/core/tests/coretests/src/android/view/InsetsControllerTest.java
index 801cd4d..48695aa 100644
--- a/core/tests/coretests/src/android/view/InsetsControllerTest.java
+++ b/core/tests/coretests/src/android/view/InsetsControllerTest.java
@@ -27,6 +27,7 @@
 import static android.view.InsetsState.ITYPE_STATUS_BAR;
 import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL;
 import static android.view.WindowInsets.Type.ime;
+import static android.view.WindowInsets.Type.navigationBars;
 import static android.view.WindowInsets.Type.statusBars;
 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
 
@@ -742,6 +743,20 @@
             mController.onControlsChanged(createSingletonControl(ITYPE_IME));
             assertEquals(newState.getSource(ITYPE_IME),
                     mTestHost.getModifiedState().peekSource(ITYPE_IME));
+
+            // The modified frames cannot be updated if there is an animation.
+            mController.onControlsChanged(createSingletonControl(ITYPE_NAVIGATION_BAR));
+            mController.hide(navigationBars());
+            newState = new InsetsState(mController.getState(), true /* copySource */);
+            newState.getSource(ITYPE_NAVIGATION_BAR).getFrame().top--;
+            mController.onStateChanged(newState);
+            assertNotEquals(newState.getSource(ITYPE_NAVIGATION_BAR),
+                    mTestHost.getModifiedState().peekSource(ITYPE_NAVIGATION_BAR));
+
+            // The modified frames can be updated while the animation is done.
+            mController.cancelExistingAnimations();
+            assertEquals(newState.getSource(ITYPE_NAVIGATION_BAR),
+                    mTestHost.getModifiedState().peekSource(ITYPE_NAVIGATION_BAR));
         });
     }
 
diff --git a/core/tests/uwbtests/Android.bp b/core/tests/uwbtests/Android.bp
new file mode 100644
index 0000000..c41c346
--- /dev/null
+++ b/core/tests/uwbtests/Android.bp
@@ -0,0 +1,28 @@
+// Copyright 2020 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.
+
+android_test {
+    name: "UwbManagerTests",
+    static_libs: [
+        "androidx.test.ext.junit",
+        "androidx.test.rules",
+    ],
+    libs: [
+        "android.test.runner",
+    ],
+    srcs: ["src/**/*.java"],
+    platform_apis: true,
+    certificate: "platform",
+    test_suites: ["device-tests"],
+}
diff --git a/core/tests/uwbtests/AndroidManifest.xml b/core/tests/uwbtests/AndroidManifest.xml
new file mode 100644
index 0000000..dc991ff
--- /dev/null
+++ b/core/tests/uwbtests/AndroidManifest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2020 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.uwb">
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <!-- This is a self-instrumenting test package. -->
+    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="android.uwb"
+                     android:label="UWB Manager Tests">
+    </instrumentation>
+
+</manifest>
+
diff --git a/core/tests/uwbtests/AndroidTest.xml b/core/tests/uwbtests/AndroidTest.xml
new file mode 100644
index 0000000..ff4b668
--- /dev/null
+++ b/core/tests/uwbtests/AndroidTest.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2020 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.
+-->
+<configuration description="Config for UWB Manager test cases">
+    <option name="test-suite-tag" value="apct"/>
+    <option name="test-suite-tag" value="apct-instrumentation"/>
+    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="UwbManagerTests.apk" />
+    </target_preparer>
+
+    <option name="test-suite-tag" value="apct"/>
+    <option name="test-tag" value="UwbManagerTests"/>
+
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.uwb" />
+        <option name="hidden-api-checks" value="false"/>
+        <option name="runner" value="androidx.test.runner.AndroidJUnitRunner"/>
+    </test>
+</configuration>
diff --git a/core/tests/uwbtests/src/android/uwb/AngleMeasurementTest.java b/core/tests/uwbtests/src/android/uwb/AngleMeasurementTest.java
new file mode 100644
index 0000000..7769c28
--- /dev/null
+++ b/core/tests/uwbtests/src/android/uwb/AngleMeasurementTest.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2020 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.uwb;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import android.os.Parcel;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Test of {@link AngleMeasurement}.
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class AngleMeasurementTest {
+    private static final double EPSILON = 0.00000000001;
+
+    @Test
+    public void testBuilder() {
+        double radians = 0.1234;
+        double errorRadians = 0.5678;
+        double confidence = 0.5;
+
+        AngleMeasurement.Builder builder = new AngleMeasurement.Builder();
+        tryBuild(builder, false);
+
+        builder.setRadians(radians);
+        tryBuild(builder, false);
+
+        builder.setErrorRadians(errorRadians);
+        tryBuild(builder, false);
+
+        builder.setConfidenceLevel(confidence);
+        AngleMeasurement measurement = tryBuild(builder, true);
+
+        assertEquals(measurement.getRadians(), radians, 0);
+        assertEquals(measurement.getErrorRadians(), errorRadians, 0);
+        assertEquals(measurement.getConfidenceLevel(), confidence, 0);
+    }
+
+    private AngleMeasurement tryBuild(AngleMeasurement.Builder builder, boolean expectSuccess) {
+        AngleMeasurement measurement = null;
+        try {
+            measurement = builder.build();
+            if (!expectSuccess) {
+                fail("Expected AngleMeasurement.Builder.build() to fail, but it succeeded");
+            }
+        } catch (IllegalStateException e) {
+            if (expectSuccess) {
+                fail("Expected AngleMeasurement.Builder.build() to succeed, but it failed");
+            }
+        }
+        return measurement;
+    }
+
+    @Test
+    public void testParcel() {
+        Parcel parcel = Parcel.obtain();
+        AngleMeasurement measurement = UwbTestUtils.getAngleMeasurement();
+        measurement.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        AngleMeasurement fromParcel = AngleMeasurement.CREATOR.createFromParcel(parcel);
+        assertEquals(measurement, fromParcel);
+    }
+}
diff --git a/core/tests/uwbtests/src/android/uwb/AngleOfArrivalMeasurementTest.java b/core/tests/uwbtests/src/android/uwb/AngleOfArrivalMeasurementTest.java
new file mode 100644
index 0000000..077b08f
--- /dev/null
+++ b/core/tests/uwbtests/src/android/uwb/AngleOfArrivalMeasurementTest.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2020 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.uwb;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import android.os.Parcel;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Test of {@link AngleOfArrivalMeasurement}.
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class AngleOfArrivalMeasurementTest {
+
+    @Test
+    public void testBuilder() {
+        AngleMeasurement azimuth = UwbTestUtils.getAngleMeasurement();
+        AngleMeasurement altitude = UwbTestUtils.getAngleMeasurement();
+
+        AngleOfArrivalMeasurement.Builder builder = new AngleOfArrivalMeasurement.Builder();
+        tryBuild(builder, false);
+
+        builder.setAltitudeAngleMeasurement(altitude);
+        tryBuild(builder, false);
+
+        builder.setAzimuthAngleMeasurement(azimuth);
+        AngleOfArrivalMeasurement measurement = tryBuild(builder, true);
+
+        assertEquals(azimuth, measurement.getAzimuth());
+        assertEquals(altitude, measurement.getAltitude());
+    }
+
+    private AngleMeasurement getAngleMeasurement(double radian, double error, double confidence) {
+        return new AngleMeasurement.Builder()
+                .setRadians(radian)
+                .setErrorRadians(error)
+                .setConfidenceLevel(confidence)
+                .build();
+    }
+
+    private AngleOfArrivalMeasurement tryBuild(AngleOfArrivalMeasurement.Builder builder,
+            boolean expectSuccess) {
+        AngleOfArrivalMeasurement measurement = null;
+        try {
+            measurement = builder.build();
+            if (!expectSuccess) {
+                fail("Expected AngleOfArrivalMeasurement.Builder.build() to fail");
+            }
+        } catch (IllegalStateException e) {
+            if (expectSuccess) {
+                fail("Expected AngleOfArrivalMeasurement.Builder.build() to succeed");
+            }
+        }
+        return measurement;
+    }
+
+    @Test
+    public void testParcel() {
+        Parcel parcel = Parcel.obtain();
+        AngleOfArrivalMeasurement measurement = UwbTestUtils.getAngleOfArrivalMeasurement();
+        measurement.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        AngleOfArrivalMeasurement fromParcel =
+                AngleOfArrivalMeasurement.CREATOR.createFromParcel(parcel);
+        assertEquals(measurement, fromParcel);
+    }
+}
diff --git a/core/tests/uwbtests/src/android/uwb/DistanceMeasurementTest.java b/core/tests/uwbtests/src/android/uwb/DistanceMeasurementTest.java
new file mode 100644
index 0000000..439c884
--- /dev/null
+++ b/core/tests/uwbtests/src/android/uwb/DistanceMeasurementTest.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2020 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.uwb;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import android.os.Parcel;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Test of {@link DistanceMeasurement}.
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class DistanceMeasurementTest {
+    private static final double EPSILON = 0.00000000001;
+
+    @Test
+    public void testBuilder() {
+        double meters = 0.12;
+        double error = 0.54;
+        double confidence = 0.99;
+
+        DistanceMeasurement.Builder builder = new DistanceMeasurement.Builder();
+        tryBuild(builder, false);
+
+        builder.setMeters(meters);
+        tryBuild(builder, false);
+
+        builder.setErrorMeters(error);
+        tryBuild(builder, false);
+
+        builder.setConfidenceLevel(confidence);
+        DistanceMeasurement measurement = tryBuild(builder, true);
+
+        assertEquals(meters, measurement.getMeters(), 0);
+        assertEquals(error, measurement.getErrorMeters(), 0);
+        assertEquals(confidence, measurement.getConfidenceLevel(), 0);
+    }
+
+    private DistanceMeasurement tryBuild(DistanceMeasurement.Builder builder,
+            boolean expectSuccess) {
+        DistanceMeasurement measurement = null;
+        try {
+            measurement = builder.build();
+            if (!expectSuccess) {
+                fail("Expected DistanceMeasurement.Builder.build() to fail");
+            }
+        } catch (IllegalStateException e) {
+            if (expectSuccess) {
+                fail("Expected DistanceMeasurement.Builder.build() to succeed");
+            }
+        }
+        return measurement;
+    }
+
+    @Test
+    public void testParcel() {
+        Parcel parcel = Parcel.obtain();
+        DistanceMeasurement measurement = UwbTestUtils.getDistanceMeasurement();
+        measurement.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        DistanceMeasurement fromParcel =
+                DistanceMeasurement.CREATOR.createFromParcel(parcel);
+        assertEquals(measurement, fromParcel);
+    }
+}
diff --git a/core/tests/uwbtests/src/android/uwb/RangingMeasurementTest.java b/core/tests/uwbtests/src/android/uwb/RangingMeasurementTest.java
new file mode 100644
index 0000000..a7559d8
--- /dev/null
+++ b/core/tests/uwbtests/src/android/uwb/RangingMeasurementTest.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2020 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.uwb;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import android.os.Parcel;
+import android.os.SystemClock;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Test of {@link RangingMeasurement}.
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class RangingMeasurementTest {
+
+    @Test
+    public void testBuilder() {
+        int status = RangingMeasurement.RANGING_STATUS_SUCCESS;
+        UwbAddress address = UwbTestUtils.getUwbAddress(false);
+        long time = SystemClock.elapsedRealtimeNanos();
+        AngleOfArrivalMeasurement angleMeasurement = UwbTestUtils.getAngleOfArrivalMeasurement();
+        DistanceMeasurement distanceMeasurement = UwbTestUtils.getDistanceMeasurement();
+
+        RangingMeasurement.Builder builder = new RangingMeasurement.Builder();
+
+        builder.setStatus(status);
+        tryBuild(builder, false);
+
+        builder.setElapsedRealtimeNanos(time);
+        tryBuild(builder, false);
+
+        builder.setAngleOfArrivalMeasurement(angleMeasurement);
+        tryBuild(builder, false);
+
+        builder.setDistanceMeasurement(distanceMeasurement);
+        tryBuild(builder, false);
+
+        builder.setRemoteDeviceAddress(address);
+        RangingMeasurement measurement = tryBuild(builder, true);
+
+        assertEquals(status, measurement.getStatus());
+        assertEquals(address, measurement.getRemoteDeviceAddress());
+        assertEquals(time, measurement.getElapsedRealtimeNanos());
+        assertEquals(angleMeasurement, measurement.getAngleOfArrival());
+        assertEquals(distanceMeasurement, measurement.getDistance());
+    }
+
+    private RangingMeasurement tryBuild(RangingMeasurement.Builder builder,
+            boolean expectSuccess) {
+        RangingMeasurement measurement = null;
+        try {
+            measurement = builder.build();
+            if (!expectSuccess) {
+                fail("Expected RangingMeasurement.Builder.build() to fail");
+            }
+        } catch (IllegalStateException e) {
+            if (expectSuccess) {
+                fail("Expected DistanceMeasurement.Builder.build() to succeed");
+            }
+        }
+        return measurement;
+    }
+
+    @Test
+    public void testParcel() {
+        Parcel parcel = Parcel.obtain();
+        RangingMeasurement measurement = UwbTestUtils.getRangingMeasurement();
+        measurement.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        RangingMeasurement fromParcel = RangingMeasurement.CREATOR.createFromParcel(parcel);
+        assertEquals(measurement, fromParcel);
+    }
+}
diff --git a/core/tests/uwbtests/src/android/uwb/RangingParamsTest.java b/core/tests/uwbtests/src/android/uwb/RangingParamsTest.java
new file mode 100644
index 0000000..8095c99
--- /dev/null
+++ b/core/tests/uwbtests/src/android/uwb/RangingParamsTest.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2020 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.uwb;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.os.Parcel;
+import android.os.PersistableBundle;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.time.Duration;
+
+/**
+ * Test of {@link RangingParams}.
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class RangingParamsTest {
+
+    @Test
+    public void testParams_Build() {
+        UwbAddress local = UwbAddress.fromBytes(new byte[] {(byte) 0xA0, (byte) 0x57});
+        UwbAddress remote = UwbAddress.fromBytes(new byte[] {(byte) 0x4D, (byte) 0x8C});
+        int channel = 9;
+        int rxPreamble = 16;
+        int txPreamble = 21;
+        boolean isController = true;
+        boolean isInitiator = false;
+        @RangingParams.StsPhyPacketType int stsPhyType = RangingParams.STS_PHY_PACKET_TYPE_SP2;
+        Duration samplePeriod = Duration.ofSeconds(1, 234);
+        PersistableBundle specParams = new PersistableBundle();
+        specParams.putString("protocol", "some_protocol");
+
+        RangingParams params = new RangingParams.Builder()
+                .setChannelNumber(channel)
+                .setReceivePreambleCodeIndex(rxPreamble)
+                .setTransmitPreambleCodeIndex(txPreamble)
+                .setLocalDeviceAddress(local)
+                .addRemoteDeviceAddress(remote)
+                .setIsController(isController)
+                .setIsInitiator(isInitiator)
+                .setSamplePeriod(samplePeriod)
+                .setStsPhPacketType(stsPhyType)
+                .setSpecificationParameters(specParams)
+                .build();
+
+        assertEquals(params.getLocalDeviceAddress(), local);
+        assertEquals(params.getRemoteDeviceAddresses().size(), 1);
+        assertEquals(params.getRemoteDeviceAddresses().get(0), remote);
+        assertEquals(params.getChannelNumber(), channel);
+        assertEquals(params.isController(), isController);
+        assertEquals(params.isInitiator(), isInitiator);
+        assertEquals(params.getRxPreambleIndex(), rxPreamble);
+        assertEquals(params.getTxPreambleIndex(), txPreamble);
+        assertEquals(params.getStsPhyPacketType(), stsPhyType);
+        assertEquals(params.getSamplingPeriod(), samplePeriod);
+        assertTrue(params.getSpecificationParameters().kindofEquals(specParams));
+    }
+
+    @Test
+    public void testParcel() {
+        Parcel parcel = Parcel.obtain();
+        RangingParams params = new RangingParams.Builder()
+                .setChannelNumber(9)
+                .setReceivePreambleCodeIndex(16)
+                .setTransmitPreambleCodeIndex(21)
+                .setLocalDeviceAddress(UwbTestUtils.getUwbAddress(false))
+                .addRemoteDeviceAddress(UwbTestUtils.getUwbAddress(true))
+                .setIsController(false)
+                .setIsInitiator(true)
+                .setSamplePeriod(Duration.ofSeconds(2))
+                .setStsPhPacketType(RangingParams.STS_PHY_PACKET_TYPE_SP1)
+                .build();
+        params.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        RangingParams fromParcel = RangingParams.CREATOR.createFromParcel(parcel);
+        assertEquals(params, fromParcel);
+    }
+}
diff --git a/core/tests/uwbtests/src/android/uwb/RangingReportTest.java b/core/tests/uwbtests/src/android/uwb/RangingReportTest.java
new file mode 100644
index 0000000..64c48ba
--- /dev/null
+++ b/core/tests/uwbtests/src/android/uwb/RangingReportTest.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2020 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.uwb;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import android.os.Parcel;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.List;
+
+/**
+ * Test of {@link RangingReport}.
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class RangingReportTest {
+
+    @Test
+    public void testBuilder() {
+        List<RangingMeasurement> measurements = UwbTestUtils.getRangingMeasurements(5);
+
+        RangingReport.Builder builder = new RangingReport.Builder();
+        builder.addMeasurements(measurements);
+        RangingReport report = tryBuild(builder, true);
+        verifyMeasurementsEqual(measurements, report.getMeasurements());
+
+
+        builder = new RangingReport.Builder();
+        for (RangingMeasurement measurement : measurements) {
+            builder.addMeasurement(measurement);
+        }
+        report = tryBuild(builder, true);
+        verifyMeasurementsEqual(measurements, report.getMeasurements());
+    }
+
+    private void verifyMeasurementsEqual(List<RangingMeasurement> expected,
+            List<RangingMeasurement> actual) {
+        assertEquals(expected.size(), actual.size());
+        for (int i = 0; i < expected.size(); i++) {
+            assertEquals(expected.get(i), actual.get(i));
+        }
+    }
+
+    private RangingReport tryBuild(RangingReport.Builder builder,
+            boolean expectSuccess) {
+        RangingReport report = null;
+        try {
+            report = builder.build();
+            if (!expectSuccess) {
+                fail("Expected RangingReport.Builder.build() to fail");
+            }
+        } catch (IllegalStateException e) {
+            if (expectSuccess) {
+                fail("Expected RangingReport.Builder.build() to succeed");
+            }
+        }
+        return report;
+    }
+
+    @Test
+    public void testParcel() {
+        Parcel parcel = Parcel.obtain();
+        RangingReport report = UwbTestUtils.getRangingReports(5);
+        report.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        RangingReport fromParcel = RangingReport.CREATOR.createFromParcel(parcel);
+        assertEquals(report, fromParcel);
+    }
+}
diff --git a/core/tests/uwbtests/src/android/uwb/UwbAddressTest.java b/core/tests/uwbtests/src/android/uwb/UwbAddressTest.java
new file mode 100644
index 0000000..ccc88a9
--- /dev/null
+++ b/core/tests/uwbtests/src/android/uwb/UwbAddressTest.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2020 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.uwb;
+
+import static org.junit.Assert.assertEquals;
+
+import android.os.Parcel;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Test of {@link UwbAddress}.
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class UwbAddressTest {
+
+    @Test
+    public void testFromBytes_Short() {
+        runFromBytes(UwbAddress.SHORT_ADDRESS_BYTE_LENGTH);
+    }
+
+    @Test
+    public void testFromBytes_Extended() {
+        runFromBytes(UwbAddress.EXTENDED_ADDRESS_BYTE_LENGTH);
+    }
+
+    private void runFromBytes(int len) {
+        byte[] addressBytes = getByteArray(len);
+        UwbAddress address = UwbAddress.fromBytes(addressBytes);
+        assertEquals(address.size(), len);
+        assertEquals(addressBytes, address.toBytes());
+    }
+
+    private byte[] getByteArray(int len) {
+        byte[] res = new byte[len];
+        for (int i = 0; i < len; i++) {
+            res[i] = (byte) i;
+        }
+        return res;
+    }
+
+    @Test
+    public void testParcel_Short() {
+        runParcel(true);
+    }
+
+    @Test
+    public void testParcel_Extended() {
+        runParcel(false);
+    }
+
+    private void runParcel(boolean useShortAddress) {
+        Parcel parcel = Parcel.obtain();
+        UwbAddress address = UwbTestUtils.getUwbAddress(useShortAddress);
+        address.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        UwbAddress fromParcel = UwbAddress.CREATOR.createFromParcel(parcel);
+        assertEquals(address, fromParcel);
+    }
+}
diff --git a/core/tests/uwbtests/src/android/uwb/UwbTestUtils.java b/core/tests/uwbtests/src/android/uwb/UwbTestUtils.java
new file mode 100644
index 0000000..62e0b62
--- /dev/null
+++ b/core/tests/uwbtests/src/android/uwb/UwbTestUtils.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2020 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.uwb;
+
+import android.os.SystemClock;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class UwbTestUtils {
+    private UwbTestUtils() {}
+
+    public static AngleMeasurement getAngleMeasurement() {
+        return new AngleMeasurement.Builder()
+                .setRadians(getDoubleInRange(-Math.PI, Math.PI))
+                .setErrorRadians(getDoubleInRange(0, Math.PI))
+                .setConfidenceLevel(getDoubleInRange(0, 1))
+                .build();
+    }
+
+    public static AngleOfArrivalMeasurement getAngleOfArrivalMeasurement() {
+        return new AngleOfArrivalMeasurement.Builder()
+                .setAltitudeAngleMeasurement(getAngleMeasurement())
+                .setAzimuthAngleMeasurement(getAngleMeasurement())
+                .build();
+    }
+
+    public static DistanceMeasurement getDistanceMeasurement() {
+        return new DistanceMeasurement.Builder()
+                .setMeters(getDoubleInRange(0, 100))
+                .setErrorMeters(getDoubleInRange(0, 10))
+                .setConfidenceLevel(getDoubleInRange(0, 1))
+                .build();
+    }
+
+    public static RangingMeasurement getRangingMeasurement() {
+        return getRangingMeasurement(getUwbAddress(false));
+    }
+
+    public static RangingMeasurement getRangingMeasurement(UwbAddress address) {
+        return new RangingMeasurement.Builder()
+                .setDistanceMeasurement(getDistanceMeasurement())
+                .setAngleOfArrivalMeasurement(getAngleOfArrivalMeasurement())
+                .setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos())
+                .setRemoteDeviceAddress(address != null ? address : getUwbAddress(false))
+                .setStatus(RangingMeasurement.RANGING_STATUS_SUCCESS)
+                .build();
+    }
+
+    public static List<RangingMeasurement> getRangingMeasurements(int num) {
+        List<RangingMeasurement> result = new ArrayList<>();
+        for (int i = 0; i < num; i++) {
+            result.add(getRangingMeasurement());
+        }
+        return result;
+    }
+
+    public static RangingReport getRangingReports(int numMeasurements) {
+        RangingReport.Builder builder = new RangingReport.Builder();
+        for (int i = 0; i < numMeasurements; i++) {
+            builder.addMeasurement(getRangingMeasurement());
+        }
+        return builder.build();
+    }
+
+    private static double getDoubleInRange(double min, double max) {
+        return min + (max - min) * Math.random();
+    }
+
+    public static UwbAddress getUwbAddress(boolean isShortAddress) {
+        byte[] addressBytes = new byte[isShortAddress ? UwbAddress.SHORT_ADDRESS_BYTE_LENGTH :
+                UwbAddress.EXTENDED_ADDRESS_BYTE_LENGTH];
+        for (int i = 0; i < addressBytes.length; i++) {
+            addressBytes[i] = (byte) getDoubleInRange(1, 255);
+        }
+        return UwbAddress.fromBytes(addressBytes);
+    }
+}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/InstallInstalling.java b/packages/PackageInstaller/src/com/android/packageinstaller/InstallInstalling.java
index 4f85eea..bbc33c3 100755
--- a/packages/PackageInstaller/src/com/android/packageinstaller/InstallInstalling.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/InstallInstalling.java
@@ -339,6 +339,10 @@
             try {
                 session = getPackageManager().getPackageInstaller().openSession(mSessionId);
             } catch (IOException e) {
+                synchronized (this) {
+                    isDone = true;
+                    notifyAll();
+                }
                 return null;
             }
 
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
index ef51abb..2702bc4 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
@@ -19,6 +19,7 @@
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
 import static android.view.WindowManager.ScreenshotSource.SCREENSHOT_GLOBAL_ACTIONS;
 import static android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN;
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON;
 
 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_USER_REQUEST;
 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED;
@@ -547,7 +548,7 @@
         if (!mDeviceProvisioned && !action.showBeforeProvisioning()) {
             return false;
         }
-        return true;
+        return action.shouldShow();
     }
 
     /**
@@ -962,6 +963,8 @@
 
     @VisibleForTesting
     class ScreenshotAction extends SinglePressAction implements LongPressAction {
+        final String KEY_SYSTEM_NAV_2BUTTONS = "system_nav_2buttons";
+
         public ScreenshotAction() {
             super(R.drawable.ic_screenshot, R.string.global_action_screenshot);
         }
@@ -994,6 +997,19 @@
         }
 
         @Override
+        public boolean shouldShow() {
+          // Include screenshot in power menu for legacy nav because it is not accessible
+          // through Recents in that mode
+            return is2ButtonNavigationEnabled();
+        }
+
+        boolean is2ButtonNavigationEnabled() {
+            return NAV_BAR_MODE_2BUTTON == mContext.getResources().getInteger(
+                    com.android.internal.R.integer.config_navBarInteractionMode);
+        }
+
+
+        @Override
         public boolean onLongPress() {
             if (FeatureFlagUtils.isEnabled(mContext, FeatureFlagUtils.SCREENRECORD_LONG_PRESS)) {
                 mUiEventLogger.log(GlobalActionsEvent.GA_SCREENSHOT_LONG_PRESS);
@@ -1616,6 +1632,10 @@
          * @return
          */
         CharSequence getMessage();
+
+        default boolean shouldShow() {
+            return true;
+        }
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
index bc03ca6..077c7aa 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
@@ -23,6 +23,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.Resources;
+import android.os.UserHandle;
 import android.provider.Settings;
 import android.service.quicksettings.Tile;
 import android.telephony.SubscriptionManager;
@@ -230,7 +231,8 @@
 
     @Override
     public boolean isAvailable() {
-        return mController.hasMobileDataFeature();
+        return mController.hasMobileDataFeature()
+            && mHost.getUserContext().getUserId() == UserHandle.USER_SYSTEM;
     }
 
     private static final class CallbackInfo {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java
index ac8c671..5e2e7c0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java
@@ -49,6 +49,7 @@
 import android.util.FeatureFlagUtils;
 import android.view.IWindowManager;
 import android.view.View;
+import android.view.WindowManagerPolicyConstants;
 import android.widget.FrameLayout;
 
 import androidx.test.filters.SmallTest;
@@ -241,6 +242,28 @@
         verifyLogPosted(GlobalActionsDialog.GlobalActionsEvent.GA_SCREENSHOT_LONG_PRESS);
     }
 
+    @Test
+    public void testShouldShowScreenshot() {
+        mContext.getOrCreateTestableResources().addOverride(
+                com.android.internal.R.integer.config_navBarInteractionMode,
+                WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON);
+
+        GlobalActionsDialog.ScreenshotAction screenshotAction =
+                mGlobalActionsDialog.makeScreenshotActionForTesting();
+        assertThat(screenshotAction.shouldShow()).isTrue();
+    }
+
+    @Test
+    public void testShouldNotShowScreenshot() {
+        mContext.getOrCreateTestableResources().addOverride(
+                com.android.internal.R.integer.config_navBarInteractionMode,
+                WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON);
+
+        GlobalActionsDialog.ScreenshotAction screenshotAction =
+                mGlobalActionsDialog.makeScreenshotActionForTesting();
+        assertThat(screenshotAction.shouldShow()).isFalse();
+    }
+
     private void verifyLogPosted(GlobalActionsDialog.GlobalActionsEvent event) {
         mTestableLooper.processAllMessages();
         verify(mUiEventLogger, times(1))
diff --git a/packages/VpnDialogs/AndroidManifest.xml b/packages/VpnDialogs/AndroidManifest.xml
index 693ca52..569617a 100644
--- a/packages/VpnDialogs/AndroidManifest.xml
+++ b/packages/VpnDialogs/AndroidManifest.xml
@@ -23,6 +23,9 @@
     <uses-permission android:name="android.permission.CONTROL_ALWAYS_ON_VPN" />
     <uses-permission android:name="android.permission.HIDE_NON_SYSTEM_OVERLAY_WINDOWS"/>
 
+    <!-- Query all packages on device on R+ -->
+    <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
+
     <application android:label="VpnDialogs"
                  android:allowBackup="false">
 
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 22423fe..a992aa6 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -1105,23 +1105,26 @@
         intentFilter.addAction(Intent.ACTION_USER_ADDED);
         intentFilter.addAction(Intent.ACTION_USER_REMOVED);
         intentFilter.addAction(Intent.ACTION_USER_UNLOCKED);
-        mContext.registerReceiverAsUser(
+
+        final Context userAllContext = mContext.createContextAsUser(UserHandle.ALL, 0 /* flags */);
+        userAllContext.registerReceiver(
                 mIntentReceiver,
-                UserHandle.ALL,
                 intentFilter,
                 null /* broadcastPermission */,
                 mHandler);
-        mContext.registerReceiverAsUser(mUserPresentReceiver, UserHandle.SYSTEM,
-                new IntentFilter(Intent.ACTION_USER_PRESENT), null, null);
+        mContext.createContextAsUser(UserHandle.SYSTEM, 0 /* flags */).registerReceiver(
+                mUserPresentReceiver,
+                new IntentFilter(Intent.ACTION_USER_PRESENT),
+                null /* broadcastPermission */,
+                null /* scheduler */);
 
         // Listen to package add and removal events for all users.
         intentFilter = new IntentFilter();
         intentFilter.addAction(Intent.ACTION_PACKAGE_REPLACED);
         intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
         intentFilter.addDataScheme("package");
-        mContext.registerReceiverAsUser(
+        userAllContext.registerReceiver(
                 mIntentReceiver,
-                UserHandle.ALL,
                 intentFilter,
                 null /* broadcastPermission */,
                 mHandler);
@@ -1129,8 +1132,8 @@
         // Listen to lockdown VPN reset.
         intentFilter = new IntentFilter();
         intentFilter.addAction(LockdownVpnTracker.ACTION_LOCKDOWN_RESET);
-        mContext.registerReceiverAsUser(
-                mIntentReceiver, UserHandle.ALL, intentFilter, NETWORK_STACK, mHandler);
+        userAllContext.registerReceiver(
+                mIntentReceiver, intentFilter, NETWORK_STACK, mHandler);
 
         try {
             mNMS.registerObserver(mDataActivityObserver);
@@ -5259,7 +5262,9 @@
             // Try creating lockdown tracker, since user present usually means
             // unlocked keystore.
             updateLockdownVpn();
-            mContext.unregisterReceiver(this);
+            // Use the same context that registered receiver before to unregister it. Because use
+            // different context to unregister receiver will cause exception.
+            context.unregisterReceiver(this);
         }
     };
 
diff --git a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
index 60e59e3..28afcbb 100644
--- a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
+++ b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
@@ -85,6 +85,7 @@
         DeviceConfig.NAMESPACE_INTELLIGENCE_CONTENT_SUGGESTIONS,
         DeviceConfig.NAMESPACE_MEDIA_NATIVE,
         DeviceConfig.NAMESPACE_NETD_NATIVE,
+        DeviceConfig.NAMESPACE_PROFCOLLECT_NATIVE_BOOT,
         DeviceConfig.NAMESPACE_RUNTIME_NATIVE,
         DeviceConfig.NAMESPACE_RUNTIME_NATIVE_BOOT,
         DeviceConfig.NAMESPACE_STORAGE_NATIVE_BOOT,
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 2991339..8be24a6 100755
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -3987,7 +3987,7 @@
     /** @see AudioManager#playSoundEffect(int, float) */
     public void playSoundEffectVolume(int effectType, float volume) {
         // do not try to play the sound effect if the system stream is muted
-        if (isStreamMutedByRingerOrZenMode(STREAM_SYSTEM)) {
+        if (isStreamMute(STREAM_SYSTEM)) {
             return;
         }
 
diff --git a/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java b/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java
index d548871..17828a0 100644
--- a/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java
+++ b/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java
@@ -95,7 +95,11 @@
 
     private static final boolean DBG = false;
 
+    // This context is for the current user.
     private final Context mContext;
+    // This context is for all users, so register a BroadcastReceiver which can receive intents from
+    // all users.
+    private final Context mUserAllContext;
     private final Handler mHandler;
     private final Clock mClock;
     private final Dependencies mDeps;
@@ -132,6 +136,7 @@
 
     public MultipathPolicyTracker(Context ctx, Handler handler, Dependencies deps) {
         mContext = ctx;
+        mUserAllContext = ctx.createContextAsUser(UserHandle.ALL, 0 /* flags */);
         mHandler = handler;
         mClock = deps.getClock();
         mDeps = deps;
@@ -155,8 +160,8 @@
 
         final IntentFilter intentFilter = new IntentFilter();
         intentFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
-        mContext.registerReceiverAsUser(
-                mConfigChangeReceiver, UserHandle.ALL, intentFilter, null, mHandler);
+        mUserAllContext.registerReceiver(
+                mConfigChangeReceiver, intentFilter, null /* broadcastPermission */, mHandler);
     }
 
     public void shutdown() {
@@ -167,7 +172,7 @@
         }
         mMultipathTrackers.clear();
         mResolver.unregisterContentObserver(mSettingsObserver);
-        mContext.unregisterReceiver(mConfigChangeReceiver);
+        mUserAllContext.unregisterReceiver(mConfigChangeReceiver);
     }
 
     // Called on an arbitrary binder thread.
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index 1a83272..9e43b54 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -865,7 +865,7 @@
             Intent serviceIntent = new Intent(VpnConfig.SERVICE_INTERFACE);
             serviceIntent.setPackage(alwaysOnPackage);
             try {
-                return mContext.startServiceAsUser(serviceIntent, UserHandle.of(mUserId)) != null;
+                return mUserIdContext.startService(serviceIntent) != null;
             } catch (RuntimeException e) {
                 Log.e(TAG, "VpnService " + serviceIntent + " failed to start", e);
                 return false;
@@ -1036,20 +1036,21 @@
 
         final long token = Binder.clearCallingIdentity();
         try {
-            final int[] toChange;
+            final String[] toChange;
 
             // Clear all AppOps if the app is being unauthorized.
             switch (vpnType) {
                 case VpnManager.TYPE_VPN_NONE:
-                    toChange = new int[] {
-                            AppOpsManager.OP_ACTIVATE_VPN, AppOpsManager.OP_ACTIVATE_PLATFORM_VPN
+                    toChange = new String[] {
+                            AppOpsManager.OPSTR_ACTIVATE_VPN,
+                            AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN
                     };
                     break;
                 case VpnManager.TYPE_VPN_PLATFORM:
-                    toChange = new int[] {AppOpsManager.OP_ACTIVATE_PLATFORM_VPN};
+                    toChange = new String[] {AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN};
                     break;
                 case VpnManager.TYPE_VPN_SERVICE:
-                    toChange = new int[] {AppOpsManager.OP_ACTIVATE_VPN};
+                    toChange = new String[] {AppOpsManager.OPSTR_ACTIVATE_VPN};
                     break;
                 default:
                     Log.wtf(TAG, "Unrecognized VPN type while granting authorization");
@@ -1058,9 +1059,9 @@
 
             final AppOpsManager appOpMgr =
                     (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
-            for (final int appOp : toChange) {
+            for (final String appOpStr : toChange) {
                 appOpMgr.setMode(
-                        appOp,
+                        appOpStr,
                         uid,
                         packageName,
                         vpnType == VpnManager.TYPE_VPN_NONE
@@ -1086,21 +1087,22 @@
         }
     }
 
-    private static boolean doesPackageHaveAppop(Context context, String packageName, int appop) {
+    private static boolean doesPackageHaveAppop(Context context, String packageName,
+            String appOpStr) {
         final AppOpsManager appOps =
                 (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
 
         // Verify that the caller matches the given package and has the required permission.
-        return appOps.noteOpNoThrow(appop, Binder.getCallingUid(), packageName)
-                == AppOpsManager.MODE_ALLOWED;
+        return appOps.noteOpNoThrow(appOpStr, Binder.getCallingUid(), packageName,
+                null /* attributionTag */, null /* message */) == AppOpsManager.MODE_ALLOWED;
     }
 
     private static boolean isVpnServicePreConsented(Context context, String packageName) {
-        return doesPackageHaveAppop(context, packageName, AppOpsManager.OP_ACTIVATE_VPN);
+        return doesPackageHaveAppop(context, packageName, AppOpsManager.OPSTR_ACTIVATE_VPN);
     }
 
     private static boolean isVpnProfilePreConsented(Context context, String packageName) {
-        return doesPackageHaveAppop(context, packageName, AppOpsManager.OP_ACTIVATE_PLATFORM_VPN)
+        return doesPackageHaveAppop(context, packageName, AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN)
                 || isVpnServicePreConsented(context, packageName);
     }
 
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
index 611b8c6..ab289ea 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
@@ -708,17 +708,17 @@
     private byte[] getSupportedShortAudioDescriptorsFromConfig(
             List<DeviceConfig> deviceConfig, @AudioCodec int[] audioFormatCodes) {
         DeviceConfig deviceConfigToUse = null;
+        String audioDeviceName = SystemProperties.get(
+                Constants.PROPERTY_SYSTEM_AUDIO_MODE_AUDIO_PORT,
+                "VX_AUDIO_DEVICE_IN_HDMI_ARC");
         for (DeviceConfig device : deviceConfig) {
-            // TODO(amyjojo) use PROPERTY_SYSTEM_AUDIO_MODE_AUDIO_PORT to get the audio device name
-            if (device.name.equals("VX_AUDIO_DEVICE_IN_HDMI_ARC")) {
+            if (device.name.equals(audioDeviceName)) {
                 deviceConfigToUse = device;
                 break;
             }
         }
         if (deviceConfigToUse == null) {
-            // TODO(amyjojo) use PROPERTY_SYSTEM_AUDIO_MODE_AUDIO_PORT to get the audio device name
-            Slog.w(TAG, "sadConfig.xml does not have required device info for "
-                        + "VX_AUDIO_DEVICE_IN_HDMI_ARC");
+            Slog.w(TAG, "sadConfig.xml does not have required device info for " + audioDeviceName);
             return new byte[0];
         }
         HashMap<Integer, byte[]> map = new HashMap<>();
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
index 2c0ddaf..804cc92 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
@@ -1667,6 +1667,7 @@
         if (avr == null) {
             return;
         }
+        setArcStatus(false);
 
         // Seq #44.
         removeAction(RequestArcInitiationAction.class);
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java
index 7d76628..fe97f70 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java
@@ -122,7 +122,25 @@
         addValidationInfo(Constants.MESSAGE_RECORD_STATUS,
                 new RecordStatusInfoValidator(), DEST_DIRECT);
 
-        // TODO: Handle messages for the Timer Programming.
+        addValidationInfo(
+                Constants.MESSAGE_CLEAR_ANALOG_TIMER, new AnalogueTimerValidator(), DEST_DIRECT);
+        addValidationInfo(
+                Constants.MESSAGE_CLEAR_DIGITAL_TIMER, new DigitalTimerValidator(), DEST_DIRECT);
+        addValidationInfo(
+                Constants.MESSAGE_CLEAR_EXTERNAL_TIMER, new ExternalTimerValidator(), DEST_DIRECT);
+        addValidationInfo(
+                Constants.MESSAGE_SET_ANALOG_TIMER, new AnalogueTimerValidator(), DEST_DIRECT);
+        addValidationInfo(
+                Constants.MESSAGE_SET_DIGITAL_TIMER, new DigitalTimerValidator(), DEST_DIRECT);
+        addValidationInfo(
+                Constants.MESSAGE_SET_EXTERNAL_TIMER, new ExternalTimerValidator(), DEST_DIRECT);
+        addValidationInfo(
+                Constants.MESSAGE_SET_TIMER_PROGRAM_TITLE, new AsciiValidator(1, 14), DEST_DIRECT);
+        addValidationInfo(
+                Constants.MESSAGE_TIMER_CLEARED_STATUS,
+                new TimerClearedStatusValidator(),
+                DEST_DIRECT);
+        addValidationInfo(Constants.MESSAGE_TIMER_STATUS, new TimerStatusValidator(), DEST_DIRECT);
 
         // Messages for the System Information.
         FixedLengthValidator oneByteValidator = new FixedLengthValidator(1);
@@ -343,6 +361,277 @@
         return true;
     }
 
+    /**
+     * Check if the given value is a valid day of month. A valid value is one which falls within the
+     * range description defined in CEC 1.4 Specification : Operand Descriptions (Section 17)
+     *
+     * @param value day of month
+     * @return true if the day of month is valid
+     */
+    private boolean isValidDayOfMonth(int value) {
+        return isWithinRange(value, 1, 31);
+    }
+
+    /**
+     * Check if the given value is a valid month of year. A valid value is one which falls within
+     * the range description defined in CEC 1.4 Specification : Operand Descriptions (Section 17)
+     *
+     * @param value month of year
+     * @return true if the month of year is valid
+     */
+    private boolean isValidMonthOfYear(int value) {
+        return isWithinRange(value, 1, 12);
+    }
+
+    /**
+     * Check if the given value is a valid hour. A valid value is one which falls within the range
+     * description defined in CEC 1.4 Specification : Operand Descriptions (Section 17)
+     *
+     * @param value hour
+     * @return true if the hour is valid
+     */
+    private boolean isValidHour(int value) {
+        return isWithinRange(value, 0, 23);
+    }
+
+    /**
+     * Check if the given value is a valid minute. A valid value is one which falls within the range
+     * description defined in CEC 1.4 Specification : Operand Descriptions (Section 17)
+     *
+     * @param value minute
+     * @return true if the minute is valid
+     */
+    private boolean isValidMinute(int value) {
+        return isWithinRange(value, 0, 59);
+    }
+
+    /**
+     * Check if the given value is a valid duration hours. A valid value is one which falls within
+     * the range description defined in CEC 1.4 Specification : Operand Descriptions (Section 17)
+     *
+     * @param value duration hours
+     * @return true if the duration hours is valid
+     */
+    private boolean isValidDurationHours(int value) {
+        return isWithinRange(value, 0, 99);
+    }
+
+    /**
+     * Check if the given value is a valid recording sequence. A valid value is adheres to range
+     * description defined in CEC 1.4 Specification : Operand Descriptions (Section 17)
+     *
+     * @param value recording sequence
+     * @return true if the given recording sequence is valid
+     */
+    private boolean isValidRecordingSequence(int value) {
+        value = value & 0xFF;
+        // Validate bit 7 is set to zero
+        if ((value & 0x80) != 0x00) {
+            return false;
+        }
+        // Validate than not more than one bit is set
+        return (Integer.bitCount(value) <= 1);
+    }
+
+    /**
+     * Check if the given value is a valid analogue broadcast type. A valid value is one which falls
+     * within the range description defined in CEC 1.4 Specification : Operand Descriptions (Section
+     * 17)
+     *
+     * @param value analogue broadcast type
+     * @return true if the analogue broadcast type is valid
+     */
+    private boolean isValidAnalogueBroadcastType(int value) {
+        return isWithinRange(value, 0x00, 0x02);
+    }
+
+    /**
+     * Check if the given value is a valid analogue frequency. A valid value is one which falls
+     * within the range description defined in CEC 1.4 Specification : Operand Descriptions (Section
+     * 17)
+     *
+     * @param value analogue frequency
+     * @return true if the analogue frequency is valid
+     */
+    private boolean isValidAnalogueFrequency(int value) {
+        value = value & 0xFFFF;
+        return (value != 0x000 && value != 0xFFFF);
+    }
+
+    /**
+     * Check if the given value is a valid broadcast system. A valid value is one which falls within
+     * the range description defined in CEC 1.4 Specification : Operand Descriptions (Section 17)
+     *
+     * @param value broadcast system
+     * @return true if the broadcast system is valid
+     */
+    private boolean isValidBroadcastSystem(int value) {
+        return isWithinRange(value, 0, 31);
+    }
+
+    /**
+     * Check if the given value is a ARIB type. A valid value is one which falls within the range
+     * description defined in CEC 1.4 Specification : Operand Descriptions (Section 17)
+     *
+     * @param value Digital Broadcast System
+     * @return true if the Digital Broadcast System is ARIB type
+     */
+    private boolean isAribDbs(int value) {
+        return (value == 0x00 || isWithinRange(value, 0x08, 0x0A));
+    }
+
+    /**
+     * Check if the given value is a ATSC type. A valid value is one which falls within the range
+     * description defined in CEC 1.4 Specification : Operand Descriptions (Section 17)
+     *
+     * @param value Digital Broadcast System
+     * @return true if the Digital Broadcast System is ATSC type
+     */
+    private boolean isAtscDbs(int value) {
+        return (value == 0x01 || isWithinRange(value, 0x10, 0x12));
+    }
+
+    /**
+     * Check if the given value is a DVB type. A valid value is one which falls within the range
+     * description defined in CEC 1.4 Specification : Operand Descriptions (Section 17)
+     *
+     * @param value Digital Broadcast System
+     * @return true if the Digital Broadcast System is DVB type
+     */
+    private boolean isDvbDbs(int value) {
+        return (value == 0x02 || isWithinRange(value, 0x18, 0x1B));
+    }
+
+    /**
+     * Check if the given value is a valid Digital Broadcast System. A valid value is one which
+     * falls within the range description defined in CEC 1.4 Specification : Operand Descriptions
+     * (Section 17)
+     *
+     * @param value Digital Broadcast System
+     * @return true if the Digital Broadcast System is valid
+     */
+    private boolean isValidDigitalBroadcastSystem(int value) {
+        return (isAribDbs(value) || isAtscDbs(value) || isDvbDbs(value));
+    }
+
+    /**
+     * Check if the given value is a valid Digital Service Identification. A valid value is one
+     * which falls within the range description defined in CEC 1.4 Specification : Operand
+     * Descriptions (Section 17)
+     *
+     * @param params Digital Timer Message parameters
+     * @param offset start offset of Digital Service Identification
+     * @return true if the Digital Service Identification is valid
+     */
+    private boolean isValidDigitalServiceIdentification(byte[] params, int offset) {
+        // MSB contains Service Identification Method
+        int serviceIdentificationMethod = params[offset] & 0x80;
+        // Last 7 bits contains Digital Broadcast System
+        int digitalBroadcastSystem = params[offset] & 0x7F;
+        offset = offset + 1;
+        if (serviceIdentificationMethod == 0x00) {
+            // Services identified by Digital IDs
+            if (isAribDbs(digitalBroadcastSystem)) {
+                // Validate ARIB type have 6 byte data
+                return params.length - offset >= 6;
+            } else if (isAtscDbs(digitalBroadcastSystem)) {
+                // Validate ATSC type have 4 byte data
+                return params.length - offset >= 4;
+            } else if (isDvbDbs(digitalBroadcastSystem)) {
+                // Validate DVB type have 6 byte data
+                return params.length - offset >= 6;
+            }
+        } else if (serviceIdentificationMethod == 0x80) {
+            // Services identified by Channel
+            if (isValidDigitalBroadcastSystem(digitalBroadcastSystem)) {
+                // First 6 bits contain Channel Number Format
+                int channelNumberFormat = params[offset] & 0xFC;
+                if (channelNumberFormat == 0x04) {
+                    // Validate it contains 1-part Channel Number data (16 bits)
+                    return params.length - offset >= 3;
+                } else if (channelNumberFormat == 0x08) {
+                    // Validate it contains Major Channel Number and Minor Channel Number (26 bits)
+                    return params.length - offset >= 4;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Check if the given value is a valid External Plug. A valid value is one which falls within
+     * the range description defined in CEC 1.4 Specification : Operand Descriptions (Section 17)
+     *
+     * @param value External Plug
+     * @return true if the External Plug is valid
+     */
+    private boolean isValidExternalPlug(int value) {
+        return isWithinRange(value, 1, 255);
+    }
+
+    /**
+     * Check if the given value is a valid External Source. A valid value is one which falls within
+     * the range description defined in CEC 1.4 Specification : Operand Descriptions (Section 17)
+     *
+     * @param value External Source Specifier
+     * @return true if the External Source is valid
+     */
+    private boolean isValidExternalSource(byte[] params, int offset) {
+        int externalSourceSpecifier = params[offset];
+        offset = offset + 1;
+        if (externalSourceSpecifier == 0x04) {
+            // External Plug
+            return isValidExternalPlug(params[offset]);
+        } else if (externalSourceSpecifier == 0x05) {
+            // External Physical Address
+            // Validate it contains 2 bytes Physical Address
+            if (params.length - offset >= 2) {
+                return isValidPhysicalAddress(params, offset);
+            }
+        }
+        return false;
+    }
+
+    private boolean isValidProgrammedInfo(int programedInfo) {
+        return (isWithinRange(programedInfo, 0x00, 0x0B));
+    }
+
+    private boolean isValidNotProgrammedErrorInfo(int nonProgramedErrorInfo) {
+        return (isWithinRange(nonProgramedErrorInfo, 0x00, 0x0E));
+    }
+
+    private boolean isValidTimerStatusData(byte[] params, int offset) {
+        int programedIndicator = params[offset] & 0x10;
+        boolean durationAvailable = false;
+        if (programedIndicator == 0x10) {
+            // Programmed
+            int programedInfo = params[offset] & 0x0F;
+            if (isValidProgrammedInfo(programedInfo)) {
+                if (programedInfo == 0x09 || programedInfo == 0x0B) {
+                    durationAvailable = true;
+                } else {
+                    return true;
+                }
+            }
+        } else {
+            // Non programmed
+            int nonProgramedErrorInfo = params[offset] & 0x0F;
+            if (isValidNotProgrammedErrorInfo(nonProgramedErrorInfo)) {
+                if (nonProgramedErrorInfo == 0x0E) {
+                    durationAvailable = true;
+                } else {
+                    return true;
+                }
+            }
+        }
+        offset = offset + 1;
+        // Duration Available (2 bytes)
+        if (durationAvailable && params.length - offset >= 2) {
+            return (isValidDurationHours(params[offset]) && isValidMinute(params[offset + 1]));
+        }
+        return false;
+    }
+
     private class PhysicalAddressValidator implements ParameterValidator {
         @Override
         public int isValid(byte[] params) {
@@ -472,4 +761,106 @@
             return toErrorCode(isWithinRange(params[0], mMinValue, mMaxValue));
         }
     }
+
+    /**
+     * Check if the given Analogue Timer message parameters are valid. Valid parameters should
+     * adhere to message description of Analogue Timer defined in CEC 1.4 Specification : Message
+     * Descriptions for Timer Programming Feature (CEC Table 12)
+     */
+    private class AnalogueTimerValidator implements ParameterValidator {
+        @Override
+        public int isValid(byte[] params) {
+            if (params.length < 11) {
+                return ERROR_PARAMETER_SHORT;
+            }
+            return toErrorCode(
+                    isValidDayOfMonth(params[0]) // Day of Month
+                            && isValidMonthOfYear(params[1]) // Month of Year
+                            && isValidHour(params[2]) // Start Time - Hour
+                            && isValidMinute(params[3]) // Start Time - Minute
+                            && isValidDurationHours(params[4]) // Duration - Duration Hours
+                            && isValidMinute(params[5]) // Duration - Minute
+                            && isValidRecordingSequence(params[6]) // Recording Sequence
+                            && isValidAnalogueBroadcastType(params[7]) // Analogue Broadcast Type
+                            && isValidAnalogueFrequency(
+                                    HdmiUtils.twoBytesToInt(params, 8)) // Analogue Frequency
+                            && isValidBroadcastSystem(params[10])); // Broadcast System
+        }
+    }
+
+    /**
+     * Check if the given Digital Timer message parameters are valid. Valid parameters should adhere
+     * to message description of Digital Timer defined in CEC 1.4 Specification : Message
+     * Descriptions for Timer Programming Feature (CEC Table 12)
+     */
+    private class DigitalTimerValidator implements ParameterValidator {
+        @Override
+        public int isValid(byte[] params) {
+            if (params.length < 11) {
+                return ERROR_PARAMETER_SHORT;
+            }
+            return toErrorCode(
+                    isValidDayOfMonth(params[0]) // Day of Month
+                            && isValidMonthOfYear(params[1]) // Month of Year
+                            && isValidHour(params[2]) // Start Time - Hour
+                            && isValidMinute(params[3]) // Start Time - Minute
+                            && isValidDurationHours(params[4]) // Duration - Duration Hours
+                            && isValidMinute(params[5]) // Duration - Minute
+                            && isValidRecordingSequence(params[6]) // Recording Sequence
+                            && isValidDigitalServiceIdentification(
+                                    params, 7)); // Digital Service Identification
+        }
+    }
+
+    /**
+     * Check if the given External Timer message parameters are valid. Valid parameters should
+     * adhere to message description of External Timer defined in CEC 1.4 Specification : Message
+     * Descriptions for Timer Programming Feature (CEC Table 12)
+     */
+    private class ExternalTimerValidator implements ParameterValidator {
+        @Override
+        public int isValid(byte[] params) {
+            if (params.length < 9) {
+                return ERROR_PARAMETER_SHORT;
+            }
+            return toErrorCode(
+                    isValidDayOfMonth(params[0]) // Day of Month
+                            && isValidMonthOfYear(params[1]) // Month of Year
+                            && isValidHour(params[2]) // Start Time - Hour
+                            && isValidMinute(params[3]) // Start Time - Minute
+                            && isValidDurationHours(params[4]) // Duration - Duration Hours
+                            && isValidMinute(params[5]) // Duration - Minute
+                            && isValidRecordingSequence(params[6]) // Recording Sequence
+                            && isValidExternalSource(params, 7)); // External Source
+        }
+    }
+
+    /**
+     * Check if the given timer cleared status parameter is valid. A valid parameter should lie
+     * within the range description defined in CEC 1.4 Specification : Operand Descriptions
+     * (Section 17)
+     */
+    private class TimerClearedStatusValidator implements ParameterValidator {
+        @Override
+        public int isValid(byte[] params) {
+            if (params.length < 1) {
+                return ERROR_PARAMETER_SHORT;
+            }
+            return toErrorCode(isWithinRange(params[0], 0x00, 0x02) || (params[0] & 0xFF) == 0x80);
+        }
+    }
+
+    /**
+     * Check if the given timer status data parameter is valid. A valid parameter should lie within
+     * the range description defined in CEC 1.4 Specification : Operand Descriptions (Section 17)
+     */
+    private class TimerStatusValidator implements ParameterValidator {
+        @Override
+        public int isValid(byte[] params) {
+            if (params.length < 1) {
+                return ERROR_PARAMETER_SHORT;
+            }
+            return toErrorCode(isValidTimerStatusData(params, 0));
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 7d0457b..e8f4826 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -559,6 +559,10 @@
     /** Set of all merged subscriberId as of last update */
     @GuardedBy("mNetworkPoliciesSecondLock")
     private List<String[]> mMergedSubscriberIds = new ArrayList<>();
+    /** Map from subId to carrierConfig as of last update */
+    @GuardedBy("mNetworkPoliciesSecondLock")
+    private final SparseArray<PersistableBundle> mSubIdToCarrierConfig =
+            new SparseArray<PersistableBundle>();
 
     /**
      * Indicates the uids restricted by admin from accessing metered data. It's a mapping from
@@ -1186,7 +1190,7 @@
             final long totalBytes = getTotalBytes(policy.template, cycleStart, cycleEnd);
 
             // Carrier might want to manage notifications themselves
-            final PersistableBundle config = mCarrierConfigManager.getConfigForSubId(subId);
+            final PersistableBundle config = mSubIdToCarrierConfig.get(subId);
             if (!CarrierConfigManager.isConfigForIdentifiedCarrier(config)) {
                 if (LOGV) Slog.v(TAG, "isConfigForIdentifiedCarrier returned false");
                 // Don't show notifications until we confirm that the loaded config is from an
@@ -1831,8 +1835,11 @@
 
         final List<String[]> mergedSubscriberIdsList = new ArrayList();
         final SparseArray<String> subIdToSubscriberId = new SparseArray<>(subList.size());
+        final SparseArray<PersistableBundle> subIdToCarrierConfig =
+                new SparseArray<PersistableBundle>();
         for (final SubscriptionInfo sub : subList) {
-            final TelephonyManager tmSub = tm.createForSubscriptionId(sub.getSubscriptionId());
+            final int subId = sub.getSubscriptionId();
+            final TelephonyManager tmSub = tm.createForSubscriptionId(subId);
             final String subscriberId = tmSub.getSubscriberId();
             if (!TextUtils.isEmpty(subscriberId)) {
                 subIdToSubscriberId.put(tmSub.getSubscriptionId(), subscriberId);
@@ -1843,6 +1850,13 @@
             final String[] mergedSubscriberId = ArrayUtils.defeatNullable(
                     tmSub.getMergedImsisFromGroup());
             mergedSubscriberIdsList.add(mergedSubscriberId);
+
+            final PersistableBundle config = mCarrierConfigManager.getConfigForSubId(subId);
+            if (config != null) {
+                subIdToCarrierConfig.put(subId, config);
+            } else {
+                Slog.e(TAG, "Missing CarrierConfig for subId " + subId);
+            }
         }
 
         synchronized (mNetworkPoliciesSecondLock) {
@@ -1853,6 +1867,12 @@
             }
 
             mMergedSubscriberIds = mergedSubscriberIdsList;
+
+            mSubIdToCarrierConfig.clear();
+            for (int i = 0; i < subIdToCarrierConfig.size(); i++) {
+                mSubIdToCarrierConfig.put(subIdToCarrierConfig.keyAt(i),
+                        subIdToCarrierConfig.valueAt(i));
+            }
         }
 
         Trace.traceEnd(TRACE_TAG_NETWORK);
@@ -2172,7 +2192,7 @@
                 }
             }
         } else {
-            final PersistableBundle config = mCarrierConfigManager.getConfigForSubId(subId);
+            final PersistableBundle config = mSubIdToCarrierConfig.get(subId);
             final int currentCycleDay;
             if (policy.cycleRule.isMonthly()) {
                 currentCycleDay = policy.cycleRule.start.getDayOfMonth();
diff --git a/services/core/java/com/android/server/net/NetworkStatsAccess.java b/services/core/java/com/android/server/net/NetworkStatsAccess.java
index 72559b4..ddc5ef2 100644
--- a/services/core/java/com/android/server/net/NetworkStatsAccess.java
+++ b/services/core/java/com/android/server/net/NetworkStatsAccess.java
@@ -24,7 +24,6 @@
 import android.Manifest;
 import android.annotation.IntDef;
 import android.app.AppOpsManager;
-import android.app.admin.DeviceAdminInfo;
 import android.app.admin.DevicePolicyManagerInternal;
 import android.content.Context;
 import android.content.pm.PackageManager;
@@ -112,8 +111,7 @@
         boolean hasCarrierPrivileges = tm != null &&
                 tm.checkCarrierPrivilegesForPackageAnyPhone(callingPackage) ==
                         TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
-        boolean isDeviceOwner = dpmi != null && dpmi.isActiveAdminWithPolicy(callingUid,
-                DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
+        boolean isDeviceOwner = dpmi != null && dpmi.isActiveDeviceOwner(callingUid);
         final int appId = UserHandle.getAppId(callingUid);
         if (hasCarrierPrivileges || isDeviceOwner
                 || appId == Process.SYSTEM_UID || appId == Process.NETWORK_STACK_UID) {
@@ -128,8 +126,9 @@
             return NetworkStatsAccess.Level.DEVICESUMMARY;
         }
 
-        boolean isProfileOwner = dpmi != null && dpmi.isActiveAdminWithPolicy(callingUid,
-                DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
+        //TODO(b/169395065) Figure out if this flow makes sense in Device Owner mode.
+        boolean isProfileOwner = dpmi != null && (dpmi.isActiveProfileOwner(callingUid)
+                || dpmi.isActiveDeviceOwner(callingUid));
         if (isProfileOwner) {
             // Apps with the AppOps permission, profile owners, and apps with the privileged
             // permission can access data usage for all apps in this user/profile.
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index dac3252..3d63606 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -4206,13 +4206,9 @@
         Iterator<ResolveInfo> iter = matches.iterator();
         while (iter.hasNext()) {
             final ResolveInfo rInfo = iter.next();
-            final PackageSetting ps = mSettings.mPackages.get(rInfo.activityInfo.packageName);
-            if (ps != null) {
-                final PermissionsState permissionsState = ps.getPermissionsState();
-                if (permissionsState.hasPermission(Manifest.permission.INSTALL_PACKAGES, 0)
-                        || Build.IS_ENG) {
-                    continue;
-                }
+            if (checkPermission(Manifest.permission.INSTALL_PACKAGES,
+                    rInfo.activityInfo.packageName, 0) == PERMISSION_GRANTED || Build.IS_ENG) {
+                continue;
             }
             iter.remove();
         }
@@ -4388,8 +4384,24 @@
             final int[] gids = (flags & PackageManager.GET_GIDS) == 0
                     ? EMPTY_INT_ARRAY : permissionsState.computeGids(userId);
             // Compute granted permissions only if package has requested permissions
-            final Set<String> permissions = ArrayUtils.isEmpty(p.getRequestedPermissions())
+            Set<String> permissions = ArrayUtils.isEmpty(p.getRequestedPermissions())
                     ? Collections.emptySet() : permissionsState.getPermissions(userId);
+            if (state.instantApp) {
+                permissions = new ArraySet<>(permissions);
+                permissions.removeIf(permissionName -> {
+                    BasePermission permission = mPermissionManager.getPermissionTEMP(
+                            permissionName);
+                    if (permission == null) {
+                        return true;
+                    }
+                    if (!permission.isInstant()) {
+                        EventLog.writeEvent(0x534e4554, "140256621", UserHandle.getUid(userId,
+                                ps.appId), permissionName);
+                        return true;
+                    }
+                    return false;
+                });
+            }
 
             PackageInfo packageInfo = PackageInfoUtils.generate(p, gids, flags,
                     ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId, ps);
@@ -8587,10 +8599,9 @@
     private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
             String[] permissions, boolean[] tmp, int flags, int userId) {
         int numMatch = 0;
-        final PermissionsState permissionsState = ps.getPermissionsState();
         for (int i=0; i<permissions.length; i++) {
             final String permission = permissions[i];
-            if (permissionsState.hasPermission(permission, userId)) {
+            if (checkPermission(permission, ps.name, userId) == PERMISSION_GRANTED) {
                 tmp[i] = true;
                 numMatch++;
             } else {
@@ -19199,6 +19210,14 @@
         final int flags = action.flags;
         final boolean systemApp = isSystemApp(ps);
 
+        // We need to get the permission state before package state is (potentially) destroyed.
+        final SparseBooleanArray hadSuspendAppsPermission = new SparseBooleanArray();
+        // allUserHandles could be null, so call mUserManager.getUserIds() directly which is cached anyway.
+        for (int userId : mUserManager.getUserIds()) {
+            hadSuspendAppsPermission.put(userId, checkPermission(Manifest.permission.SUSPEND_APPS,
+                    packageName, userId) == PERMISSION_GRANTED);
+        }
+
         final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
 
         if ((!systemApp || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)
@@ -19265,8 +19284,7 @@
             affectedUserIds = resolveUserIds(userId);
         }
         for (final int affectedUserId : affectedUserIds) {
-            if (ps.getPermissionsState().hasPermission(Manifest.permission.SUSPEND_APPS,
-                    affectedUserId)) {
+            if (hadSuspendAppsPermission.get(affectedUserId)) {
                 unsuspendForSuspendingPackage(packageName, affectedUserId);
                 removeAllDistractingPackageRestrictions(affectedUserId);
             }
@@ -21036,8 +21054,8 @@
                 pkgSetting.setEnabled(newState, userId, callingPackage);
                 if ((newState == COMPONENT_ENABLED_STATE_DISABLED_USER
                         || newState == COMPONENT_ENABLED_STATE_DISABLED)
-                        && pkgSetting.getPermissionsState().hasPermission(
-                                Manifest.permission.SUSPEND_APPS, userId)) {
+                        && checkPermission(Manifest.permission.SUSPEND_APPS, packageName, userId)
+                        == PERMISSION_GRANTED) {
                     // This app should not generally be allowed to get disabled by the UI, but if it
                     // ever does, we don't want to end up with some of the user's apps permanently
                     // suspended.
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index b571a9c..bb5a953 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -1060,7 +1060,9 @@
                 + "; isStaged = " + session.isStaged()
                 + "; isReady = " + session.isStagedSessionReady()
                 + "; isApplied = " + session.isStagedSessionApplied()
-                + "; isFailed = " + session.isStagedSessionFailed() + ";");
+                + "; isFailed = " + session.isStagedSessionFailed()
+                + "; errorMsg = " + session.getStagedSessionErrorMessage()
+                + ";");
     }
 
     private Intent parseIntentAndUser() throws URISyntaxException {
diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java
index 0c96f59..33433db 100644
--- a/services/core/java/com/android/server/pm/StagingManager.java
+++ b/services/core/java/com/android/server/pm/StagingManager.java
@@ -605,13 +605,14 @@
             // If checkpoint is supported, then we only resume sessions if we are in checkpointing
             // mode. If not, we fail all sessions.
             if (supportsCheckpoint() && !needsCheckpoint()) {
-                String errorMsg = "Reverting back to safe state. Marking " + session.sessionId
-                        + " as failed";
-                if (!TextUtils.isEmpty(mFailureReason)) {
-                    errorMsg = errorMsg + ": " + mFailureReason;
+                String revertMsg = "Reverting back to safe state. Marking "
+                        + session.sessionId + " as failed.";
+                final String reasonForRevert = getReasonForRevert();
+                if (!TextUtils.isEmpty(reasonForRevert)) {
+                    revertMsg += " Reason for revert: " + reasonForRevert;
                 }
-                Slog.d(TAG, errorMsg);
-                session.setStagedSessionFailed(SessionInfo.STAGED_SESSION_UNKNOWN, errorMsg);
+                Slog.d(TAG, revertMsg);
+                session.setStagedSessionFailed(SessionInfo.STAGED_SESSION_UNKNOWN, revertMsg);
                 return;
             }
         } catch (RemoteException e) {
@@ -715,6 +716,16 @@
         }
     }
 
+    private String getReasonForRevert() {
+        if (!TextUtils.isEmpty(mFailureReason)) {
+            return mFailureReason;
+        }
+        if (!TextUtils.isEmpty(mNativeFailureReason)) {
+            return "Session reverted due to crashing native process: " + mNativeFailureReason;
+        }
+        return "";
+    }
+
     private List<String> findAPKsInDir(File stageDir) {
         List<String> ret = new ArrayList<>();
         if (stageDir != null && stageDir.exists()) {
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index b79953e..cfbc77c 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -4578,15 +4578,6 @@
             return false;
         }
 
-        // Check if the activity is on a sleeping display, and if it can turn it ON.
-        if (getDisplay().isSleeping()) {
-            final boolean canTurnScreenOn = !mSetToSleep || canTurnScreenOn()
-                    || canShowWhenLocked() || containsDismissKeyguardWindow();
-            if (!canTurnScreenOn) {
-                return false;
-            }
-        }
-
         // Now check whether it's really visible depending on Keyguard state, and update
         // {@link ActivityStack} internal states.
         // Inform the method if this activity is the top activity of this stack, but exclude the
@@ -4597,6 +4588,12 @@
         final boolean visibleIgnoringDisplayStatus = stack.checkKeyguardVisibility(this,
                 visibleIgnoringKeyguard, isTop && isTopNotPinnedStack);
 
+        // Check if the activity is on a sleeping display, and if it can turn it ON.
+        // TODO(b/163993448): Do not make activity visible before display awake.
+        if (visibleIgnoringDisplayStatus && getDisplay().isSleeping()) {
+            return !mSetToSleep || canTurnScreenOn();
+        }
+
         return visibleIgnoringDisplayStatus;
     }
 
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index e9768a2..2b785c5 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -1704,8 +1704,9 @@
         // If the most recent activity was noHistory but was only stopped rather
         // than stopped+finished because the device went to sleep, we need to make
         // sure to finish it as we're making a new activity topmost.
-        if (shouldSleepActivities() && mLastNoHistoryActivity != null &&
-                !mLastNoHistoryActivity.finishing) {
+        if (shouldSleepActivities() && mLastNoHistoryActivity != null
+                && !mLastNoHistoryActivity.finishing
+                && mLastNoHistoryActivity != next) {
             if (DEBUG_STATES) Slog.d(TAG_STATES,
                     "no-history finish of " + mLastNoHistoryActivity + " on new resume");
             mLastNoHistoryActivity.finishIfPossible("resume-no-history", false /* oomAdj */);
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index b378621..35ccc43 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -1481,9 +1481,10 @@
             // anyone interested in this piece of information.
             final ActivityStack homeStack = targetTask.getDisplayArea().getRootHomeTask();
             final boolean homeTaskVisible = homeStack != null && homeStack.shouldBeVisible(null);
+            final ActivityRecord top = targetTask.getTopNonFinishingActivity();
+            final boolean visible = top != null && top.isVisible();
             mService.getTaskChangeNotificationController().notifyActivityRestartAttempt(
-                    targetTask.getTaskInfo(), homeTaskVisible, clearedTask,
-                    targetTask.getTopNonFinishingActivity().isVisible());
+                    targetTask.getTaskInfo(), homeTaskVisible, clearedTask, visible);
         }
     }
 
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 0da47ca..faf3f06 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -12474,6 +12474,22 @@
         }
 
         @Override
+        public boolean isActiveDeviceOwner(int uid) {
+            synchronized (getLockObject()) {
+                return getActiveAdminWithPolicyForUidLocked(
+                        null, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER, uid) != null;
+            }
+        }
+
+        @Override
+        public boolean isActiveProfileOwner(int uid) {
+            synchronized (getLockObject()) {
+                return getActiveAdminWithPolicyForUidLocked(
+                        null, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER, uid) != null;
+            }
+        }
+
+        @Override
         public boolean isActiveSupervisionApp(int uid) {
             synchronized (getLockObject()) {
                 final ActiveAdmin admin = getActiveAdminWithPolicyForUidLocked(
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index ae693c7..2ba94e8 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -1226,7 +1226,7 @@
             mSystemServiceManager.startService(IorapForwardingService.class);
             t.traceEnd();
 
-            if (Build.IS_DEBUGGABLE) {
+            if (Build.IS_DEBUGGABLE && ProfcollectForwardingService.enabled()) {
                 t.traceBegin("ProfcollectForwardingService");
                 mSystemServiceManager.startService(ProfcollectForwardingService.class);
                 t.traceEnd();
diff --git a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
index d14ed5a..1944965 100644
--- a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
+++ b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
@@ -31,6 +31,7 @@
 import android.os.SystemProperties;
 import android.os.UpdateEngine;
 import android.os.UpdateEngineCallback;
+import android.provider.DeviceConfig;
 import android.util.Log;
 
 import com.android.server.IoThread;
@@ -68,6 +69,14 @@
         sSelfService = this;
     }
 
+    /**
+     * Check whether profcollect is enabled through device config.
+     */
+    public static boolean enabled() {
+        return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_PROFCOLLECT_NATIVE_BOOT, "enabled",
+            false);
+    }
+
     @Override
     public void onStart() {
         if (DEBUG) {
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java
index 4702940..553df3b 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java
@@ -130,6 +130,17 @@
     }
 
     @Test
+    public void isValid_setTimerProgramTitle() {
+        assertMessageValidity("40:67:47:61:6D:65:20:6F:66:20:54:68:72:6F:6E:65:73").isEqualTo(OK);
+        assertMessageValidity("40:67:4A").isEqualTo(OK);
+
+        assertMessageValidity("4F:67:47:4F:54").isEqualTo(ERROR_DESTINATION);
+        assertMessageValidity("F4:67:47:4F:54").isEqualTo(ERROR_SOURCE);
+        assertMessageValidity("40:67").isEqualTo(ERROR_PARAMETER_SHORT);
+        assertMessageValidity("40:67:47:9A:54").isEqualTo(ERROR_PARAMETER);
+    }
+
+    @Test
     public void isValid_setMenuLanguage() {
         assertMessageValidity("4F:32:53:50:41").isEqualTo(OK);
         assertMessageValidity("0F:32:45:4E:47:8C:49:D3:48").isEqualTo(OK);
@@ -182,6 +193,166 @@
         assertMessageValidity("40:0A:30").isEqualTo(ERROR_PARAMETER);
     }
 
+    @Test
+    public void isValid_setAnalogueTimer_clearAnalogueTimer() {
+        assertMessageValidity("04:33:0C:08:10:1E:04:30:08:00:13:AD:06").isEqualTo(OK);
+        assertMessageValidity("04:34:04:0C:16:0F:08:37:00:02:EA:60:03:34").isEqualTo(OK);
+
+        assertMessageValidity("0F:33:0C:08:10:1E:04:30:08:00:13:AD:06")
+                .isEqualTo(ERROR_DESTINATION);
+        assertMessageValidity("F0:34:04:0C:16:0F:08:37:00:02:EA:60:03").isEqualTo(ERROR_SOURCE);
+        assertMessageValidity("04:33:0C:08:10:1E:04:30:08:13:AD:06")
+                .isEqualTo(ERROR_PARAMETER_SHORT);
+        // Out of range Day of Month
+        assertMessageValidity("04:34:20:0C:16:0F:08:37:00:02:EA:60:03").isEqualTo(ERROR_PARAMETER);
+        // Out of range Month of Year
+        assertMessageValidity("04:33:0C:00:10:1E:04:30:08:00:13:AD:06").isEqualTo(ERROR_PARAMETER);
+        // Out of range Start Time - Hour
+        assertMessageValidity("04:34:04:0C:18:0F:08:37:00:02:EA:60:03").isEqualTo(ERROR_PARAMETER);
+        // Out of range Start Time - Minute
+        assertMessageValidity("04:33:0C:08:10:50:04:30:08:00:13:AD:06").isEqualTo(ERROR_PARAMETER);
+        // Out of range Duration - Duration Hours
+        assertMessageValidity("04:34:04:0C:16:0F:64:37:00:02:EA:60:03").isEqualTo(ERROR_PARAMETER);
+        // Out of range Duration - Minute
+        assertMessageValidity("04:33:0C:08:10:1E:04:64:08:00:13:AD:06").isEqualTo(ERROR_PARAMETER);
+        // Invalid Recording Sequence
+        assertMessageValidity("04:34:04:0C:16:0F:08:37:88:02:EA:60:03").isEqualTo(ERROR_PARAMETER);
+        // Invalid Recording Sequence
+        assertMessageValidity("04:33:0C:08:10:1E:04:30:A2:00:13:AD:06").isEqualTo(ERROR_PARAMETER);
+        // Out of range Analogue Broadcast Type
+        assertMessageValidity("04:34:04:0C:16:0F:08:37:00:03:EA:60:03").isEqualTo(ERROR_PARAMETER);
+        // Out of range Analogue Frequency
+        assertMessageValidity("04:33:0C:08:10:1E:04:30:08:00:FF:FF:06").isEqualTo(ERROR_PARAMETER);
+        // Out of range Broadcast System
+        assertMessageValidity("04:34:04:0C:16:0F:08:37:00:02:EA:60:20").isEqualTo(ERROR_PARAMETER);
+    }
+
+    @Test
+    public void isValid_setDigitalTimer_clearDigitalTimer() {
+        // Services identified by Digital IDs - ARIB Broadcast System
+        assertMessageValidity("04:99:0C:08:15:05:04:1E:00:00:C4:C2:11:D8:75:30").isEqualTo(OK);
+        // Service identified by Digital IDs - ATSC Broadcast System
+        assertMessageValidity("04:97:1E:07:12:20:50:28:01:01:8B:5E:39:5A").isEqualTo(OK);
+        // Service identified by Digital IDs - DVB Broadcast System
+        assertMessageValidity("04:99:05:0C:06:0A:19:3B:40:19:8B:44:03:11:04:FC").isEqualTo(OK);
+        // Service identified by Channel - 1 part channel number
+        assertMessageValidity("04:97:12:06:0C:2D:5A:19:08:91:04:00:B1").isEqualTo(OK);
+        // Service identified by Channel - 2 part channel number
+        assertMessageValidity("04:99:15:09:00:0F:00:2D:04:82:09:C8:72:C8").isEqualTo(OK);
+
+        assertMessageValidity("4F:97:0C:08:15:05:04:1E:00:00:C4:C2:11:D8:75:30")
+                .isEqualTo(ERROR_DESTINATION);
+        assertMessageValidity("F0:99:15:09:00:0F:00:2D:04:82:09:C8:72:C8").isEqualTo(ERROR_SOURCE);
+        assertMessageValidity("04:97:1E:12:20:58:01:01:8B:5E:39:5A")
+                .isEqualTo(ERROR_PARAMETER_SHORT);
+        // Out of range Day of Month
+        assertMessageValidity("04:99:24:0C:06:0A:19:3B:40:19:8B:44:03:11:04:FC")
+                .isEqualTo(ERROR_PARAMETER);
+        // Out of range Month of Year
+        assertMessageValidity("04:97:12:10:0C:2D:5A:19:08:91:04:00:B1").isEqualTo(ERROR_PARAMETER);
+        // Out of range Start Time - Hour
+        assertMessageValidity("04:99:0C:08:20:05:04:1E:00:00:C4:C2:11:D8:75:30")
+                .isEqualTo(ERROR_PARAMETER);
+        // Out of range Start Time - Minute
+        assertMessageValidity("04:97:15:09:00:4B:00:2D:04:82:09:C8:72:C8")
+                .isEqualTo(ERROR_PARAMETER);
+        // Out of range Duration - Duration Hours
+        assertMessageValidity("04:99:1E:07:12:20:78:28:01:01:8B:5E:39:5A")
+                .isEqualTo(ERROR_PARAMETER);
+        // Out of range Duration - Minute
+        assertMessageValidity("04:97:05:0C:06:0A:19:48:40:19:8B:44:03:11:04:FC")
+                .isEqualTo(ERROR_PARAMETER);
+        // Invalid Recording Sequence
+        assertMessageValidity("04:99:12:06:0C:2D:5A:19:90:91:04:00:B1").isEqualTo(ERROR_PARAMETER);
+        // Invalid Recording Sequence
+        assertMessageValidity("04:97:0C:08:15:05:04:1E:21:00:C4:C2:11:D8:75:30")
+                .isEqualTo(ERROR_PARAMETER);
+
+        // Invalid Digital Broadcast System
+        assertMessageValidity("04:99:1E:07:12:20:50:28:01:04:8B:5E:39:5A")
+                .isEqualTo(ERROR_PARAMETER);
+        // Invalid Digital Broadcast System
+        assertMessageValidity("04:97:05:0C:06:0A:19:3B:40:93:8B:44:03:11:04:FC")
+                .isEqualTo(ERROR_PARAMETER);
+        // Insufficient data for ARIB Broadcast system
+        assertMessageValidity("04:99:0C:08:15:05:04:1E:00:00:C4:C2:11:D8:75")
+                .isEqualTo(ERROR_PARAMETER);
+        // Insufficient data for ATSC Broadcast system
+        assertMessageValidity("04:97:1E:07:12:20:50:28:01:01:8B:5E:39").isEqualTo(ERROR_PARAMETER);
+        // Insufficient data for DVB Broadcast system
+        assertMessageValidity("04:99:05:0C:06:0A:19:3B:40:19:8B:44:03:11:04")
+                .isEqualTo(ERROR_PARAMETER);
+        // Insufficient data for 2 part channel number
+        assertMessageValidity("04:97:15:09:00:0F:00:2D:04:82:09:C8:72").isEqualTo(ERROR_PARAMETER);
+        // Invalid Channel Number format
+        assertMessageValidity("04:99:12:06:0C:2D:5A:19:08:91:0D:00:B1").isEqualTo(ERROR_PARAMETER);
+    }
+
+    @Test
+    public void isValid_setExternalTimer_clearExternalTimer() {
+        assertMessageValidity("40:A1:0C:08:15:05:04:1E:02:04:20").isEqualTo(OK);
+        assertMessageValidity("40:A2:14:09:12:28:4B:19:10:05:10:00").isEqualTo(OK);
+
+        assertMessageValidity("4F:A1:0C:08:15:05:04:1E:02:04:20").isEqualTo(ERROR_DESTINATION);
+        assertMessageValidity("F4:A2:14:09:12:28:4B:19:10:05:10:00").isEqualTo(ERROR_SOURCE);
+        assertMessageValidity("40:A1:0C:08:15:05:04:1E:02:04").isEqualTo(ERROR_PARAMETER_SHORT);
+        // Out of range Day of Month
+        assertMessageValidity("40:A2:28:09:12:28:4B:19:10:05:10:00").isEqualTo(ERROR_PARAMETER);
+        // Out of range Month of Year
+        assertMessageValidity("40:A1:0C:0F:15:05:04:1E:02:04:20").isEqualTo(ERROR_PARAMETER);
+        // Out of range Start Time - Hour
+        assertMessageValidity("40:A2:14:09:1A:28:4B:19:10:05:10:00").isEqualTo(ERROR_PARAMETER);
+        // Out of range Start Time - Minute
+        assertMessageValidity("40:A1:0C:08:15:48:04:1E:02:04:20").isEqualTo(ERROR_PARAMETER);
+        // Out of range Duration - Duration Hours
+        assertMessageValidity("40:A2:14:09:12:28:66:19:10:05:10:00").isEqualTo(ERROR_PARAMETER);
+        // Out of range Duration - Minute
+        assertMessageValidity("40:A1:0C:08:15:05:04:3F:02:04:20").isEqualTo(ERROR_PARAMETER);
+        // Invalid Recording Sequence
+        assertMessageValidity("40:A2:14:09:12:28:4B:19:84:05:10:00").isEqualTo(ERROR_PARAMETER);
+        // Invalid Recording Sequence
+        assertMessageValidity("40:A1:0C:08:15:05:04:1E:14:04:20").isEqualTo(ERROR_PARAMETER);
+        // Invalid external source specifier
+        assertMessageValidity("40:A2:14:09:12:28:4B:19:10:08:10:00").isEqualTo(ERROR_PARAMETER);
+        // Invalid External PLug
+        assertMessageValidity("04:A1:0C:08:15:05:04:1E:02:04:00").isEqualTo(ERROR_PARAMETER);
+    }
+
+    @Test
+    public void isValid_timerClearedStatus() {
+        assertMessageValidity("40:43:01:7E").isEqualTo(OK);
+        assertMessageValidity("40:43:80").isEqualTo(OK);
+
+        assertMessageValidity("4F:43:01").isEqualTo(ERROR_DESTINATION);
+        assertMessageValidity("F0:43:80").isEqualTo(ERROR_SOURCE);
+        assertMessageValidity("40:43").isEqualTo(ERROR_PARAMETER_SHORT);
+        assertMessageValidity("40:43:03").isEqualTo(ERROR_PARAMETER);
+    }
+
+    @Test
+    public void isValid_timerStatus() {
+        // Programmed - Space available
+        assertMessageValidity("40:35:58").isEqualTo(OK);
+        // Programmed - Not enough space available
+        assertMessageValidity("40:35:B9:32:1C:4F").isEqualTo(OK);
+        // Not programmed - Date out of range
+        assertMessageValidity("40:35:82:3B").isEqualTo(OK);
+        // Not programmed - Duplicate
+        assertMessageValidity("40:35:EE:52:0C").isEqualTo(OK);
+
+        assertMessageValidity("4F:35:58").isEqualTo(ERROR_DESTINATION);
+        assertMessageValidity("F0:35:82").isEqualTo(ERROR_SOURCE);
+        assertMessageValidity("40:35").isEqualTo(ERROR_PARAMETER_SHORT);
+        // Programmed - Invalid programmed info
+        assertMessageValidity("40:35:BD").isEqualTo(ERROR_PARAMETER);
+        // Non programmed - Invalid not programmed error info
+        assertMessageValidity("40:35:DE").isEqualTo(ERROR_PARAMETER);
+        // Programmed - Might not be enough space available - Invalid duration hours
+        assertMessageValidity("40:35:BB:96:1C").isEqualTo(ERROR_PARAMETER);
+        // Not programmed - Duplicate - Invalid duration minutes
+        assertMessageValidity("40:35:EE:52:4A").isEqualTo(ERROR_PARAMETER);
+    }
+
     private IntegerSubject assertMessageValidity(String message) {
         return assertThat(mHdmiCecMessageValidator.isValid(buildMessage(message)));
     }
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index c7b45ef..6ab0697 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -1100,6 +1100,34 @@
     }
 
     /**
+     * Verify the visibility of a show-when-locked and dismiss keyguard activity on sleeping
+     * display.
+     */
+    @Test
+    public void testDisplaySleeping_activityInvisible() {
+        final KeyguardController keyguardController =
+                mActivity.mStackSupervisor.getKeyguardController();
+        doReturn(true).when(keyguardController).isKeyguardLocked();
+        final ActivityRecord topActivity = new ActivityBuilder(mService).setTask(mTask).build();
+        topActivity.mVisibleRequested = true;
+        topActivity.nowVisible = true;
+        topActivity.setState(RESUMED, "test" /*reason*/);
+        doReturn(true).when(topActivity).containsDismissKeyguardWindow();
+        doCallRealMethod().when(mRootWindowContainer).ensureActivitiesVisible(
+                any() /* starting */, anyInt() /* configChanges */,
+                anyBoolean() /* preserveWindows */, anyBoolean() /* notifyClients */);
+        topActivity.setShowWhenLocked(true);
+
+        // Verify the top activity is occluded keyguard.
+        assertEquals(topActivity, mStack.topRunningActivity());
+        assertTrue(mStack.topActivityOccludesKeyguard());
+
+        final DisplayContent display = mActivity.mDisplayContent;
+        doReturn(true).when(display).isSleeping();
+        assertFalse(topActivity.shouldBeVisible());
+    }
+
+    /**
      * Verify that complete finish request for a show-when-locked activity must ensure the
      * keyguard occluded state being updated.
      */
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index a85eb53..1238e7b 100755
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -1468,8 +1468,11 @@
 
         /**
          * Writes the string {@param input} into the outgoing text stream for this RTT call. Since
-         * RTT transmits text in real-time, this method should be called once for each character
-         * the user enters into the device.
+         * RTT transmits text in real-time, this method should be called once for each user action.
+         * For example, when the user enters text as discrete characters using the keyboard, this
+         * method should be called once for each character. However, if the user enters text by
+         * pasting or autocomplete, the entire contents of the pasted or autocompleted text should
+         * be sent in one call to this method.
          *
          * This method is not thread-safe -- calling it from multiple threads simultaneously may
          * lead to interleaved text.
diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java
index a3cc0ab..2de1599 100644
--- a/telephony/java/android/telephony/SmsManager.java
+++ b/telephony/java/android/telephony/SmsManager.java
@@ -1721,6 +1721,7 @@
      *
      * {@hide}
      */
+    @UnsupportedAppUsage
     @RequiresPermission(Manifest.permission.ACCESS_MESSAGES_ON_ICC)
     public boolean deleteMessageFromIcc(int messageIndex) {
         boolean success = false;
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 2e51ef1..3aa9345 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -1365,6 +1365,7 @@
      * include those that were inserted before, maybe empty but not null.
      * @hide
      */
+    @NonNull
     @UnsupportedAppUsage
     public List<SubscriptionInfo> getAllSubscriptionInfoList() {
         if (VDBG) logd("[getAllSubscriptionInfoList]+");
@@ -1382,7 +1383,7 @@
         }
 
         if (result == null) {
-            result = new ArrayList<>();
+            result = Collections.emptyList();
         }
         return result;
     }
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 0e327b4..5f3fd60 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -305,6 +305,8 @@
     private static boolean sServiceHandleCacheEnabled = true;
 
     @GuardedBy("sCacheLock")
+    private static ITelephony sITelephony;
+    @GuardedBy("sCacheLock")
     private static IPhoneSubInfo sIPhoneSubInfo;
     @GuardedBy("sCacheLock")
     private static ISub sISub;
@@ -4185,7 +4187,7 @@
         }
     }
 
-   /**
+    /**
      * @param keyAvailability bitmask that defines the availabilty of keys for a type.
      * @param keyType the key type which is being checked. (WLAN, EPDG)
      * @return true if the digit at position keyType is 1, else false.
@@ -5504,13 +5506,39 @@
         }
     }
 
-   /**
-    * @hide
-    */
+    /**
+     * @hide
+     */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
     private ITelephony getITelephony() {
-        return ITelephony.Stub.asInterface(TelephonyFrameworkInitializer
-                .getTelephonyServiceManager().getTelephonyServiceRegisterer().get());
+        // Keeps cache disabled until test fixes are checked into AOSP.
+        if (!sServiceHandleCacheEnabled) {
+            return ITelephony.Stub.asInterface(
+                    TelephonyFrameworkInitializer
+                            .getTelephonyServiceManager()
+                            .getTelephonyServiceRegisterer()
+                            .get());
+        }
+
+        if (sITelephony == null) {
+            ITelephony temp = ITelephony.Stub.asInterface(
+                    TelephonyFrameworkInitializer
+                            .getTelephonyServiceManager()
+                            .getTelephonyServiceRegisterer()
+                            .get());
+            synchronized (sCacheLock) {
+                if (sITelephony == null && temp != null) {
+                    try {
+                        sITelephony = temp;
+                        sITelephony.asBinder().linkToDeath(sServiceDeath, 0);
+                    } catch (Exception e) {
+                        // something has gone horribly wrong
+                        sITelephony = null;
+                    }
+                }
+            }
+        }
+        return sITelephony;
     }
 
     private IOns getIOns() {
@@ -13430,6 +13458,149 @@
         }
     }
 
+    /**
+     * No error. Operation succeeded.
+     * @hide
+     */
+    @SystemApi
+    public static final int ENABLE_NR_DUAL_CONNECTIVITY_SUCCESS = 0;
+
+    /**
+     * NR Dual connectivity enablement is not supported.
+     * @hide
+     */
+    @SystemApi
+    public static final int ENABLE_NR_DUAL_CONNECTIVITY_NOT_SUPPORTED = 1;
+
+    /**
+     * Radio is not available.
+     * @hide
+     */
+    @SystemApi
+    public static final int ENABLE_NR_DUAL_CONNECTIVITY_RADIO_NOT_AVAILABLE = 2;
+
+    /**
+     * Internal Radio error.
+     * @hide
+     */
+    @SystemApi
+    public static final int ENABLE_NR_DUAL_CONNECTIVITY_RADIO_ERROR = 3;
+
+    /**
+     * Currently in invalid state. Not able to process the request.
+     * @hide
+     */
+    @SystemApi
+    public static final int ENABLE_NR_DUAL_CONNECTIVITY_INVALID_STATE = 4;
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = {"ENABLE_NR_DUAL_CONNECTIVITY"}, value = {
+            ENABLE_NR_DUAL_CONNECTIVITY_SUCCESS,
+            ENABLE_NR_DUAL_CONNECTIVITY_NOT_SUPPORTED,
+            ENABLE_NR_DUAL_CONNECTIVITY_INVALID_STATE,
+            ENABLE_NR_DUAL_CONNECTIVITY_RADIO_NOT_AVAILABLE,
+            ENABLE_NR_DUAL_CONNECTIVITY_RADIO_ERROR})
+    public @interface EnableNrDualConnectivityResult {}
+
+    /**
+     * Enable NR dual connectivity. Enabled state does not mean dual connectivity
+     * is active. It means device is allowed to connect to both primary and secondary.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final int NR_DUAL_CONNECTIVITY_ENABLE = 1;
+
+    /**
+     * Disable NR dual connectivity. Disabled state does not mean the secondary cell is released.
+     * Modem will release it only if the current bearer is released to avoid radio link failure.
+     * @hide
+     */
+    @SystemApi
+    public static final int NR_DUAL_CONNECTIVITY_DISABLE = 2;
+
+    /**
+     * Disable NR dual connectivity and force the secondary cell to be released if dual connectivity
+     * was active. This will result in radio link failure.
+     * @hide
+     */
+    @SystemApi
+    public static final int NR_DUAL_CONNECTIVITY_DISABLE_IMMEDIATE = 3;
+
+    /**
+     * @hide
+     */
+    @IntDef(prefix = { "NR_DUAL_CONNECTIVITY_" }, value = {
+            NR_DUAL_CONNECTIVITY_ENABLE,
+            NR_DUAL_CONNECTIVITY_DISABLE,
+            NR_DUAL_CONNECTIVITY_DISABLE_IMMEDIATE,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface NrDualConnectivityState {
+    }
+
+    /**
+     * Enable/Disable E-UTRA-NR Dual Connectivity.
+     *
+     * @param nrDualConnectivityState expected NR dual connectivity state
+     * This can be passed following states
+     * <ol>
+     * <li>Enable NR dual connectivity {@link #NR_DUAL_CONNECTIVITY_ENABLE}
+     * <li>Disable NR dual connectivity {@link #NR_DUAL_CONNECTIVITY_DISABLE}
+     * <li>Disable NR dual connectivity and force secondary cell to be released
+     * {@link #NR_DUAL_CONNECTIVITY_DISABLE_IMMEDIATE}
+     * </ol>
+     * @return operation result.
+     * <p>Requires Permission:
+     * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
+     * @throws IllegalStateException if the Telephony process is not currently available.
+     * @hide
+     */
+    @SystemApi
+    public @EnableNrDualConnectivityResult int setNrDualConnectivityState(
+            @NrDualConnectivityState int nrDualConnectivityState) {
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                return telephony.setNrDualConnectivityState(getSubId(), nrDualConnectivityState);
+            } else {
+                throw new IllegalStateException("telephony service is null.");
+            }
+        } catch (RemoteException ex) {
+            Rlog.e(TAG, "setNrDualConnectivityState RemoteException", ex);
+            ex.rethrowFromSystemServer();
+        }
+
+        return ENABLE_NR_DUAL_CONNECTIVITY_INVALID_STATE;
+    }
+
+    /**
+     * Is E-UTRA-NR Dual Connectivity enabled.
+     * @return true if dual connectivity is enabled else false. Enabled state does not mean dual
+     * connectivity is active. It means the device is allowed to connect to both primary and
+     * secondary cell.
+     * <p>Requires Permission:
+     * {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE READ_PRIVILEGED_PHONE_STATE}
+     * @throws IllegalStateException if the Telephony process is not currently available.
+     * @hide
+     */
+    @SystemApi
+    public boolean isNrDualConnectivityEnabled() {
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                return telephony.isNrDualConnectivityEnabled(getSubId());
+            } else {
+                throw new IllegalStateException("telephony service is null.");
+            }
+        } catch (RemoteException ex) {
+            Rlog.e(TAG, "isNRDualConnectivityEnabled RemoteException", ex);
+            ex.rethrowFromSystemServer();
+        }
+        return false;
+    }
+
     private static class DeathRecipient implements IBinder.DeathRecipient {
         @Override
         public void binderDied() {
@@ -13444,6 +13615,10 @@
     */
     private static void resetServiceCache() {
         synchronized (sCacheLock) {
+            if (sITelephony != null) {
+                sITelephony.asBinder().unlinkToDeath(sServiceDeath, 0);
+                sITelephony = null;
+            }
             if (sISub != null) {
                 sISub.asBinder().unlinkToDeath(sServiceDeath, 0);
                 sISub = null;
@@ -13460,9 +13635,9 @@
         }
     }
 
-   /**
-    * @hide
-    */
+    /**
+     * @hide
+     */
     static IPhoneSubInfo getSubscriberInfoService() {
         // Keeps cache disabled until test fixes are checked into AOSP.
         if (!sServiceHandleCacheEnabled) {
diff --git a/telephony/java/android/telephony/ims/AudioCodecAttributes.aidl b/telephony/java/android/telephony/ims/AudioCodecAttributes.aidl
new file mode 100644
index 0000000..bbab548
--- /dev/null
+++ b/telephony/java/android/telephony/ims/AudioCodecAttributes.aidl
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2020 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.telephony.ims;
+
+parcelable AudioCodecAttributes;
diff --git a/telephony/java/android/telephony/ims/AudioCodecAttributes.java b/telephony/java/android/telephony/ims/AudioCodecAttributes.java
new file mode 100644
index 0000000..7b6ab00
--- /dev/null
+++ b/telephony/java/android/telephony/ims/AudioCodecAttributes.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2020 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.telephony.ims;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Range;
+
+/**
+ * Parcelable object to handle audio codec attributes.
+ * It provides the audio codec bitrate, bandwidth and their upper/lower bound.
+ *
+ * @hide
+ */
+@SystemApi
+public final class AudioCodecAttributes implements Parcelable {
+    // The audio codec bitrate in kbps.
+    private float mBitrateKbps;
+    // The range of the audio codec bitrate in kbps.
+    private Range<Float> mBitrateRangeKbps;
+    // The audio codec bandwidth in kHz.
+    private float mBandwidthKhz;
+    // The range of the audio codec bandwidth in kHz.
+    private Range<Float> mBandwidthRangeKhz;
+
+
+    /**
+     * Constructor.
+     *
+     * @param bitrateKbps        The audio codec bitrate in kbps.
+     * @param bitrateRangeKbps  The range of the audio codec bitrate in kbps.
+     * @param bandwidthKhz      The audio codec bandwidth in kHz.
+     * @param bandwidthRangeKhz The range of the audio codec bandwidth in kHz.
+     */
+
+    public AudioCodecAttributes(float bitrateKbps, @NonNull Range<Float> bitrateRangeKbps,
+            float bandwidthKhz, @NonNull Range<Float> bandwidthRangeKhz) {
+        mBitrateKbps = bitrateKbps;
+        mBitrateRangeKbps = bitrateRangeKbps;
+        mBandwidthKhz = bandwidthKhz;
+        mBandwidthRangeKhz = bandwidthRangeKhz;
+    }
+
+    private AudioCodecAttributes(Parcel in) {
+        mBitrateKbps = in.readFloat();
+        mBitrateRangeKbps = new Range<>(in.readFloat(), in.readFloat());
+        mBandwidthKhz = in.readFloat();
+        mBandwidthRangeKhz = new Range<>(in.readFloat(), in.readFloat());
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel out, int flags) {
+        out.writeFloat(mBitrateKbps);
+        out.writeFloat(mBitrateRangeKbps.getLower());
+        out.writeFloat(mBitrateRangeKbps.getUpper());
+        out.writeFloat(mBandwidthKhz);
+        out.writeFloat(mBandwidthRangeKhz.getLower());
+        out.writeFloat(mBandwidthRangeKhz.getUpper());
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    public static final @NonNull Creator<AudioCodecAttributes> CREATOR =
+            new Creator<AudioCodecAttributes>() {
+                @Override
+                public AudioCodecAttributes createFromParcel(Parcel in) {
+                    return new AudioCodecAttributes(in);
+                }
+
+                @Override
+                public AudioCodecAttributes[] newArray(int size) {
+                    return new AudioCodecAttributes[size];
+                }
+            };
+
+    /**
+     * @return the exact value of the audio codec bitrate in kbps.
+     */
+    public float getBitrateKbps() {
+        return mBitrateKbps;
+    }
+
+    /**
+     * @return the range of the audio codec bitrate in kbps
+     */
+    public @NonNull Range<Float> getBitrateRangeKbps() {
+        return mBitrateRangeKbps;
+    }
+
+    /**
+     * @return the exact value of the audio codec bandwidth in kHz.
+     */
+    public float getBandwidthKhz() {
+        return mBandwidthKhz;
+    }
+
+    /**
+     * @return the range of the audio codec bandwidth in kHz.
+     */
+    public @NonNull Range<Float> getBandwidthRangeKhz() {
+        return mBandwidthRangeKhz;
+    }
+
+    @NonNull
+    @Override
+    public String toString() {
+        return "{ bitrateKbps=" + mBitrateKbps
+                + ", bitrateRangeKbps=" + mBitrateRangeKbps
+                + ", bandwidthKhz=" + mBandwidthKhz
+                + ", bandwidthRangeKhz=" + mBandwidthRangeKhz + " }";
+    }
+}
diff --git a/telephony/java/android/telephony/ims/ImsCallProfile.java b/telephony/java/android/telephony/ims/ImsCallProfile.java
index 47a0ab6..dcb8736 100644
--- a/telephony/java/android/telephony/ims/ImsCallProfile.java
+++ b/telephony/java/android/telephony/ims/ImsCallProfile.java
@@ -28,6 +28,8 @@
 import android.telephony.emergency.EmergencyNumber;
 import android.telephony.emergency.EmergencyNumber.EmergencyCallRouting;
 import android.telephony.emergency.EmergencyNumber.EmergencyServiceCategories;
+import android.telephony.ims.feature.MmTelFeature;
+import android.util.ArraySet;
 import android.util.Log;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -37,7 +39,10 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
 
 /**
  * A Parcelable object to handle the IMS call profile, which provides the service, call type, and
@@ -444,6 +449,10 @@
     /** Indicates if we have known the intent of the user for the call is emergency */
     private boolean mHasKnownUserIntentEmergency = false;
 
+    private Set<RtpHeaderExtensionType> mOfferedRtpHeaderExtensionTypes = new ArraySet<>();
+
+    private Set<RtpHeaderExtensionType> mAcceptedRtpHeaderExtensionTypes = new ArraySet<>();
+
     /**
      * Extras associated with this {@link ImsCallProfile}.
      * <p>
@@ -682,6 +691,8 @@
         out.writeBoolean(mHasKnownUserIntentEmergency);
         out.writeInt(mRestrictCause);
         out.writeInt(mCallerNumberVerificationStatus);
+        out.writeArray(mOfferedRtpHeaderExtensionTypes.toArray());
+        out.writeArray(mAcceptedRtpHeaderExtensionTypes.toArray());
     }
 
     private void readFromParcel(Parcel in) {
@@ -696,9 +707,16 @@
         mHasKnownUserIntentEmergency = in.readBoolean();
         mRestrictCause = in.readInt();
         mCallerNumberVerificationStatus = in.readInt();
+        Object[] offered = in.readArray(RtpHeaderExtensionType.class.getClassLoader());
+        mOfferedRtpHeaderExtensionTypes = Arrays.stream(offered)
+                .map(o -> (RtpHeaderExtensionType) o).collect(Collectors.toSet());
+        Object[] accepted = in.readArray(RtpHeaderExtensionType.class.getClassLoader());
+        mAcceptedRtpHeaderExtensionTypes = Arrays.stream(accepted)
+                .map(o -> (RtpHeaderExtensionType) o).collect(Collectors.toSet());
     }
 
-    public static final @android.annotation.NonNull Creator<ImsCallProfile> CREATOR = new Creator<ImsCallProfile>() {
+    public static final @android.annotation.NonNull Creator<ImsCallProfile> CREATOR =
+            new Creator<ImsCallProfile>() {
         @Override
         public ImsCallProfile createFromParcel(Parcel in) {
             return new ImsCallProfile(in);
@@ -1085,4 +1103,66 @@
     public boolean hasKnownUserIntentEmergency() {
         return mHasKnownUserIntentEmergency;
     }
+
+    /**
+     * For an incoming or outgoing call, indicates the {@link RtpHeaderExtensionType}s which the
+     * caller is offering to make available.
+     * <p>
+     * For outgoing calls, an {@link ImsService} will reserve
+     * {@link RtpHeaderExtensionType#getLocalIdentifier()} identifiers the telephony stack has
+     * proposed to use and not use these same local identifiers.  The offered header extension
+     * types for an outgoing call can be found in the
+     * {@link ImsCallProfile#getOfferedRtpHeaderExtensionTypes()} and will be available to the
+     * {@link ImsService} in {@link MmTelFeature#createCallSession(ImsCallProfile)}.
+     * The {@link ImsService} sets the accepted {@link #setAcceptedRtpHeaderExtensionTypes(Set)}
+     * when the SDP offer/accept process has completed.
+     * <p>
+     * According to RFC8285, RTP header extensions available to a call are determined using the
+     * offer/accept phase of the SDP protocol (see RFC4566).
+     *
+     * @return the {@link RtpHeaderExtensionType}s which were offered by other end of the call.
+     */
+    public @NonNull Set<RtpHeaderExtensionType> getOfferedRtpHeaderExtensionTypes() {
+        return mOfferedRtpHeaderExtensionTypes;
+    }
+
+    /**
+     * Sets the offered {@link RtpHeaderExtensionType}s for this call.
+     * <p>
+     * According to RFC8285, RTP header extensions available to a call are determined using the
+     * offer/accept phase of the SDP protocol (see RFC4566).
+     *
+     * @param rtpHeaderExtensions the {@link RtpHeaderExtensionType}s which are offered.
+     */
+    public void setOfferedRtpHeaderExtensionTypes(@NonNull Set<RtpHeaderExtensionType>
+                    rtpHeaderExtensions) {
+        mOfferedRtpHeaderExtensionTypes.clear();
+        mOfferedRtpHeaderExtensionTypes.addAll(rtpHeaderExtensions);
+    }
+
+    /**
+     * Gets the {@link RtpHeaderExtensionType}s which have been accepted by both ends of the call.
+     * <p>
+     * According to RFC8285, RTP header extensions available to a call are determined using the
+     * offer/accept phase of the SDP protocol (see RFC4566).
+     *
+     * @return the {@link RtpHeaderExtensionType}s which were accepted by the other end of the call.
+     */
+    public @NonNull Set<RtpHeaderExtensionType> getAcceptedRtpHeaderExtensionTypes() {
+        return mAcceptedRtpHeaderExtensionTypes;
+    }
+
+    /**
+     * Sets the accepted {@link RtpHeaderExtensionType}s for this call.
+     * <p>
+     * According to RFC8285, RTP header extensions available to a call are determined using the
+     * offer/accept phase of the SDP protocol (see RFC4566).
+     *
+     * @param rtpHeaderExtensions
+     */
+    public void setAcceptedRtpHeaderExtensionTypes(@NonNull Set<RtpHeaderExtensionType>
+            rtpHeaderExtensions) {
+        mAcceptedRtpHeaderExtensionTypes.clear();
+        mAcceptedRtpHeaderExtensionTypes.addAll(rtpHeaderExtensions);
+    }
 }
diff --git a/telephony/java/android/telephony/ims/ImsCallSession.java b/telephony/java/android/telephony/ims/ImsCallSession.java
index 8857b9b..a3efb79 100755
--- a/telephony/java/android/telephony/ims/ImsCallSession.java
+++ b/telephony/java/android/telephony/ims/ImsCallSession.java
@@ -22,11 +22,16 @@
 import android.os.RemoteException;
 import android.telephony.CallQuality;
 import android.telephony.ims.aidl.IImsCallSessionListener;
+import android.util.ArraySet;
 import android.util.Log;
 
 import com.android.ims.internal.IImsCallSession;
 import com.android.ims.internal.IImsVideoCallProvider;
 
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
 /**
  * Provides the call initiation/termination, and media exchange between two IMS endpoints.
  * It directly communicates with IMS service which implements the IMS protocol behavior.
@@ -468,11 +473,31 @@
         }
 
         /**
+         * Informs the framework of a DTMF digit which was received from the network.
+         * <p>
+         * According to <a href="http://tools.ietf.org/html/rfc2833">RFC 2833 sec 3.10</a>,
+         * event 0 ~ 9 maps to decimal value 0 ~ 9, '*' to 10, '#' to 11, event 'A' ~ 'D' to
+         * 12 ~ 15.
+         * @param digit the DTMF digit
+         */
+        public void callSessionDtmfReceived(char digit) {
+            // no-op
+        }
+
+        /**
          * Called when the IMS service reports a change to the call quality.
          */
         public void callQualityChanged(CallQuality callQuality) {
             // no-op
         }
+
+        /**
+         * Called when the IMS service reports incoming RTP header extension data.
+         */
+        public void callSessionRtpHeaderExtensionsReceived(
+                @NonNull Set<RtpHeaderExtension> extensions) {
+            // no-op
+        }
     }
 
     private final IImsCallSession miSession;
@@ -1119,6 +1144,31 @@
     }
 
     /**
+     * Requests that {@code rtpHeaderExtensions} are sent as a header extension with the next
+     * RTP packet sent by the IMS stack.
+     * <p>
+     * The {@link RtpHeaderExtensionType}s negotiated during SDP (Session Description Protocol)
+     * signalling determine the {@link RtpHeaderExtension}s which can be sent using this method.
+     * See RFC8285 for more information.
+     * <p>
+     * By specification, the RTP header extension is an unacknowledged transmission and there is no
+     * guarantee that the header extension will be delivered by the network to the other end of the
+     * call.
+     * @param rtpHeaderExtensions The header extensions to be included in the next RTP header.
+     */
+    public void sendRtpHeaderExtensions(@NonNull Set<RtpHeaderExtension> rtpHeaderExtensions) {
+        if (mClosed) {
+            return;
+        }
+
+        try {
+            miSession.sendRtpHeaderExtensions(
+                    new ArrayList<RtpHeaderExtension>(rtpHeaderExtensions));
+        } catch (RemoteException e) {
+        }
+    }
+
+    /**
      * A listener type for receiving notification on IMS call session events.
      * When an event is generated for an {@link IImsCallSession},
      * the application is notified by having one of the methods called on
@@ -1477,6 +1527,17 @@
         }
 
         /**
+         * DTMF digit received.
+         * @param dtmf The DTMF digit.
+         */
+        @Override
+        public void callSessionDtmfReceived(char dtmf) {
+            if (mListener != null) {
+                mListener.callSessionDtmfReceived(dtmf);
+            }
+        }
+
+        /**
          * Call quality updated
          */
         @Override
@@ -1485,6 +1546,19 @@
                 mListener.callQualityChanged(callQuality);
             }
         }
+
+        /**
+         * RTP header extension data received.
+         * @param extensions The header extension data.
+         */
+        @Override
+        public void callSessionRtpHeaderExtensionsReceived(
+                @NonNull List<RtpHeaderExtension> extensions) {
+            if (mListener != null) {
+                mListener.callSessionRtpHeaderExtensionsReceived(
+                        new ArraySet<RtpHeaderExtension>(extensions));
+            }
+        }
     }
 
     /**
diff --git a/telephony/java/android/telephony/ims/ImsCallSessionListener.java b/telephony/java/android/telephony/ims/ImsCallSessionListener.java
index 2fdd195..86bb5d9 100644
--- a/telephony/java/android/telephony/ims/ImsCallSessionListener.java
+++ b/telephony/java/android/telephony/ims/ImsCallSessionListener.java
@@ -28,6 +28,10 @@
 
 import com.android.ims.internal.IImsCallSession;
 
+import java.util.ArrayList;
+import java.util.Objects;
+import java.util.Set;
+
 /**
  * Listener interface for notifying the Framework's {@link ImsCallSession} for updates to an ongoing
  * IMS call.
@@ -683,6 +687,59 @@
     }
 
     /**
+     * The {@link ImsService} calls this method to inform the framework of a DTMF digit which was
+     * received from the network.
+     * <p>
+     * According to <a href="http://tools.ietf.org/html/rfc2833">RFC 2833 sec 3.10</a>,
+     * event 0 ~ 9 maps to decimal value 0 ~ 9, '*' to 10, '#' to 11, event 'A' ~ 'D' to 12 ~ 15.
+     * <p>
+     * <em>Note:</em> Alpha DTMF digits are converted from lower-case to upper-case.
+     *
+     * @param dtmf The DTMF digit received, '0'-'9', *, #, A, B, C, or D.
+     * @throws IllegalArgumentException If an invalid DTMF character is provided.
+     */
+    public void callSessionDtmfReceived(char dtmf) {
+        if (!(dtmf >= '0' && dtmf <= '9'
+                || dtmf >= 'A' && dtmf <= 'D'
+                || dtmf >= 'a' && dtmf <= 'd'
+                || dtmf == '*'
+                || dtmf == '#')) {
+            throw new IllegalArgumentException("DTMF digit must be 0-9, *, #, A, B, C, D");
+        }
+        try {
+            mListener.callSessionDtmfReceived(Character.toUpperCase(dtmf));
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * The {@link ImsService} calls this method to inform the framework of RTP header extension data
+     * which was received from the network.
+     * <p>
+     * The set of {@link RtpHeaderExtension} data are identified by local identifiers which were
+     * negotiated during SDP signalling.  See RFC8285,
+     * {@link ImsCallProfile#getAcceptedRtpHeaderExtensionTypes()} and
+     * {@link RtpHeaderExtensionType} for more information.
+     * <p>
+     * By specification, the RTP header extension is an unacknowledged transmission and there is no
+     * guarantee that the header extension will be delivered by the network to the other end of the
+     * call.
+     *
+     * @param extensions The RTP header extension data received.
+     */
+    public void callSessionRtpHeaderExtensionsReceived(
+            @NonNull Set<RtpHeaderExtension> extensions) {
+        Objects.requireNonNull(extensions, "extensions are required.");
+        try {
+            mListener.callSessionRtpHeaderExtensionsReceived(
+                    new ArrayList<RtpHeaderExtension>(extensions));
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Notifies the result of transfer request.
      * @hide
      */
diff --git a/telephony/java/android/telephony/ims/ImsRcsManager.java b/telephony/java/android/telephony/ims/ImsRcsManager.java
index 94407f1..8b6dac8 100644
--- a/telephony/java/android/telephony/ims/ImsRcsManager.java
+++ b/telephony/java/android/telephony/ims/ImsRcsManager.java
@@ -29,12 +29,10 @@
 import android.provider.Settings;
 import android.telephony.AccessNetworkConstants;
 import android.telephony.CarrierConfigManager;
-import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyFrameworkInitializer;
 import android.telephony.ims.aidl.IImsCapabilityCallback;
 import android.telephony.ims.aidl.IImsRcsController;
 import android.telephony.ims.feature.ImsFeature;
-import android.telephony.ims.feature.RcsFeature;
 import android.telephony.ims.stub.ImsRegistrationImplBase;
 import android.util.Log;
 
@@ -77,7 +75,7 @@
             "android.telephony.ims.action.SHOW_CAPABILITY_DISCOVERY_OPT_IN";
 
     /**
-     * Receives RCS availability status updates from the ImsService.
+     * Receives RCS Feature availability status updates from the ImsService.
      *
      * @see #isAvailable(int)
      * @see #registerRcsAvailabilityCallback(Executor, AvailabilityCallback)
@@ -101,8 +99,7 @@
 
                 long callingIdentity = Binder.clearCallingIdentity();
                 try {
-                    mExecutor.execute(() -> mLocalCallback.onAvailabilityChanged(
-                            new RcsFeature.RcsImsCapabilities(config)));
+                    mExecutor.execute(() -> mLocalCallback.onAvailabilityChanged(config));
                 } finally {
                     restoreCallingIdentity(callingIdentity);
                 }
@@ -137,7 +134,7 @@
          *
          * @param capabilities The new availability of the capabilities.
          */
-        public void onAvailabilityChanged(@NonNull RcsFeature.RcsImsCapabilities capabilities) {
+        public void onAvailabilityChanged(@RcsUceAdapter.RcsImsCapabilityFlag int capabilities) {
         }
 
         /**@hide*/
@@ -394,7 +391,7 @@
      * @hide
      */
     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
-    public boolean isCapable(@RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability,
+    public boolean isCapable(@RcsUceAdapter.RcsImsCapabilityFlag int capability,
             @ImsRegistrationImplBase.ImsRegistrationTech int radioTech) throws ImsException {
         IImsRcsController imsRcsController = getIImsRcsController();
         if (imsRcsController == null) {
@@ -428,7 +425,7 @@
      * @hide
      */
     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
-    public boolean isAvailable(@RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability)
+    public boolean isAvailable(@RcsUceAdapter.RcsImsCapabilityFlag int capability)
             throws ImsException {
         IImsRcsController imsRcsController = getIImsRcsController();
         if (imsRcsController == null) {
diff --git a/telephony/java/android/telephony/ims/ImsStreamMediaProfile.java b/telephony/java/android/telephony/ims/ImsStreamMediaProfile.java
index 131cb1a..4aca48b 100644
--- a/telephony/java/android/telephony/ims/ImsStreamMediaProfile.java
+++ b/telephony/java/android/telephony/ims/ImsStreamMediaProfile.java
@@ -17,6 +17,7 @@
 package android.telephony.ims;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.os.Parcel;
@@ -89,6 +90,9 @@
     /** @hide */
     @UnsupportedAppUsage
     public int mAudioDirection;
+    // Audio codec attributes
+    private AudioCodecAttributes mAudioCodecAttributes;
+
     // Video related information
     /** @hide */
     public int mVideoQuality;
@@ -190,6 +194,7 @@
     public void copyFrom(ImsStreamMediaProfile profile) {
         mAudioQuality = profile.mAudioQuality;
         mAudioDirection = profile.mAudioDirection;
+        mAudioCodecAttributes = profile.mAudioCodecAttributes;
         mVideoQuality = profile.mVideoQuality;
         mVideoDirection = profile.mVideoDirection;
         mRttMode = profile.mRttMode;
@@ -198,12 +203,13 @@
     @NonNull
     @Override
     public String toString() {
-        return "{ audioQuality=" + mAudioQuality +
-                ", audioDirection=" + mAudioDirection +
-                ", videoQuality=" + mVideoQuality +
-                ", videoDirection=" + mVideoDirection +
-                ", rttMode=" + mRttMode +
-                ", hasRttAudioSpeech=" + mIsReceivingRttAudio + " }";
+        return "{ audioQuality=" + mAudioQuality
+                + ", audioDirection=" + mAudioDirection
+                + ", audioCodecAttribute=" + mAudioCodecAttributes
+                + ", videoQuality=" + mVideoQuality
+                + ", videoDirection=" + mVideoDirection
+                + ", rttMode=" + mRttMode
+                + ", hasRttAudioSpeech=" + mIsReceivingRttAudio + " }";
     }
 
     @Override
@@ -215,6 +221,7 @@
     public void writeToParcel(Parcel out, int flags) {
         out.writeInt(mAudioQuality);
         out.writeInt(mAudioDirection);
+        out.writeTypedObject(mAudioCodecAttributes, flags);
         out.writeInt(mVideoQuality);
         out.writeInt(mVideoDirection);
         out.writeInt(mRttMode);
@@ -224,6 +231,7 @@
     private void readFromParcel(Parcel in) {
         mAudioQuality = in.readInt();
         mAudioDirection = in.readInt();
+        mAudioCodecAttributes = in.readTypedObject(AudioCodecAttributes.CREATOR);
         mVideoQuality = in.readInt();
         mVideoDirection = in.readInt();
         mRttMode = in.readInt();
@@ -274,6 +282,23 @@
         return mAudioDirection;
     }
 
+    /**
+     * Get the audio codec attributes {@link AudioCodecAttributes} which may be {@code null} if
+     * ImsService doesn't support this information.
+     * @return audio codec attributes
+     */
+    public @Nullable AudioCodecAttributes getAudioCodecAttributes() {
+        return mAudioCodecAttributes;
+    }
+
+    /**
+     * Set the audio codec attributes {@link AudioCodecAttributes} which includes bitrate and
+     * bandwidth information.
+     */
+    public void setAudioCodecAttributes(@NonNull AudioCodecAttributes audioCodecAttributes) {
+        mAudioCodecAttributes = audioCodecAttributes;
+    }
+
     public int getVideoQuality() {
         return mVideoQuality;
     }
diff --git a/telephony/java/android/telephony/ims/RcsContactTerminatedReason.aidl b/telephony/java/android/telephony/ims/RcsContactTerminatedReason.aidl
new file mode 100644
index 0000000..cd1ee84
--- /dev/null
+++ b/telephony/java/android/telephony/ims/RcsContactTerminatedReason.aidl
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2020 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.telephony.ims;
+
+parcelable RcsContactTerminatedReason;
diff --git a/telephony/java/android/telephony/ims/RcsContactTerminatedReason.java b/telephony/java/android/telephony/ims/RcsContactTerminatedReason.java
new file mode 100644
index 0000000..ee02564
--- /dev/null
+++ b/telephony/java/android/telephony/ims/RcsContactTerminatedReason.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2020 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.telephony.ims;
+
+import android.annotation.NonNull;
+import android.net.Uri;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * When the resource for the presence subscribe event has been terminated, the method
+ * SubscribeResponseCallback#onResourceTerminated wil be called with a list of
+ * RcsContactTerminatedReason.
+ * @hide
+ */
+public final class RcsContactTerminatedReason implements Parcelable {
+    private final Uri mContactUri;
+    private final String mReason;
+
+    public RcsContactTerminatedReason(Uri contact, String reason) {
+        mContactUri = contact;
+        mReason = reason;
+    }
+
+    private RcsContactTerminatedReason(Parcel in) {
+        mContactUri = in.readParcelable(Uri.class.getClassLoader());
+        mReason = in.readString();
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel out, int flags) {
+        out.writeParcelable(mContactUri, flags);
+        out.writeString(mReason);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    public static final @NonNull Creator<RcsContactTerminatedReason> CREATOR =
+            new Creator<RcsContactTerminatedReason>() {
+                @Override
+                public RcsContactTerminatedReason createFromParcel(Parcel in) {
+                    return new RcsContactTerminatedReason(in);
+                }
+
+                @Override
+                public RcsContactTerminatedReason[] newArray(int size) {
+                    return new RcsContactTerminatedReason[size];
+                }
+            };
+
+    public Uri getContactUri() {
+        return mContactUri;
+    }
+
+    public String getReason() {
+        return mReason;
+    }
+}
diff --git a/telephony/java/android/telephony/ims/RcsUceAdapter.java b/telephony/java/android/telephony/ims/RcsUceAdapter.java
index 0c88ade..0aeaecc 100644
--- a/telephony/java/android/telephony/ims/RcsUceAdapter.java
+++ b/telephony/java/android/telephony/ims/RcsUceAdapter.java
@@ -47,6 +47,30 @@
     private static final String TAG = "RcsUceAdapter";
 
     /**
+     * This carrier supports User Capability Exchange as, defined by the framework using
+     * SIP OPTIONS. If set, the RcsFeature should support capability exchange. If not set, this
+     * RcsFeature should not publish capabilities or service capability requests.
+     * @hide
+     */
+    public static final int CAPABILITY_TYPE_OPTIONS_UCE = 1 << 0;
+
+    /**
+     * This carrier supports User Capability Exchange as, defined by the framework using a
+     * presence server. If set, the RcsFeature should support capability exchange. If not set, this
+     * RcsFeature should not publish capabilities or service capability requests.
+     * @hide
+     */
+    public static final int CAPABILITY_TYPE_PRESENCE_UCE = 1 << 1;
+
+    /**@hide*/
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = "CAPABILITY_TYPE_", value = {
+            CAPABILITY_TYPE_OPTIONS_UCE,
+            CAPABILITY_TYPE_PRESENCE_UCE
+    })
+    public @interface RcsImsCapabilityFlag {}
+
+    /**
      * An unknown error has caused the request to fail.
      * @hide
      */
@@ -106,11 +130,6 @@
      * @hide
      */
     public static final int ERROR_LOST_NETWORK = 12;
-    /**
-     * The request has failed because the same request has already been added to the queue.
-     * @hide
-     */
-    public static final int ERROR_ALREADY_IN_QUEUE = 13;
 
     /**@hide*/
     @Retention(RetentionPolicy.SOURCE)
@@ -125,12 +144,90 @@
             ERROR_REQUEST_TOO_LARGE,
             ERROR_REQUEST_TIMEOUT,
             ERROR_INSUFFICIENT_MEMORY,
-            ERROR_LOST_NETWORK,
-            ERROR_ALREADY_IN_QUEUE
+            ERROR_LOST_NETWORK
     })
     public @interface ErrorCode {}
 
     /**
+     * A capability update has been requested due to the Entity Tag (ETag) expiring.
+     * @hide
+     */
+    public static final int CAPABILITY_UPDATE_TRIGGER_ETAG_EXPIRED = 0;
+    /**
+     * A capability update has been requested due to moving to LTE with VoPS disabled.
+     * @hide
+     */
+    public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_LTE_VOPS_DISABLED = 1;
+    /**
+     * A capability update has been requested due to moving to LTE with VoPS enabled.
+     * @hide
+     */
+    public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_LTE_VOPS_ENABLED = 2;
+    /**
+     * A capability update has been requested due to moving to eHRPD.
+     * @hide
+     */
+    public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_EHRPD = 3;
+    /**
+     * A capability update has been requested due to moving to HSPA+.
+     * @hide
+     */
+    public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_HSPAPLUS = 4;
+    /**
+     * A capability update has been requested due to moving to 3G.
+     * @hide
+     */
+    public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_3G = 5;
+    /**
+     * A capability update has been requested due to moving to 2G.
+     * @hide
+     */
+    public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_2G = 6;
+    /**
+     * A capability update has been requested due to moving to WLAN
+     * @hide
+     */
+    public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_WLAN = 7;
+    /**
+     * A capability update has been requested due to moving to IWLAN
+     * @hide
+     */
+    public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_IWLAN = 8;
+    /**
+     * A capability update has been requested but the reason is unknown.
+     * @hide
+     */
+    public static final int CAPABILITY_UPDATE_TRIGGER_UNKNOWN = 9;
+    /**
+     * A capability update has been requested due to moving to 5G NR with VoPS disabled.
+     * @hide
+     */
+    public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_NR5G_VOPS_DISABLED = 10;
+    /**
+     * A capability update has been requested due to moving to 5G NR with VoPS enabled.
+     * @hide
+     */
+    public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_NR5G_VOPS_ENABLED = 11;
+
+    /**@hide*/
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = "ERROR_", value = {
+            CAPABILITY_UPDATE_TRIGGER_ETAG_EXPIRED,
+            CAPABILITY_UPDATE_TRIGGER_MOVE_TO_LTE_VOPS_DISABLED,
+            CAPABILITY_UPDATE_TRIGGER_MOVE_TO_LTE_VOPS_ENABLED,
+            CAPABILITY_UPDATE_TRIGGER_MOVE_TO_EHRPD,
+            CAPABILITY_UPDATE_TRIGGER_MOVE_TO_HSPAPLUS,
+            CAPABILITY_UPDATE_TRIGGER_MOVE_TO_3G,
+            CAPABILITY_UPDATE_TRIGGER_MOVE_TO_2G,
+            CAPABILITY_UPDATE_TRIGGER_MOVE_TO_WLAN,
+            CAPABILITY_UPDATE_TRIGGER_MOVE_TO_IWLAN,
+            CAPABILITY_UPDATE_TRIGGER_UNKNOWN,
+            CAPABILITY_UPDATE_TRIGGER_MOVE_TO_NR5G_VOPS_DISABLED,
+            CAPABILITY_UPDATE_TRIGGER_MOVE_TO_NR5G_VOPS_ENABLED
+    })
+    public @interface StackPublishTriggerType {}
+
+    /**
      * The last publish has resulted in a "200 OK" response or the device is using SIP OPTIONS for
      * UCE.
      * @hide
@@ -205,7 +302,7 @@
             public void onPublishStateChanged(int publishState) {
                 if (mLocalCallback == null) return;
 
-                long callingIdentity = Binder.clearCallingIdentity();
+                final long callingIdentity = Binder.clearCallingIdentity();
                 try {
                     mExecutor.execute(() -> mLocalCallback.onChanged(publishState));
                 } finally {
@@ -238,38 +335,49 @@
     }
 
     /**
-     * Provides a one-time callback for the response to a UCE request. After this callback is called
-     * by the framework, the reference to this callback will be discarded on the service side.
+     * A callback for the response to a UCE request. The method
+     * {@link CapabilitiesCallback#onCapabilitiesReceived} will be called zero or more times as the
+     * capabilities are received for each requested contact.
+     * <p>
+     * This request will take a varying amount of time depending on if the contacts requested are
+     * cached or if it requires a network query. The timeout time of these requests can vary
+     * depending on the network, however in poor cases it could take up to a minute for a request
+     * to timeout. In that time only a subset of capabilities may have been retrieved.
+     * <p>
+     * After {@link CapabilitiesCallback#onComplete} or {@link CapabilitiesCallback#onError} has
+     * been called, the reference to this callback will be discarded on the service side.
      * @see #requestCapabilities(Executor, List, CapabilitiesCallback)
      * @hide
      */
-    public static class CapabilitiesCallback {
+    public interface CapabilitiesCallback {
 
         /**
-         * Notify this application that the pending capability request has returned successfully.
+         * Notify this application that the pending capability request has returned successfully
+         * for one or more of the requested contacts.
          * @param contactCapabilities List of capabilities associated with each contact requested.
          */
-        public void onCapabilitiesReceived(
-                @NonNull List<RcsContactUceCapability> contactCapabilities) {
+        void onCapabilitiesReceived(@NonNull List<RcsContactUceCapability> contactCapabilities);
 
-        }
+        /**
+         * The pending request has completed successfully due to all requested contacts information
+         * being delivered.
+         */
+        void onComplete();
 
         /**
          * The pending request has resulted in an error and may need to be retried, depending on the
          * error code.
          * @param errorCode The reason for the framework being unable to process the request.
          */
-        public void onError(@ErrorCode int errorCode) {
-
-        }
+        void onError(@ErrorCode int errorCode);
     }
 
     private final Context mContext;
     private final int mSubId;
 
     /**
-     * Not to be instantiated directly, use
-     * {@link ImsRcsManager#getUceAdapter()} to instantiate this manager class.
+     * Not to be instantiated directly, use {@link ImsRcsManager#getUceAdapter()} to instantiate
+     * this manager class.
      * @hide
      */
     RcsUceAdapter(Context context, int subId) {
@@ -280,6 +388,9 @@
     /**
      * Request the User Capability Exchange capabilities for one or more contacts.
      * <p>
+     * This will return the cached capabilities of the contact and will not perform a capability
+     * poll on the network unless there are contacts being queried with stale information.
+     * <p>
      * Be sure to check the availability of this feature using
      * {@link ImsRcsManager#isAvailable(int)} and ensuring
      * {@link RcsFeature.RcsImsCapabilities#CAPABILITY_TYPE_OPTIONS_UCE} or
@@ -302,7 +413,7 @@
             @NonNull List<Uri> contactNumbers,
             @NonNull CapabilitiesCallback c) throws ImsException {
         if (c == null) {
-            throw new IllegalArgumentException("Must include a non-null AvailabilityCallback.");
+            throw new IllegalArgumentException("Must include a non-null CapabilitiesCallback.");
         }
         if (executor == null) {
             throw new IllegalArgumentException("Must include a non-null Executor.");
@@ -321,7 +432,7 @@
         IRcsUceControllerCallback internalCallback = new IRcsUceControllerCallback.Stub() {
             @Override
             public void onCapabilitiesReceived(List<RcsContactUceCapability> contactCapabilities) {
-                long callingIdentity = Binder.clearCallingIdentity();
+                final long callingIdentity = Binder.clearCallingIdentity();
                 try {
                     executor.execute(() ->
                             c.onCapabilitiesReceived(contactCapabilities));
@@ -330,8 +441,17 @@
                 }
             }
             @Override
+            public void onComplete() {
+                final long callingIdentity = Binder.clearCallingIdentity();
+                try {
+                    executor.execute(() -> c.onComplete());
+                } finally {
+                    restoreCallingIdentity(callingIdentity);
+                }
+            }
+            @Override
             public void onError(int errorCode) {
-                long callingIdentity = Binder.clearCallingIdentity();
+                final long callingIdentity = Binder.clearCallingIdentity();
                 try {
                     executor.execute(() -> c.onError(errorCode));
                 } finally {
@@ -351,6 +471,88 @@
     }
 
     /**
+     * Ignore the device cache and perform a capability discovery for one contact, also called
+     * "availability fetch."
+     * <p>
+     * This will always perform a query to the network as long as requests are over the carrier
+     * availability fetch throttling threshold. If too many network requests are sent too quickly,
+     * #ERROR_TOO_MANY_REQUESTS will be returned.
+     *
+     * <p>
+     * Be sure to check the availability of this feature using
+     * {@link ImsRcsManager#isAvailable(int)} and ensuring
+     * {@link RcsFeature.RcsImsCapabilities#CAPABILITY_TYPE_OPTIONS_UCE} or
+     * {@link RcsFeature.RcsImsCapabilities#CAPABILITY_TYPE_PRESENCE_UCE} is
+     * enabled or else this operation will fail with
+     * {@link #ERROR_NOT_AVAILABLE} or {@link #ERROR_NOT_ENABLED}.
+     *
+     * @param contactNumber The contact of the capabilities is being requested for.
+     * @param c A one-time callback for when the request for capabilities completes or there is
+     * an error processing the request.
+     * @hide
+     */
+    @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
+    public void requestNetworkAvailability(@NonNull @CallbackExecutor Executor executor,
+            @NonNull Uri contactNumber, @NonNull CapabilitiesCallback c) throws ImsException {
+        if (executor == null) {
+            throw new IllegalArgumentException("Must include a non-null Executor.");
+        }
+        if (contactNumber == null) {
+            throw new IllegalArgumentException("Must include non-null contact number.");
+        }
+        if (c == null) {
+            throw new IllegalArgumentException("Must include a non-null CapabilitiesCallback.");
+        }
+
+        IImsRcsController imsRcsController = getIImsRcsController();
+        if (imsRcsController == null) {
+            Log.e(TAG, "requestNetworkAvailability: IImsRcsController is null");
+            throw new ImsException("Cannot find remote IMS service",
+                    ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+        }
+
+        IRcsUceControllerCallback internalCallback = new IRcsUceControllerCallback.Stub() {
+            @Override
+            public void onCapabilitiesReceived(List<RcsContactUceCapability> contactCapabilities) {
+                final long callingIdentity = Binder.clearCallingIdentity();
+                try {
+                    executor.execute(() ->
+                            c.onCapabilitiesReceived(contactCapabilities));
+                } finally {
+                    restoreCallingIdentity(callingIdentity);
+                }
+            }
+            @Override
+            public void onComplete() {
+                final long callingIdentity = Binder.clearCallingIdentity();
+                try {
+                    executor.execute(() -> c.onComplete());
+                } finally {
+                    restoreCallingIdentity(callingIdentity);
+                }
+            }
+            @Override
+            public void onError(int errorCode) {
+                final long callingIdentity = Binder.clearCallingIdentity();
+                try {
+                    executor.execute(() -> c.onError(errorCode));
+                } finally {
+                    restoreCallingIdentity(callingIdentity);
+                }
+            }
+        };
+
+        try {
+            imsRcsController.requestNetworkAvailability(mSubId, mContext.getOpPackageName(),
+                    mContext.getAttributionTag(), contactNumber, internalCallback);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error calling IImsRcsController#requestNetworkAvailability", e);
+            throw new ImsException("Remote IMS Service is not available",
+                    ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+        }
+    }
+
+    /**
      * Gets the last publish result from the UCE service if the device is using an RCS presence
      * server.
      * @return The last publish result from the UCE service. If the device is using SIP OPTIONS,
diff --git a/telephony/java/android/telephony/ims/RtpHeaderExtension.aidl b/telephony/java/android/telephony/ims/RtpHeaderExtension.aidl
new file mode 100644
index 0000000..cbf79d3
--- /dev/null
+++ b/telephony/java/android/telephony/ims/RtpHeaderExtension.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2020 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.telephony.ims;
+
+parcelable RtpHeaderExtension;
\ No newline at end of file
diff --git a/telephony/java/android/telephony/ims/RtpHeaderExtension.java b/telephony/java/android/telephony/ims/RtpHeaderExtension.java
new file mode 100644
index 0000000..f9ab701
--- /dev/null
+++ b/telephony/java/android/telephony/ims/RtpHeaderExtension.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2020 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.telephony.ims;
+
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Arrays;
+import java.util.Objects;
+
+/**
+ * A representation of an RTP header extension.
+ * <p>
+ * Per RFC8285, an RTP header extension consists of both a local identifier in the range 1-14, an
+ * 8-bit length indicator and a number of extension data bytes equivalent to the stated length.
+ * @hide
+ */
+@SystemApi
+public final class RtpHeaderExtension implements Parcelable {
+    private int mLocalIdentifier;
+    private byte[] mExtensionData;
+
+    /**
+     * Creates a new {@link RtpHeaderExtension}.
+     * @param localIdentifier The local identifier for this RTP header extension.
+     * @param extensionData The data for this RTP header extension.
+     * @throws IllegalArgumentException if {@code extensionId} is not in the range 1-14.
+     * @throws NullPointerException if {@code extensionData} is null.
+     */
+    public RtpHeaderExtension(@IntRange(from = 1, to = 14) int localIdentifier,
+            @NonNull byte[] extensionData) {
+        if (localIdentifier < 1 || localIdentifier > 13) {
+            throw new IllegalArgumentException("localIdentifier must be in range 1-14");
+        }
+        if (extensionData == null) {
+            throw new NullPointerException("extensionDa is required.");
+        }
+        mLocalIdentifier = localIdentifier;
+        mExtensionData = extensionData;
+    }
+
+    /**
+     * Creates a new instance of {@link RtpHeaderExtension} from a parcel.
+     * @param in The parceled data to read.
+     */
+    private RtpHeaderExtension(@NonNull Parcel in) {
+        mLocalIdentifier = in.readInt();
+        mExtensionData = in.createByteArray();
+    }
+
+    /**
+     * The local identifier for the RTP header extension.
+     * <p>
+     * Per RFC8285, the extension ID is a value in the range 1-14 (0 is reserved for padding and
+     * 15 is reserved for the one-byte header form.
+     * <p>
+     * Within the current call, this extension ID will match one of the
+     * {@link RtpHeaderExtensionType#getLocalIdentifier()}s.
+     *
+     * @return The local identifier for this RTP header extension.
+     */
+    @IntRange(from = 1, to = 14)
+    public int getLocalIdentifier() {
+        return mLocalIdentifier;
+    }
+
+    /**
+     * The data payload for the RTP header extension.
+     * <p>
+     * Per RFC8285 Sec 4.3, an RTP header extension includes an 8-bit length field which indicate
+     * how many bytes of data are present in the RTP header extension.  The extension includes this
+     * many bytes of actual data.
+     * <p>
+     * We represent this as a byte array who's length is equivalent to the 8-bit length field.
+     * @return RTP header extension data payload.  The payload may be up to 255 bytes in length.
+     */
+    public @NonNull byte[] getExtensionData() {
+        return mExtensionData;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeInt(mLocalIdentifier);
+        dest.writeByteArray(mExtensionData);
+    }
+
+    public static final @NonNull Creator<RtpHeaderExtension> CREATOR =
+            new Creator<RtpHeaderExtension>() {
+                @Override
+                public RtpHeaderExtension createFromParcel(@NonNull Parcel in) {
+                    return new RtpHeaderExtension(in);
+                }
+
+                @Override
+                public RtpHeaderExtension[] newArray(int size) {
+                    return new RtpHeaderExtension[size];
+                }
+            };
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        RtpHeaderExtension that = (RtpHeaderExtension) o;
+        return mLocalIdentifier == that.mLocalIdentifier
+                && Arrays.equals(mExtensionData, that.mExtensionData);
+    }
+
+    @Override
+    public int hashCode() {
+        int result = Objects.hash(mLocalIdentifier);
+        result = 31 * result + Arrays.hashCode(mExtensionData);
+        return result;
+    }
+}
diff --git a/telephony/java/android/telephony/ims/RtpHeaderExtensionType.aidl b/telephony/java/android/telephony/ims/RtpHeaderExtensionType.aidl
new file mode 100644
index 0000000..3e62fff
--- /dev/null
+++ b/telephony/java/android/telephony/ims/RtpHeaderExtensionType.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2020 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.telephony.ims;
+
+parcelable RtpHeaderExtensionType;
\ No newline at end of file
diff --git a/telephony/java/android/telephony/ims/RtpHeaderExtensionType.java b/telephony/java/android/telephony/ims/RtpHeaderExtensionType.java
new file mode 100644
index 0000000..e1d39c2
--- /dev/null
+++ b/telephony/java/android/telephony/ims/RtpHeaderExtensionType.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2020 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.telephony.ims;
+
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.net.Uri;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Objects;
+
+/**
+ * Defines a mapping between a local identifier and a {@link Uri} which identifies an RTP header
+ * extension.
+ * <p>
+ * According to RFC8285, SDP (Session Description Protocol) signalling for a call provides a means
+ * for the supported RTP header extensions for a call to be negotiated at call initiation time.
+ * The types of RTP header extensions potentially usable in a session are identified by a local
+ * identifier ({@link #getLocalIdentifier()}) when RTP header extensions are present on RTP packets.
+ * A {@link Uri} ({@link #getUri()}) provides a unique identifier for the RTP header extension
+ * format which parties in a call can use to identify supported RTP header extensions.
+ * @hide
+ */
+@SystemApi
+public final class RtpHeaderExtensionType implements Parcelable {
+    private int mLocalIdentifier;
+    private Uri mUri;
+
+    /**
+     * Create a new RTP header extension type.
+     * @param localIdentifier the local identifier.
+     * @param uri the {@link Uri} identifying the RTP header extension type.
+     * @throws IllegalArgumentException if {@code localIdentifier} is out of the expected range.
+     * @throws NullPointerException if {@code uri} is null.
+     */
+    public RtpHeaderExtensionType(@IntRange(from = 1, to = 14) int localIdentifier,
+            @NonNull Uri uri) {
+        if (localIdentifier < 1 || localIdentifier > 13) {
+            throw new IllegalArgumentException("localIdentifier must be in range 1-14");
+        }
+        if (uri == null) {
+            throw new NullPointerException("uri is required.");
+        }
+        mLocalIdentifier = localIdentifier;
+        mUri = uri;
+    }
+
+    private RtpHeaderExtensionType(Parcel in) {
+        mLocalIdentifier = in.readInt();
+        mUri = in.readParcelable(Uri.class.getClassLoader());
+    }
+
+    public static final @NonNull Creator<RtpHeaderExtensionType> CREATOR =
+            new Creator<RtpHeaderExtensionType>() {
+                @Override
+                public RtpHeaderExtensionType createFromParcel(@NonNull Parcel in) {
+                    return new RtpHeaderExtensionType(in);
+                }
+
+                @Override
+                public @NonNull RtpHeaderExtensionType[] newArray(int size) {
+                    return new RtpHeaderExtensionType[size];
+                }
+            };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeInt(mLocalIdentifier);
+        dest.writeParcelable(mUri, flags);
+    }
+
+    /**
+     * The local identifier for this RTP header extension type.
+     * <p>
+     * {@link RtpHeaderExtension}s which indicate a {@link RtpHeaderExtension#getLocalIdentifier()}
+     * matching this local identifier will have the format specified by {@link #getUri()}.
+     * <p>
+     * Per RFC8285, the extension ID is a value in the range 1-14 (0 is reserved for padding and
+     * 15 is reserved for the one-byte header form.
+     *
+     * @return The local identifier associated with this {@link #getUri()}.
+     */
+    public @IntRange(from = 1, to = 14) int getLocalIdentifier() {
+        return mLocalIdentifier;
+    }
+
+    /**
+     * A {@link Uri} which identifies the format of the RTP extension header.
+     * <p>
+     * According to RFC8285 section 5, URIs MUST be absolute and SHOULD contain a month/date pair
+     * in the form mmyyyy to indicate versioning of the extension.  Extension headers defined in an
+     * RFC are typically defined using URNs starting with {@code urn:ietf:params:rtp-hdrext:}.
+     * For example, RFC6464 defines {@code urn:ietf:params:rtp-hdrext:ssrc-audio-level} which is an
+     * RTP header extension for communicating client to mixer audio level indications.
+     *
+     * @return A unique {@link Uri} identifying the format of the RTP extension header.
+     */
+    public @NonNull Uri getUri() {
+        return mUri;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        RtpHeaderExtensionType that = (RtpHeaderExtensionType) o;
+        return mLocalIdentifier == that.mLocalIdentifier
+                && mUri.equals(that.mUri);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mLocalIdentifier, mUri);
+    }
+}
diff --git a/telephony/java/android/telephony/ims/aidl/ICapabilityExchangeEventListener.aidl b/telephony/java/android/telephony/ims/aidl/ICapabilityExchangeEventListener.aidl
new file mode 100644
index 0000000..a4ffbef
--- /dev/null
+++ b/telephony/java/android/telephony/ims/aidl/ICapabilityExchangeEventListener.aidl
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2020 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.telephony.ims.aidl;
+
+import android.net.Uri;
+import android.telephony.ims.aidl.IOptionsRequestCallback;
+
+import java.util.List;
+
+/**
+ * Listener interface for the ImsService to use to notify the framework of UCE events.
+ * {@hide}
+ */
+oneway interface ICapabilityExchangeEventListener {
+    /**
+     * Trigger the framework to provide a capability update using
+     * {@link RcsCapabilityExchangeImplBase#publishCapabilities}.
+     * <p>
+     * This is typically used when trying to generate an initial PUBLISH for a new
+     * subscription to the network. The device will cache all presence publications
+     * after boot until this method is called the first time.
+     * @param publishTriggerType {@link StackPublishTriggerType} The reason for the
+     * capability update request.
+     * @throws ImsException If this {@link RcsPresenceExchangeImplBase} instance is
+     * not currently connected to the framework. This can happen if the
+     * {@link RcsFeature} is not {@link ImsFeature#STATE_READY} and the
+     * {@link RcsFeature} has not received the
+     * {@link ImsFeature#onFeatureReady()} callback. This may also happen in rare
+     * cases when the Telephony stack has crashed.
+     */
+    void onRequestPublishCapabilities(int publishTriggerType);
+
+    /**
+     * Notify the framework that the device's capabilities have been unpublished from the network.
+     *
+     * @throws ImsException If this {@link RcsPresenceExchangeImplBase} instance is not currently
+     * connected to the framework. This can happen if the {@link RcsFeature} is not
+     * {@link ImsFeature#STATE_READY} and the {@link RcsFeature} has not received the
+     * {@link ImsFeature#onFeatureReady()} callback. This may also happen in rare cases when the
+     * Telephony stack has crashed.
+     */
+    void onUnpublish();
+
+    /**
+     * Inform the framework of a query for this device's UCE capabilities.
+     * <p>
+     * The framework will respond via the
+     * {@link IOptionsRequestCallback#respondToCapabilityRequest} or
+     * {@link IOptionsRequestCallback#respondToCapabilityRequestWithError} method.
+     * @param contactUri The URI associated with the remote contact that is requesting capabilities.
+     * @param remoteCapabilities The remote contact's capability information.
+     * @throws ImsException If this {@link RcsSipOptionsImplBase} instance is not currently
+     * connected to the framework. This can happen if the {@link RcsFeature} is not
+     * {@link ImsFeature#STATE_READY} and the {@link RcsFeature} has not received
+     * the {@link ImsFeature#onFeatureReady()} callback. This may also happen in rare cases when
+     * the Telephony stack has crashed.
+     */
+    void onRemoteCapabilityRequest(in Uri contactUri,
+            in List<String> remoteCapabilities,
+            IOptionsRequestCallback cb);
+}
diff --git a/telephony/java/android/telephony/ims/aidl/IImsCallSessionListener.aidl b/telephony/java/android/telephony/ims/aidl/IImsCallSessionListener.aidl
index 36d2067..ed895b7 100644
--- a/telephony/java/android/telephony/ims/aidl/IImsCallSessionListener.aidl
+++ b/telephony/java/android/telephony/ims/aidl/IImsCallSessionListener.aidl
@@ -21,9 +21,12 @@
 import android.telephony.ims.ImsCallProfile;
 import android.telephony.ims.ImsReasonInfo;
 import android.telephony.ims.ImsConferenceState;
+import android.telephony.ims.RtpHeaderExtension;
 import com.android.ims.internal.IImsCallSession;
 import android.telephony.ims.ImsSuppServiceNotification;
 
+import java.util.List;
+
 /**
  * A listener type for receiving notification on IMS call session events.
  * When an event is generated for an {@link IImsCallSession}, the application is notified
@@ -153,9 +156,17 @@
     void callSessionTransferred();
     void callSessionTransferFailed(in ImsReasonInfo reasonInfo);
 
+    void callSessionDtmfReceived(char dtmf);
+
     /**
      * Notifies of a change to the call quality.
      * @param callQuality then updated call quality
      */
     void callQualityChanged(in CallQuality callQuality);
+
+    /**
+     * Notifies of incoming RTP header extensions from the network.
+     * @param extensions the RTP header extensions received.
+     */
+    void callSessionRtpHeaderExtensionsReceived(in List<RtpHeaderExtension> extensions);
 }
diff --git a/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl b/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl
index 6d25a09..8e84e93 100644
--- a/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl
+++ b/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl
@@ -47,6 +47,9 @@
     // ImsUceAdapter specific
     void requestCapabilities(int subId, String callingPackage, String callingFeatureId,
             in List<Uri> contactNumbers, IRcsUceControllerCallback c);
+    void requestNetworkAvailability(int subId, String callingPackage,
+            String callingFeatureId, in Uri contactNumber,
+            IRcsUceControllerCallback c);
     int getUcePublishState(int subId);
     boolean isUceSettingEnabled(int subId, String callingPackage, String callingFeatureId);
     void setUceSettingEnabled(int subId, boolean isEnabled);
diff --git a/telephony/java/android/telephony/ims/aidl/IImsRcsFeature.aidl b/telephony/java/android/telephony/ims/aidl/IImsRcsFeature.aidl
index 4b98b79..b47e3c7 100644
--- a/telephony/java/android/telephony/ims/aidl/IImsRcsFeature.aidl
+++ b/telephony/java/android/telephony/ims/aidl/IImsRcsFeature.aidl
@@ -18,8 +18,12 @@
 
 import android.net.Uri;
 import android.telephony.ims.RcsContactUceCapability;
+import android.telephony.ims.aidl.ICapabilityExchangeEventListener;
 import android.telephony.ims.aidl.IImsCapabilityCallback;
+import android.telephony.ims.aidl.IOptionsResponseCallback;
+import android.telephony.ims.aidl.IPublishResponseCallback;
 import android.telephony.ims.aidl.IRcsFeatureListener;
+import android.telephony.ims.aidl.ISubscribeResponseCallback;
 import android.telephony.ims.feature.CapabilityChangeRequest;
 
 import java.util.List;
@@ -40,6 +44,12 @@
             IImsCapabilityCallback c);
     oneway void queryCapabilityConfiguration(int capability, int radioTech,
             IImsCapabilityCallback c);
+    // RcsCapabilityExchangeImplBase specific api
+    oneway void setCapabilityExchangeEventListener(ICapabilityExchangeEventListener listener);
+    oneway void publishCapabilities(in String pidfXml, IPublishResponseCallback cb);
+    oneway void subscribeForCapabilities(in List<Uri> uris, ISubscribeResponseCallback cb);
+    oneway void sendOptionsCapabilityRequest(in Uri contactUri,
+            in List<String> myCapabilities, IOptionsResponseCallback cb);
     // RcsPresenceExchangeImplBase specific api
     oneway void requestCapabilities(in List<Uri> uris, int operationToken);
     oneway void updateCapabilities(in RcsContactUceCapability capabilities, int operationToken);
@@ -50,4 +60,4 @@
             in RcsContactUceCapability ownCapabilities, int operationToken);
     oneway void respondToCapabilityRequestWithError(in Uri contactUri, int code, in String reason,
             int operationToken);
-}
\ No newline at end of file
+}
diff --git a/telephony/java/android/telephony/ims/aidl/IOptionsRequestCallback.aidl b/telephony/java/android/telephony/ims/aidl/IOptionsRequestCallback.aidl
new file mode 100644
index 0000000..d55670d
--- /dev/null
+++ b/telephony/java/android/telephony/ims/aidl/IOptionsRequestCallback.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2020 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.telephony.ims.aidl;
+
+import android.telephony.ims.RcsContactUceCapability;
+
+/**
+ * Interface used by the framework to respond to OPTIONS requests.
+ * {@hide}
+ */
+oneway interface IOptionsRequestCallback {
+    /**
+     * Respond to a remote capability request from the contact specified with the capabilities
+     * of this device.
+     * @param ownCapabilities The capabilities of this device.
+     */
+    void respondToCapabilityRequest(in RcsContactUceCapability ownCapabilities);
+
+    /**
+     * Respond to a remote capability request from the contact specified with the
+     * specified error.
+     * @param contactUri A URI containing the remote contact.
+     * @param code The SIP response code to respond with.
+     * @param reason A non-null String containing the reason associated with the SIP code.
+     */
+    void respondToCapabilityRequestWithError(int code, String reason);
+}
diff --git a/telephony/java/android/telephony/ims/aidl/IOptionsResponseCallback.aidl b/telephony/java/android/telephony/ims/aidl/IOptionsResponseCallback.aidl
new file mode 100644
index 0000000..a8c8329
--- /dev/null
+++ b/telephony/java/android/telephony/ims/aidl/IOptionsResponseCallback.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2020 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.telephony.ims.aidl;
+
+import java.util.List;
+
+/**
+ * Interface used by the framework to receive the response from the remote user
+ * through {@link RcsCapabilityExchangeImplBase#sendOptionsCapabilityRequest}
+ * {@hide}
+ */
+oneway interface IOptionsResponseCallback {
+    void onCommandError(int code);
+    void onNetworkResponse(int code, String reason, in List<String> theirCaps);
+}
diff --git a/telephony/java/android/telephony/ims/aidl/IPublishResponseCallback.aidl b/telephony/java/android/telephony/ims/aidl/IPublishResponseCallback.aidl
new file mode 100644
index 0000000..481e7f8
--- /dev/null
+++ b/telephony/java/android/telephony/ims/aidl/IPublishResponseCallback.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2020 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.telephony.ims.aidl;
+
+import java.util.List;
+
+/**
+ * Interface used by the framework to receive the response of the publish
+ * request through {@link RcsCapabilityExchangeImplBase#publishCapabilities}
+ * {@hide}
+ */
+oneway interface IPublishResponseCallback {
+    void onCommandError(int code);
+    void onNetworkResponse(int code, String reason);
+}
diff --git a/telephony/java/android/telephony/ims/aidl/IRcsUceControllerCallback.aidl b/telephony/java/android/telephony/ims/aidl/IRcsUceControllerCallback.aidl
index 5975930..0bd3e5e 100644
--- a/telephony/java/android/telephony/ims/aidl/IRcsUceControllerCallback.aidl
+++ b/telephony/java/android/telephony/ims/aidl/IRcsUceControllerCallback.aidl
@@ -25,5 +25,6 @@
  */
 oneway interface IRcsUceControllerCallback {
     void onCapabilitiesReceived(in List<RcsContactUceCapability> contactCapabilities);
+    void onComplete();
     void onError(int errorCode);
 }
diff --git a/telephony/java/android/telephony/ims/aidl/ISubscribeResponseCallback.aidl b/telephony/java/android/telephony/ims/aidl/ISubscribeResponseCallback.aidl
new file mode 100644
index 0000000..4deaba1
--- /dev/null
+++ b/telephony/java/android/telephony/ims/aidl/ISubscribeResponseCallback.aidl
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2020 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.telephony.ims.aidl;
+
+import android.net.Uri;
+import android.telephony.ims.RcsContactTerminatedReason;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Interface used by the framework to receive the response of the subscribe
+ * request through {@link RcsCapabilityExchangeImplBase#subscribeForCapabilities}
+ * {@hide}
+ */
+oneway interface ISubscribeResponseCallback {
+    void onCommandError(int code);
+    void onNetworkResponse(int code, in String reason);
+    void onNotifyCapabilitiesUpdate(in List<String> pidfXmls);
+    void onResourceTerminated(in List<RcsContactTerminatedReason> uriTerminatedReason);
+    void onTerminated(in String reason, in String retryAfter);
+}
diff --git a/telephony/java/android/telephony/ims/aidl/RcsOptionsResponseAidlWrapper.java b/telephony/java/android/telephony/ims/aidl/RcsOptionsResponseAidlWrapper.java
new file mode 100644
index 0000000..47a96af
--- /dev/null
+++ b/telephony/java/android/telephony/ims/aidl/RcsOptionsResponseAidlWrapper.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2020 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.telephony.ims.aidl;
+
+import android.os.RemoteException;
+import android.telephony.ims.ImsException;
+import android.telephony.ims.stub.RcsCapabilityExchangeImplBase.OptionsResponseCallback;
+
+import java.util.List;
+
+/**
+ * Implementation of the callback OptionsResponseCallback by wrapping the internal AIDL from
+ * telephony.
+ * @hide
+ */
+public class RcsOptionsResponseAidlWrapper implements OptionsResponseCallback {
+
+    private final IOptionsResponseCallback mResponseBinder;
+
+    public RcsOptionsResponseAidlWrapper(IOptionsResponseCallback responseBinder) {
+        mResponseBinder = responseBinder;
+    }
+
+    @Override
+    public void onCommandError(int code) {
+        try {
+            mResponseBinder.onCommandError(code);
+        } catch (RemoteException e) {
+        }
+    }
+
+    @Override
+    public void onNetworkResponse(int code, String reason, List<String> theirCaps)
+            throws ImsException {
+        try {
+            mResponseBinder.onNetworkResponse(code, reason, theirCaps);
+        } catch (RemoteException e) {
+        }
+    }
+}
diff --git a/telephony/java/android/telephony/ims/aidl/RcsPublishResponseAidlWrapper.java b/telephony/java/android/telephony/ims/aidl/RcsPublishResponseAidlWrapper.java
new file mode 100644
index 0000000..22985d0
--- /dev/null
+++ b/telephony/java/android/telephony/ims/aidl/RcsPublishResponseAidlWrapper.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2020 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.telephony.ims.aidl;
+
+import android.os.RemoteException;
+import android.telephony.ims.ImsException;
+import android.telephony.ims.stub.RcsCapabilityExchangeImplBase.PublishResponseCallback;
+
+/**
+ * Implementation of the callback PublishResponseCallback by wrapping the internal AIDL from
+ * telephony.
+ * @hide
+ */
+public class RcsPublishResponseAidlWrapper implements PublishResponseCallback {
+
+    private final IPublishResponseCallback mResponseBinder;
+
+    public RcsPublishResponseAidlWrapper(IPublishResponseCallback responseBinder) {
+        mResponseBinder = responseBinder;
+    }
+
+    @Override
+    public void onCommandError(int code) {
+        try {
+            mResponseBinder.onCommandError(code);
+        } catch (RemoteException e) {
+        }
+    }
+
+    @Override
+    public void onNetworkResponse(int code, String reason) throws ImsException {
+        try {
+            mResponseBinder.onNetworkResponse(code, reason);
+        } catch (RemoteException e) {
+        }
+    }
+}
diff --git a/telephony/java/android/telephony/ims/aidl/RcsSubscribeResponseAidlWrapper.java b/telephony/java/android/telephony/ims/aidl/RcsSubscribeResponseAidlWrapper.java
new file mode 100644
index 0000000..37588ed
--- /dev/null
+++ b/telephony/java/android/telephony/ims/aidl/RcsSubscribeResponseAidlWrapper.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2020 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.telephony.ims.aidl;
+
+import android.net.Uri;
+import android.os.RemoteException;
+import android.telephony.ims.ImsException;
+import android.telephony.ims.RcsContactTerminatedReason;
+import android.telephony.ims.stub.RcsCapabilityExchangeImplBase.SubscribeResponseCallback;
+import android.util.Pair;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Implementation of the callback OptionsResponseCallback by wrapping the internal AIDL from
+ * telephony.
+ * @hide
+ */
+public class RcsSubscribeResponseAidlWrapper implements SubscribeResponseCallback {
+
+    private final ISubscribeResponseCallback mResponseBinder;
+
+    public RcsSubscribeResponseAidlWrapper(ISubscribeResponseCallback responseBinder) {
+        mResponseBinder = responseBinder;
+    }
+
+    @Override
+    public void onCommandError(int code) {
+        try {
+            mResponseBinder.onCommandError(code);
+        } catch (RemoteException e) {
+        }
+    }
+
+    @Override
+    public void onNetworkResponse(int code, String reason) throws ImsException {
+        try {
+            mResponseBinder.onNetworkResponse(code, reason);
+        } catch (RemoteException e) {
+        }
+    }
+
+    @Override
+    public void onNotifyCapabilitiesUpdate(List<String> pidfXmls) throws ImsException {
+        try {
+            mResponseBinder.onNotifyCapabilitiesUpdate(pidfXmls);
+        } catch (RemoteException e) {
+        }
+    }
+
+    @Override
+    public void onResourceTerminated(List<Pair<Uri, String>> uriTerminatedReason)
+            throws ImsException {
+        try {
+            mResponseBinder.onResourceTerminated(getTerminatedReasonList(uriTerminatedReason));
+        } catch (RemoteException e) {
+        }
+    }
+
+    private List<RcsContactTerminatedReason> getTerminatedReasonList(
+            List<Pair<Uri, String>> uriTerminatedReason) {
+        List<RcsContactTerminatedReason> uriTerminatedReasonList = new ArrayList<>();
+        if (uriTerminatedReason != null) {
+            for (Pair<Uri, String> pair : uriTerminatedReason) {
+                RcsContactTerminatedReason reason =
+                        new RcsContactTerminatedReason(pair.first, pair.second);
+                uriTerminatedReasonList.add(reason);
+            }
+        }
+        return uriTerminatedReasonList;
+    }
+
+    @Override
+    public void onTerminated(String reason, String retryAfter) throws ImsException {
+        try {
+            mResponseBinder.onTerminated(reason, retryAfter);
+        } catch (RemoteException e) {
+        }
+    }
+}
diff --git a/telephony/java/android/telephony/ims/compat/stub/ImsCallSessionImplBase.java b/telephony/java/android/telephony/ims/compat/stub/ImsCallSessionImplBase.java
index 06aa642..06f0397 100755
--- a/telephony/java/android/telephony/ims/compat/stub/ImsCallSessionImplBase.java
+++ b/telephony/java/android/telephony/ims/compat/stub/ImsCallSessionImplBase.java
@@ -29,11 +29,14 @@
 import android.telephony.ims.ImsReasonInfo;
 import android.telephony.ims.ImsStreamMediaProfile;
 import android.telephony.ims.ImsSuppServiceNotification;
+import android.telephony.ims.RtpHeaderExtension;
 import android.telephony.ims.aidl.IImsCallSessionListener;
 
 import com.android.ims.internal.IImsCallSession;
 import com.android.ims.internal.IImsVideoCallProvider;
 
+import java.util.List;
+
 /**
  * Compat implementation of ImsCallSessionImplBase for older implementations.
  *
@@ -404,6 +407,15 @@
     }
 
     /**
+     * Device sends RTP header extensions.
+     * @param headerExtensions The header extensions to send.
+     */
+    @Override
+    public void sendRtpHeaderExtensions(@NonNull List<RtpHeaderExtension> headerExtensions) {
+        // no-op; not supported in compat layer.
+    }
+
+    /**
      * There are two different ImsCallSessionListeners that need to reconciled here, we need to
      * convert the "old" version of the com.android.ims.internal.IImsCallSessionListener to the
      * "new" version of the Listener android.telephony.ims.ImsCallSessionListener when calling
diff --git a/telephony/java/android/telephony/ims/feature/CapabilityChangeRequest.java b/telephony/java/android/telephony/ims/feature/CapabilityChangeRequest.java
index 87a5094..87a6873 100644
--- a/telephony/java/android/telephony/ims/feature/CapabilityChangeRequest.java
+++ b/telephony/java/android/telephony/ims/feature/CapabilityChangeRequest.java
@@ -28,8 +28,8 @@
 import java.util.Set;
 
 /**
- * Request to send to IMS provider, which will try to enable/disable capabilities that are added to
- * the request.
+ * Used by the framework to enable and disable MMTEL and RCS capabilities. See
+ * MmTelFeature#changeEnabledCapabilities and RcsFeature#changeEnabledCapabilities.
  * {@hide}
  */
 @SystemApi
diff --git a/telephony/java/android/telephony/ims/feature/RcsFeature.java b/telephony/java/android/telephony/ims/feature/RcsFeature.java
index b8ae146..5de2ddc 100644
--- a/telephony/java/android/telephony/ims/feature/RcsFeature.java
+++ b/telephony/java/android/telephony/ims/feature/RcsFeature.java
@@ -23,12 +23,22 @@
 import android.net.Uri;
 import android.os.RemoteException;
 import android.telephony.ims.RcsContactUceCapability;
+import android.telephony.ims.RcsUceAdapter;
+import android.telephony.ims.aidl.ICapabilityExchangeEventListener;
 import android.telephony.ims.aidl.IImsCapabilityCallback;
 import android.telephony.ims.aidl.IImsRcsFeature;
+import android.telephony.ims.aidl.IOptionsResponseCallback;
+import android.telephony.ims.aidl.IPublishResponseCallback;
 import android.telephony.ims.aidl.IRcsFeatureListener;
+import android.telephony.ims.aidl.ISubscribeResponseCallback;
+import android.telephony.ims.aidl.RcsOptionsResponseAidlWrapper;
+import android.telephony.ims.aidl.RcsPublishResponseAidlWrapper;
+import android.telephony.ims.aidl.RcsSubscribeResponseAidlWrapper;
 import android.telephony.ims.stub.ImsRegistrationImplBase;
-import android.telephony.ims.stub.RcsPresenceExchangeImplBase;
-import android.telephony.ims.stub.RcsSipOptionsImplBase;
+import android.telephony.ims.stub.RcsCapabilityExchangeImplBase;
+import android.telephony.ims.stub.RcsCapabilityExchangeImplBase.OptionsResponseCallback;
+import android.telephony.ims.stub.RcsCapabilityExchangeImplBase.PublishResponseCallback;
+import android.telephony.ims.stub.RcsCapabilityExchangeImplBase.SubscribeResponseCallback;
 import android.util.Log;
 
 import com.android.internal.telephony.util.TelephonyUtils;
@@ -64,9 +74,14 @@
             mExecutor = executor;
         }
 
+        /**
+         * @deprecated This method is deprecated. Please call the method
+         * setCapabilityExchangeEventListener instead.
+         */
         @Override
+        @Deprecated
         public void setListener(IRcsFeatureListener listener) {
-            mReference.setListener(listener);
+            Log.w(LOG_TAG, "The method setListener is deprecated");
         }
 
         @Override
@@ -106,44 +121,66 @@
             return executeMethodAsyncForResult(mReference::getFeatureState, "getFeatureState");
         }
 
+        // RcsCapabilityExchangeImplBase specific APIs
+        @Override
+        public void setCapabilityExchangeEventListener(
+                @NonNull ICapabilityExchangeEventListener listener) throws RemoteException {
+            executeMethodAsync(() -> mReference.setCapabilityExchangeEventListener(listener),
+                    "setCapabilityExchangeEventListener");
+        }
+
+        @Override
+        public void publishCapabilities(@NonNull String pidfXml,
+                @NonNull IPublishResponseCallback callback) throws RemoteException {
+            PublishResponseCallback callbackWrapper = new RcsPublishResponseAidlWrapper(callback);
+            executeMethodAsync(() -> mReference.getCapabilityExchangeImplBaseInternal()
+                    .publishCapabilities(pidfXml, callbackWrapper), "publishCapabilities");
+        }
+
+        @Override
+        public void subscribeForCapabilities(@NonNull List<Uri> uris,
+                @NonNull ISubscribeResponseCallback callback) throws RemoteException {
+            SubscribeResponseCallback wrapper = new RcsSubscribeResponseAidlWrapper(callback);
+            executeMethodAsync(() -> mReference.getCapabilityExchangeImplBaseInternal()
+                    .subscribeForCapabilities(uris, wrapper), "subscribeForCapabilities");
+        }
+
+        @Override
+        public void sendOptionsCapabilityRequest(@NonNull Uri contactUri,
+                @NonNull List<String> myCapabilities, @NonNull IOptionsResponseCallback callback)
+                throws RemoteException {
+            OptionsResponseCallback callbackWrapper = new RcsOptionsResponseAidlWrapper(callback);
+            executeMethodAsync(() -> mReference.getCapabilityExchangeImplBaseInternal()
+                    .sendOptionsCapabilityRequest(contactUri, myCapabilities, callbackWrapper),
+                    "sendOptionsCapabilityRequest");
+        }
+
         // RcsPresenceExchangeImplBase specific APIS
         @Override
         public void requestCapabilities(List<Uri> uris, int operationToken) throws RemoteException {
-            executeMethodAsync(() -> mReference.getPresenceExchangeInternal()
-                    .requestCapabilities(uris, operationToken), "requestCapabilities");
+            throw new RemoteException("Unsupported operation: requestCapabilities");
         }
         @Override
         public void updateCapabilities(RcsContactUceCapability capabilities, int operationToken)
                 throws RemoteException {
-            executeMethodAsync(() -> mReference.getPresenceExchangeInternal()
-                            .updateCapabilities(capabilities, operationToken),
-                    "updateCapabilities");
-
+            throw new RemoteException("Unsupported operation: updateCapabilities");
         }
         // RcsSipOptionsImplBase specific APIS
         @Override
         public void sendCapabilityRequest(Uri contactUri, RcsContactUceCapability capabilities,
                 int operationToken) throws RemoteException {
-            executeMethodAsync(() -> mReference.getOptionsExchangeInternal()
-                            .sendCapabilityRequest(contactUri, capabilities, operationToken),
-                    "sendCapabilityRequest");
-
+            throw new RemoteException("Unsupported operation: sendCapabilityRequest");
         }
         @Override
         public void respondToCapabilityRequest(String contactUri,
                 RcsContactUceCapability ownCapabilities, int operationToken)
                 throws RemoteException {
-            executeMethodAsync(() -> mReference.getOptionsExchangeInternal()
-                            .respondToCapabilityRequest(contactUri, ownCapabilities,
-                                    operationToken), "respondToCapabilityRequest");
-
+            throw new RemoteException("Unsupported operation: respondToCapabilityRequest");
         }
         @Override
         public void respondToCapabilityRequestWithError(Uri contactUri, int code, String reason,
                 int operationToken) throws RemoteException {
-            executeMethodAsync(() -> mReference.getOptionsExchangeInternal()
-                            .respondToCapabilityRequestWithError(contactUri, code, reason,
-                                    operationToken), "respondToCapabilityRequestWithError");
+            throw new RemoteException("Unsupported operation: respondToCapabilityRequestWithError");
         }
 
         // Call the methods with a clean calling identity on the executor and wait indefinitely for
@@ -182,8 +219,8 @@
      * Contains the capabilities defined and supported by a {@link RcsFeature} in the
      * form of a bitmask. The capabilities that are used in the RcsFeature are
      * defined as:
-     * {@link RcsImsCapabilityFlag#CAPABILITY_TYPE_OPTIONS_UCE}
-     * {@link RcsImsCapabilityFlag#CAPABILITY_TYPE_PRESENCE_UCE}
+     * {@link RcsUceAdatper.RcsImsCapabilityFlag#CAPABILITY_TYPE_OPTIONS_UCE}
+     * {@link RceUceAdapter.RcsImsCapabilityFlag#CAPABILITY_TYPE_PRESENCE_UCE}
      *
      * The enabled capabilities of this RcsFeature will be set by the framework
      * using {@link #changeEnabledCapabilities(CapabilityChangeRequest, CapabilityCallbackProxy)}.
@@ -223,7 +260,7 @@
          */
         public static final int CAPABILITY_TYPE_PRESENCE_UCE =  1 << 1;
 
-        public RcsImsCapabilities(@RcsImsCapabilityFlag int capabilities) {
+        public RcsImsCapabilities(@RcsUceAdapter.RcsImsCapabilityFlag int capabilities) {
             super(capabilities);
         }
 
@@ -232,25 +269,24 @@
         }
 
         @Override
-        public void addCapabilities(@RcsImsCapabilityFlag int capabilities) {
+        public void addCapabilities(@RcsUceAdapter.RcsImsCapabilityFlag int capabilities) {
             super.addCapabilities(capabilities);
         }
 
         @Override
-        public void removeCapabilities(@RcsImsCapabilityFlag int capabilities) {
+        public void removeCapabilities(@RcsUceAdapter.RcsImsCapabilityFlag int capabilities) {
             super.removeCapabilities(capabilities);
         }
 
         @Override
-        public boolean isCapable(@RcsImsCapabilityFlag int capabilities) {
+        public boolean isCapable(@RcsUceAdapter.RcsImsCapabilityFlag int capabilities) {
             return super.isCapable(capabilities);
         }
     }
 
     private final RcsFeatureBinder mImsRcsBinder;
-    private IRcsFeatureListener mListenerBinder;
-    private RcsPresenceExchangeImplBase mPresExchange;
-    private RcsSipOptionsImplBase mSipOptions;
+    private RcsCapabilityExchangeImplBase mCapabilityExchangeImpl;
+    private ICapabilityExchangeEventListener mCapExchangeEventListener;
 
     /**
      * Create a new RcsFeature.
@@ -314,7 +350,7 @@
      * @hide
      */
     public boolean queryCapabilityConfiguration(
-            @RcsImsCapabilities.RcsImsCapabilityFlag int capability,
+            @RcsUceAdapter.RcsImsCapabilityFlag int capability,
             @ImsRegistrationImplBase.ImsRegistrationTech int radioTech) {
         // Base Implementation - Override to provide functionality
         return false;
@@ -342,37 +378,22 @@
     }
 
     /**
-     * Retrieve the implementation of SIP OPTIONS for this {@link RcsFeature}.
-     * <p>
-     * Will only be requested by the framework if capability exchange via SIP OPTIONS is
-     * configured as capable during a
+     * Retrieve the implementation of UCE for this {@link RcsFeature}, which can use either
+     * presence or OPTIONS for capability exchange.
+     *
+     * Will only be requested by the framework if capability exchange is configured
+     * as capable during a
      * {@link #changeEnabledCapabilities(CapabilityChangeRequest, CapabilityCallbackProxy)}
      * operation and the RcsFeature sets the status of the capability to true using
      * {@link #notifyCapabilitiesStatusChanged(RcsImsCapabilities)}.
      *
-     * @return An instance of {@link RcsSipOptionsImplBase} that implements SIP options exchange if
-     * it is supported by the device.
-     * @hide
-     */
-    public @NonNull RcsSipOptionsImplBase getOptionsExchangeImpl() {
-        // Base Implementation, override to implement functionality
-        return new RcsSipOptionsImplBase();
-    }
-
-    /**
-     * Retrieve the implementation of UCE presence for this {@link RcsFeature}.
-     * Will only be requested by the framework if presence exchang is configured as capable during
-     * a {@link #changeEnabledCapabilities(CapabilityChangeRequest, CapabilityCallbackProxy)}
-     * operation and the RcsFeature sets the status of the capability to true using
-     * {@link #notifyCapabilitiesStatusChanged(RcsImsCapabilities)}.
-     *
-     * @return An instance of {@link RcsPresenceExchangeImplBase} that implements presence
+     * @return An instance of {@link RcsCapabilityExchangeImplBase} that implements presence
      * exchange if it is supported by the device.
      * @hide
      */
-    public @NonNull RcsPresenceExchangeImplBase getPresenceExchangeImpl() {
-        // Base Implementation, override to implement functionality.
-        return new RcsPresenceExchangeImplBase();
+    public @NonNull RcsCapabilityExchangeImplBase createCapabilityExchangeImpl() {
+        // Base Implementation, override to implement functionality
+        return new RcsCapabilityExchangeImplBase();
     }
 
     /**{@inheritDoc}*/
@@ -395,39 +416,20 @@
         return mImsRcsBinder;
     }
 
-    /**@hide*/
-    public IRcsFeatureListener getListener() {
-        synchronized (mLock) {
-            return mListenerBinder;
+    private void setCapabilityExchangeEventListener(ICapabilityExchangeEventListener listener) {
+        mCapExchangeEventListener = listener;
+        if (mCapExchangeEventListener != null) {
+            onFeatureReady();
         }
     }
 
-    private void setListener(IRcsFeatureListener listener) {
+    private RcsCapabilityExchangeImplBase getCapabilityExchangeImplBaseInternal() {
         synchronized (mLock) {
-            mListenerBinder = listener;
-            if (mListenerBinder != null) {
-                onFeatureReady();
+            if (mCapabilityExchangeImpl == null) {
+                mCapabilityExchangeImpl = createCapabilityExchangeImpl();
+                mCapabilityExchangeImpl.setEventListener(mCapExchangeEventListener);
             }
-        }
-    }
-
-    private RcsPresenceExchangeImplBase getPresenceExchangeInternal() {
-        synchronized (mLock) {
-            if (mPresExchange == null) {
-                mPresExchange = getPresenceExchangeImpl();
-                mPresExchange.initialize(this);
-            }
-            return mPresExchange;
-        }
-    }
-
-    private RcsSipOptionsImplBase getOptionsExchangeInternal() {
-        synchronized (mLock) {
-            if (mSipOptions == null) {
-                mSipOptions = getOptionsExchangeImpl();
-                mSipOptions.initialize(this);
-            }
-            return mSipOptions;
+            return mCapabilityExchangeImpl;
         }
     }
 }
diff --git a/telephony/java/android/telephony/ims/stub/ImsCallSessionImplBase.java b/telephony/java/android/telephony/ims/stub/ImsCallSessionImplBase.java
index 1cebdd5..a3a6cb8 100644
--- a/telephony/java/android/telephony/ims/stub/ImsCallSessionImplBase.java
+++ b/telephony/java/android/telephony/ims/stub/ImsCallSessionImplBase.java
@@ -26,10 +26,17 @@
 import android.telephony.ims.ImsReasonInfo;
 import android.telephony.ims.ImsStreamMediaProfile;
 import android.telephony.ims.ImsVideoCallProvider;
+import android.telephony.ims.RtpHeaderExtension;
+import android.telephony.ims.RtpHeaderExtensionType;
 import android.telephony.ims.aidl.IImsCallSessionListener;
+import android.util.ArraySet;
 
 import com.android.ims.internal.IImsCallSession;
 import com.android.ims.internal.IImsVideoCallProvider;
+
+import java.util.List;
+import java.util.Set;
+
 /**
  * Base implementation of IImsCallSession, which implements stub versions of the methods available.
  *
@@ -277,6 +284,12 @@
         public void sendRttMessage(String rttMessage) {
             ImsCallSessionImplBase.this.sendRttMessage(rttMessage);
         }
+
+        @Override
+        public void sendRtpHeaderExtensions(@NonNull List<RtpHeaderExtension> extensions) {
+            ImsCallSessionImplBase.this.sendRtpHeaderExtensions(
+                    new ArraySet<RtpHeaderExtension>(extensions));
+        }
     };
 
     /**
@@ -636,6 +649,22 @@
     public void sendRttMessage(String rttMessage) {
     }
 
+    /**
+     * Device requests that {@code rtpHeaderExtensions} are sent as a header extension with the next
+     * RTP packet sent by the IMS stack.
+     * <p>
+     * The {@link RtpHeaderExtensionType}s negotiated during SDP (Session Description Protocol)
+     * signalling determine the {@link RtpHeaderExtension}s which can be sent using this method.
+     * See RFC8285 for more information.
+     * <p>
+     * By specification, the RTP header extension is an unacknowledged transmission and there is no
+     * guarantee that the header extension will be delivered by the network to the other end of the
+     * call.
+     * @param rtpHeaderExtensions The RTP header extensions to be included in the next RTP header.
+     */
+    public void sendRtpHeaderExtensions(@NonNull Set<RtpHeaderExtension> rtpHeaderExtensions) {
+    }
+
     /** @hide */
     public IImsCallSession getServiceImpl() {
         return mServiceImpl;
diff --git a/telephony/java/android/telephony/ims/stub/RcsCapabilityExchange.java b/telephony/java/android/telephony/ims/stub/RcsCapabilityExchange.java
index fda295a..0b13efb 100644
--- a/telephony/java/android/telephony/ims/stub/RcsCapabilityExchange.java
+++ b/telephony/java/android/telephony/ims/stub/RcsCapabilityExchange.java
@@ -87,12 +87,8 @@
 
     /** @hide */
     protected final IRcsFeatureListener getListener() throws ImsException {
-        IRcsFeatureListener listener = mFeature.getListener();
-        if (listener == null) {
-            throw new ImsException("Connection to Framework has not been established, wait for "
-                    + "onFeatureReady().", ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
-        }
-        return mFeature.getListener();
+        throw new ImsException("This method is deprecated.",
+                ImsException.CODE_ERROR_UNSUPPORTED_OPERATION);
     }
 
     /**
diff --git a/telephony/java/android/telephony/ims/stub/RcsCapabilityExchangeImplBase.java b/telephony/java/android/telephony/ims/stub/RcsCapabilityExchangeImplBase.java
new file mode 100644
index 0000000..b5704bf
--- /dev/null
+++ b/telephony/java/android/telephony/ims/stub/RcsCapabilityExchangeImplBase.java
@@ -0,0 +1,338 @@
+/*
+ * Copyright (c) 2020 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.telephony.ims.stub;
+
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.net.Uri;
+import android.telephony.ims.ImsException;
+import android.telephony.ims.aidl.ICapabilityExchangeEventListener;
+import android.util.Log;
+import android.util.Pair;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.List;
+
+/**
+ * Base class for different types of Capability exchange.
+ * @hide
+ */
+public class RcsCapabilityExchangeImplBase {
+
+    private static final String LOG_TAG = "RcsCapExchangeImplBase";
+
+    /**
+     * Service is unknown.
+     */
+    public static final int COMMAND_CODE_SERVICE_UNKNOWN = 0;
+
+    /**
+     * The command failed with an unknown error.
+     */
+    public static final int COMMAND_CODE_GENERIC_FAILURE = 1;
+
+    /**
+     * Invalid parameter(s).
+     */
+    public static final int COMMAND_CODE_INVALID_PARAM = 2;
+
+    /**
+     * Fetch error.
+     */
+    public static final int COMMAND_CODE_FETCH_ERROR = 3;
+
+    /**
+     * Request timed out.
+     */
+    public static final int COMMAND_CODE_REQUEST_TIMEOUT = 4;
+
+    /**
+     * Failure due to insufficient memory available.
+     */
+    public static final int COMMAND_CODE_INSUFFICIENT_MEMORY = 5;
+
+    /**
+     * Network connection is lost.
+     * @hide
+     */
+    public static final int COMMAND_CODE_LOST_NETWORK_CONNECTION = 6;
+
+    /**
+     * Requested feature/resource is not supported.
+     * @hide
+     */
+    public static final int COMMAND_CODE_NOT_SUPPORTED = 7;
+
+    /**
+     * Contact or resource is not found.
+     */
+    public static final int COMMAND_CODE_NOT_FOUND = 8;
+
+    /**
+     * Service is not available.
+     */
+    public static final int COMMAND_CODE_SERVICE_UNAVAILABLE = 9;
+
+    /**
+     * Command resulted in no change in state, ignoring.
+     */
+    public static final int COMMAND_CODE_NO_CHANGE = 10;
+
+    /**@hide*/
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = "COMMAND_CODE_", value = {
+            COMMAND_CODE_SERVICE_UNKNOWN,
+            COMMAND_CODE_GENERIC_FAILURE,
+            COMMAND_CODE_INVALID_PARAM,
+            COMMAND_CODE_FETCH_ERROR,
+            COMMAND_CODE_REQUEST_TIMEOUT,
+            COMMAND_CODE_INSUFFICIENT_MEMORY,
+            COMMAND_CODE_LOST_NETWORK_CONNECTION,
+            COMMAND_CODE_NOT_SUPPORTED,
+            COMMAND_CODE_NOT_FOUND,
+            COMMAND_CODE_SERVICE_UNAVAILABLE,
+            COMMAND_CODE_NO_CHANGE
+    })
+    public @interface CommandCode {}
+
+    /**
+     * Interface used by the framework to receive the response of the publish request.
+     */
+    public interface PublishResponseCallback {
+        /**
+         * Notify the framework that the command associated with this callback has failed.
+         *
+         * @param code The reason why the associated command has failed.
+         * @throws ImsException If this {@link RcsCapabilityExchangeImplBase} instance is
+         * not currently connected to the framework. This can happen if the {@link RcsFeature}
+         * is not {@link ImsFeature#STATE_READY} and the {@link RcsFeature} has not received
+         * the {@link ImsFeature#onFeatureReady()} callback. This may also happen in rare cases
+         * when the Telephony stack has crashed.
+         */
+        void onCommandError(@CommandCode int code) throws ImsException;
+
+
+        /**
+         * Provide the framework with a subsequent network response update to
+         * {@link #publishCapabilities(String, PublishResponseCallback)}.
+         *
+         * @param code The SIP response code sent from the network for the operation
+         * token specified.
+         * @param reason The optional reason response from the network. If the network
+         *  provided no reason with the code, the string should be empty.
+         * @throws ImsException If this {@link RcsCapabilityExchangeImplBase} instance is
+         * not currently connected to the framework. This can happen if the {@link RcsFeature}
+         * is not {@link ImsFeature#STATE_READY} and the {@link RcsFeature} has not received
+         * the {@link ImsFeature#onFeatureReady()} callback. This may also happen in rare cases
+         * when the Telephony stack has crashed.
+         */
+        void onNetworkResponse(@IntRange(from = 100, to = 699) int code,
+                @NonNull String reason) throws ImsException;
+    }
+
+    /**
+     * Interface used by the framework to respond to OPTIONS requests.
+     */
+    public interface OptionsResponseCallback {
+        /**
+         * Notify the framework that the command associated with this callback has failed.
+         *
+         * @param code The reason why the associated command has failed.
+         * @throws ImsException If this {@link RcsCapabilityExchangeImplBase} instance is
+         * not currently connected to the framework. This can happen if the
+         * {@link RcsFeature} is not {@link ImsFeature#STATE_READY} and the {@link RcsFeature}
+         * has not received the {@link ImsFeature#onFeatureReady()} callback. This may also happen
+         * in rare cases when the Telephony stack has crashed.
+         */
+        void onCommandError(@CommandCode int code) throws ImsException;
+
+        /**
+         * Send the response of a SIP OPTIONS capability exchange to the framework.
+         * @param code The SIP response code that was sent by the network in response
+         * to the request sent by {@link #sendOptionsCapabilityRequest}.
+         * @param reason The optional SIP response reason sent by the network.
+         * If none was sent, this should be an empty string.
+         * @param theirCaps the contact's UCE capabilities associated with the
+         * capability request.
+         * @throws ImsException If this {@link RcsSipOptionsImplBase} instance is not
+         * currently connected to the framework. This can happen if the
+         * {@link RcsFeature} is not {@link ImsFeature#STATE_READY} and the
+         * {@link RcsFeature} has not received the
+         * {@link ImsFeature#onFeatureReady()} callback. This may also happen in rare
+         * cases when the Telephony stack has crashed.
+         */
+        void onNetworkResponse(int code, @NonNull String reason,
+                @Nullable List<String> theirCaps) throws ImsException;
+    }
+
+    /**
+     * Interface used by the framework to receive the response of the subscribe request.
+     */
+    public interface SubscribeResponseCallback {
+        /**
+         * Notify the framework that the command associated with this callback has failed.
+         *
+         * @param code The reason why the associated command has failed.
+         * @throws ImsException If this {@link RcsCapabilityExchangeImplBase} instance is
+         * not currently connected to the framework. This can happen if the
+         * {@link RcsFeature} is not
+         * {@link ImsFeature#STATE_READY} and the {@link RcsFeature} has not received
+         * the {@link ImsFeature#onFeatureReady()} callback. This may also happen in
+         * rare cases when the Telephony stack has crashed.
+         */
+        void onCommandError(@CommandCode int code) throws ImsException;
+
+        /**
+         * Notify the framework of the response to the SUBSCRIBE request from
+         * {@link #subscribeForCapabilities(List<Uri>, SubscribeResponseCallback)}.
+         *
+         * @param code The SIP response code sent from the network for the operation
+         * token specified.
+         * @param reason The optional reason response from the network. If the network
+         *  provided no reason with the code, the string should be empty.
+         * @throws ImsException If this {@link RcsCapabilityExchangeImplBase} instance is
+         * not currently connected to the framework. This can happen if the
+         * {@link RcsFeature} is not {@link ImsFeature#STATE_READY} and the
+         * {@link RcsFeature} has not received the {@link ImsFeature#onFeatureReady()} callback.
+         * This may also happen in rare cases when the Telephony stack has crashed.
+         */
+        void onNetworkResponse(@IntRange(from = 100, to = 699) int code,
+                @NonNull String reason) throws ImsException;
+
+        /**
+         * Provides the framework with latest XML PIDF documents included in the
+         * network response for the requested  contacts' capabilities requested by the
+         * Framework  using {@link #requestCapabilities(List, int)}. This should be
+         * called every time a new NOTIFY event is received with new capability
+         * information.
+         *
+         * @throws ImsException If this {@link RcsCapabilityExchangeImplBase} instance is
+         * not currently
+         * connected to the framework. This can happen if the {@link RcsFeature} is not
+         * {@link ImsFeature#STATE_READY} and the {@link RcsFeature} has not received
+         * the {@link ImsFeature#onFeatureReady()} callback. This may also happen in
+         * rare cases when the
+         * Telephony stack has crashed.
+         */
+        void onNotifyCapabilitiesUpdate(@NonNull List<String> pidfXmls) throws ImsException;
+
+        /**
+         * A resource in the resource list for the presence subscribe event has been terminated.
+         * <p>
+         * This allows the framework to know that there will not be any capability information for
+         * a specific contact URI that they subscribed for.
+         */
+        void onResourceTerminated(
+                @NonNull List<Pair<Uri, String>> uriTerminatedReason) throws ImsException;
+
+        /**
+         * The subscription associated with a previous #requestCapabilities operation
+         * has been terminated. This will mostly be due to the subscription expiring,
+         * but may also happen due to an error.
+         * <p>
+         * This allows the framework to know that there will no longer be any
+         * capability updates for the requested operationToken.
+         */
+        void onTerminated(String reason, String retryAfter) throws ImsException;
+    }
+
+
+    private ICapabilityExchangeEventListener mListener;
+
+    /**
+     * Set the event listener to send the request to Framework.
+     */
+    public void setEventListener(ICapabilityExchangeEventListener listener) {
+        mListener = listener;
+    }
+
+    /**
+     * Get the event listener.
+     */
+    public ICapabilityExchangeEventListener getEventListener() {
+        return mListener;
+    }
+
+    /**
+     * The user capabilities of one or multiple contacts have been requested by the framework.
+     * <p>
+     * The response from the network to the SUBSCRIBE request must be sent back to the framework
+     * using {@link #onSubscribeNetworkResponse(int, String, int)}. As NOTIFY requests come in from
+     * the network, the requested contact’s capabilities should be sent back to the framework using
+     * {@link #onSubscribeNotifyRequest} and {@link onSubscribeResourceTerminated}
+     * should be called with the presence information for the contacts specified.
+     * <p>
+     * Once the subscription is terminated, {@link #onSubscriptionTerminated} must be called for
+     * the framework to finish listening for NOTIFY responses.
+     * @param uris A {@link List} of the {@link Uri}s that the framework is requesting the UCE
+     * capabilities for.
+     * @param cb The callback of the subscribe request.
+     */
+    public void subscribeForCapabilities(@NonNull List<Uri> uris,
+            @NonNull SubscribeResponseCallback cb) {
+        // Stub - to be implemented by service
+        Log.w(LOG_TAG, "subscribeForCapabilities called with no implementation.");
+        try {
+            cb.onCommandError(COMMAND_CODE_NOT_SUPPORTED);
+        } catch (ImsException e) {
+            // Do not do anything, this is a stub implementation.
+        }
+    }
+
+    /**
+     * The capabilities of this device have been updated and should be published to the network.
+     * <p>
+     * If this operation succeeds, network response updates should be sent to the framework using
+     * {@link #onNetworkResponse(int, String)}.
+     * @param pidfXml The XML PIDF document containing the capabilities of this device to be sent
+     * to the carrier’s presence server.
+     * @param cb The callback of the publish request
+     */
+    public void publishCapabilities(@NonNull String pidfXml, @NonNull PublishResponseCallback cb) {
+        // Stub - to be implemented by service
+        Log.w(LOG_TAG, "publishCapabilities called with no implementation.");
+        try {
+            cb.onCommandError(COMMAND_CODE_NOT_SUPPORTED);
+        } catch (ImsException e) {
+            // Do not do anything, this is a stub implementation.
+        }
+    }
+
+    /**
+     * Push one's own capabilities to a remote user via the SIP OPTIONS presence exchange mechanism
+     * in order to receive the capabilities of the remote user in response.
+     * <p>
+     * The implementer must call {@link #onNetworkResponse} to send the response of this
+     * query back to the framework.
+     * @param contactUri The URI of the remote user that we wish to get the capabilities of.
+     * @param myCapabilities The capabilities of this device to send to the remote user.
+     * @param callback The callback of this request which is sent from the remote user.
+     */
+    public void sendOptionsCapabilityRequest(@NonNull Uri contactUri,
+            @NonNull List<String> myCapabilities, @NonNull OptionsResponseCallback callback) {
+        // Stub - to be implemented by service
+        Log.w(LOG_TAG, "sendOptionsCapabilityRequest called with no implementation.");
+        try {
+            callback.onCommandError(COMMAND_CODE_NOT_SUPPORTED);
+        } catch (ImsException e) {
+            // Do not do anything, this is a stub implementation.
+        }
+    }
+}
diff --git a/telephony/java/com/android/ims/internal/IImsCallSession.aidl b/telephony/java/com/android/ims/internal/IImsCallSession.aidl
index ab14e82..e3a8aee 100644
--- a/telephony/java/com/android/ims/internal/IImsCallSession.aidl
+++ b/telephony/java/com/android/ims/internal/IImsCallSession.aidl
@@ -20,6 +20,8 @@
 import android.telephony.ims.aidl.IImsCallSessionListener;
 import android.telephony.ims.ImsCallProfile;
 import android.telephony.ims.ImsStreamMediaProfile;
+import android.telephony.ims.RtpHeaderExtension;
+
 import com.android.ims.internal.IImsVideoCallProvider;
 
 /**
@@ -297,4 +299,10 @@
      * @param rttMessage RTT message to be sent
      */
     void sendRttMessage(in String rttMessage);
+
+    /*
+     * Device sends RTP header extension(s).
+     * @param extensions the header extensions to be sent
+     */
+    void sendRtpHeaderExtensions(in List<RtpHeaderExtension> extensions);
 }
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 7945636..a8a491a 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -2216,4 +2216,20 @@
      * does not exist on the SIM card.
      */
     List<String> getEquivalentHomePlmns(int subId, String callingPackage, String callingFeatureId);
+
+    /**
+     * Enable/Disable E-UTRA-NR Dual Connectivity
+     * @return operation result. See TelephonyManager.EnableNrDualConnectivityResult for
+     * details
+     * @param subId the id of the subscription
+     * @param enable enable/disable dual connectivity
+     */
+    int setNrDualConnectivityState(int subId, int nrDualConnectivityState);
+
+    /**
+     * Is E-UTRA-NR Dual Connectivity enabled
+     * @param subId the id of the subscription
+     * @return true if dual connectivity is enabled else false
+     */
+    boolean isNrDualConnectivityEnabled(int subId);
 }
diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java
index ca7efcd..d3c27dc4 100644
--- a/telephony/java/com/android/internal/telephony/RILConstants.java
+++ b/telephony/java/com/android/internal/telephony/RILConstants.java
@@ -30,77 +30,96 @@
 
     // from RIL_Errno
     int SUCCESS = 0;
-    int RADIO_NOT_AVAILABLE = 1;              /* If radio did not start or is resetting */
+    int RADIO_NOT_AVAILABLE = 1;                    /* If radio did not start or is resetting */
     int GENERIC_FAILURE = 2;
-    int PASSWORD_INCORRECT = 3;               /* for PIN/PIN2 methods only! */
-    int SIM_PIN2 = 4;                         /* Operation requires SIM PIN2 to be entered */
-    int SIM_PUK2 = 5;                         /* Operation requires SIM PIN2 to be entered */
+    int PASSWORD_INCORRECT = 3;                     /* for PIN/PIN2 methods only! */
+    int SIM_PIN2 = 4;                               /* Operation requires SIM PIN2 to be entered */
+    int SIM_PUK2 = 5;                               /* Operation requires SIM PIN2 to be entered */
     int REQUEST_NOT_SUPPORTED = 6;
     int REQUEST_CANCELLED = 7;
-    int OP_NOT_ALLOWED_DURING_VOICE_CALL = 8; /* data operation is not allowed during voice call in
-                                                 class C */
-    int OP_NOT_ALLOWED_BEFORE_REG_NW = 9;     /* request is not allowed before device registers to
-                                                 network */
-    int SMS_SEND_FAIL_RETRY = 10;             /* send sms fail and need retry */
-    int SIM_ABSENT = 11;                      /* ICC card is absent */
-    int SUBSCRIPTION_NOT_AVAILABLE = 12;      /* fail to find CDMA subscription from specified
-                                                 location */
-    int MODE_NOT_SUPPORTED = 13;              /* HW does not support preferred network type */
-    int FDN_CHECK_FAILURE = 14;               /* send operation barred error when FDN is enabled */
-    int ILLEGAL_SIM_OR_ME = 15;               /* network selection failure due
-                                                 to wrong SIM/ME and no
-                                                 retries needed */
-    int MISSING_RESOURCE = 16;                /* no logical channel available */
-    int NO_SUCH_ELEMENT = 17;                 /* application not found on SIM */
-    int DIAL_MODIFIED_TO_USSD = 18;           /* DIAL request modified to USSD */
-    int DIAL_MODIFIED_TO_SS = 19;             /* DIAL request modified to SS */
-    int DIAL_MODIFIED_TO_DIAL = 20;           /* DIAL request modified to DIAL with different data*/
-    int USSD_MODIFIED_TO_DIAL = 21;           /* USSD request modified to DIAL */
-    int USSD_MODIFIED_TO_SS = 22;             /* USSD request modified to SS */
-    int USSD_MODIFIED_TO_USSD = 23;           /* USSD request modified to different USSD request */
-    int SS_MODIFIED_TO_DIAL = 24;             /* SS request modified to DIAL */
-    int SS_MODIFIED_TO_USSD = 25;             /* SS request modified to USSD */
-    int SUBSCRIPTION_NOT_SUPPORTED = 26;      /* Subscription not supported */
-    int SS_MODIFIED_TO_SS = 27;               /* SS request modified to different SS request */
-    int SIM_ALREADY_POWERED_OFF = 29;         /* SAP: 0x03, Error card aleready powered off */
-    int SIM_ALREADY_POWERED_ON = 30;          /* SAP: 0x05, Error card already powered on */
-    int SIM_DATA_NOT_AVAILABLE = 31;          /* SAP: 0x06, Error data not available */
+    int OP_NOT_ALLOWED_DURING_VOICE_CALL = 8;       /* data operation is not allowed during voice
+                                                       call in class C */
+    int OP_NOT_ALLOWED_BEFORE_REG_NW = 9;           /* request is not allowed before device
+                                                       registers to network */
+    int SMS_SEND_FAIL_RETRY = 10;                   /* send sms fail and need retry */
+    int SIM_ABSENT = 11;                            /* ICC card is absent */
+    int SUBSCRIPTION_NOT_AVAILABLE = 12;            /* fail to find CDMA subscription from specified
+                                                       location */
+    int MODE_NOT_SUPPORTED = 13;                    /* HW does not support preferred network type */
+    int FDN_CHECK_FAILURE = 14;                     /* send operation barred error when FDN is
+                                                       enabled */
+    int ILLEGAL_SIM_OR_ME = 15;                     /* network selection failure due to wrong
+                                                       SIM/ME and no retries needed */
+    int MISSING_RESOURCE = 16;                      /* no logical channel available */
+    int NO_SUCH_ELEMENT = 17;                       /* application not found on SIM */
+    int DIAL_MODIFIED_TO_USSD = 18;                 /* DIAL request modified to USSD */
+    int DIAL_MODIFIED_TO_SS = 19;                   /* DIAL request modified to SS */
+    int DIAL_MODIFIED_TO_DIAL = 20;                 /* DIAL request modified to DIAL with
+                                                       different data*/
+    int USSD_MODIFIED_TO_DIAL = 21;                 /* USSD request modified to DIAL */
+    int USSD_MODIFIED_TO_SS = 22;                   /* USSD request modified to SS */
+    int USSD_MODIFIED_TO_USSD = 23;                 /* USSD request modified to different USSD
+                                                       request */
+    int SS_MODIFIED_TO_DIAL = 24;                   /* SS request modified to DIAL */
+    int SS_MODIFIED_TO_USSD = 25;                   /* SS request modified to USSD */
+    int SUBSCRIPTION_NOT_SUPPORTED = 26;            /* Subscription not supported */
+    int SS_MODIFIED_TO_SS = 27;                     /* SS request modified to different SS
+                                                       request */
+    int SIM_ALREADY_POWERED_OFF = 29;               /* SAP: 0x03, Error card aleready powered off */
+    int SIM_ALREADY_POWERED_ON = 30;                /* SAP: 0x05, Error card already powered on */
+    int SIM_DATA_NOT_AVAILABLE = 31;                /* SAP: 0x06, Error data not available */
     int SIM_SAP_CONNECT_FAILURE = 32;
     int SIM_SAP_MSG_SIZE_TOO_LARGE = 33;
     int SIM_SAP_MSG_SIZE_TOO_SMALL = 34;
     int SIM_SAP_CONNECT_OK_CALL_ONGOING = 35;
-    int LCE_NOT_SUPPORTED = 36;               /* Link Capacity Estimation (LCE) not supported */
-    int NO_MEMORY = 37;                       /* Not sufficient memory to process the request */
-    int INTERNAL_ERR = 38;                    /* Hit unexpected vendor internal error scenario */
-    int SYSTEM_ERR = 39;                      /* Hit platform or system error */
-    int MODEM_ERR = 40;                       /* Hit unexpected modem error */
-    int INVALID_STATE = 41;                   /* Unexpected request for the current state */
-    int NO_RESOURCES = 42;                    /* Not sufficient resource to process the request */
-    int SIM_ERR = 43;                         /* Received error from SIM card */
-    int INVALID_ARGUMENTS = 44;               /* Received invalid arguments in request */
-    int INVALID_SIM_STATE = 45;               /* Can not process the request in current SIM state */
-    int INVALID_MODEM_STATE = 46;             /* Can not process the request in current Modem state */
-    int INVALID_CALL_ID = 47;                 /* Received invalid call id in request */
-    int NO_SMS_TO_ACK = 48;                   /* ACK received when there is no SMS to ack */
-    int NETWORK_ERR = 49;                     /* Received error from network */
-    int REQUEST_RATE_LIMITED = 50;            /* Operation denied due to overly-frequent requests */
-    int SIM_BUSY = 51;                        /* SIM is busy */
-    int SIM_FULL = 52;                        /* The target EF is full */
-    int NETWORK_REJECT = 53;                  /* Request is rejected by network */
-    int OPERATION_NOT_ALLOWED = 54;           /* Not allowed the request now */
-    int EMPTY_RECORD = 55;                    /* The request record is empty */
-    int INVALID_SMS_FORMAT = 56;              /* Invalid sms format */
-    int ENCODING_ERR = 57;                    /* Message not encoded properly */
-    int INVALID_SMSC_ADDRESS = 58;            /* SMSC address specified is invalid */
-    int NO_SUCH_ENTRY = 59;                   /* No such entry present to perform the request */
-    int NETWORK_NOT_READY = 60;               /* Network is not ready to perform the request */
-    int NOT_PROVISIONED = 61;                 /* Device doesnot have this value provisioned */
-    int NO_SUBSCRIPTION = 62;                 /* Device doesnot have subscription */
-    int NO_NETWORK_FOUND = 63;                /* Network cannot be found */
-    int DEVICE_IN_USE = 64;                   /* Operation cannot be performed because the device
-                                                 is currently in use */
-    int ABORTED = 65;                         /* Operation aborted */
-    int INVALID_RESPONSE = 66;                /* Invalid response sent by vendor code */
+    int LCE_NOT_SUPPORTED = 36;                     /* Link Capacity Estimation (LCE) not
+                                                       supported */
+    int NO_MEMORY = 37;                             /* Not sufficient memory to process the
+                                                       request */
+    int INTERNAL_ERR = 38;                          /* Hit unexpected vendor internal error
+                                                       scenario */
+    int SYSTEM_ERR = 39;                            /* Hit platform or system error */
+    int MODEM_ERR = 40;                             /* Hit unexpected modem error */
+    int INVALID_STATE = 41;                         /* Unexpected request for the current state */
+    int NO_RESOURCES = 42;                          /* Not sufficient resource to process the
+                                                       request */
+    int SIM_ERR = 43;                               /* Received error from SIM card */
+    int INVALID_ARGUMENTS = 44;                     /* Received invalid arguments in request */
+    int INVALID_SIM_STATE = 45;                     /* Can not process the request in current SIM
+                                                       state */
+    int INVALID_MODEM_STATE = 46;                   /* Can not process the request in current Modem
+                                                       state */
+    int INVALID_CALL_ID = 47;                       /* Received invalid call id in request */
+    int NO_SMS_TO_ACK = 48;                         /* ACK received when there is no SMS to ack */
+    int NETWORK_ERR = 49;                           /* Received error from network */
+    int REQUEST_RATE_LIMITED = 50;                  /* Operation denied due to overly-frequent
+                                                       requests */
+    int SIM_BUSY = 51;                              /* SIM is busy */
+    int SIM_FULL = 52;                              /* The target EF is full */
+    int NETWORK_REJECT = 53;                        /* Request is rejected by network */
+    int OPERATION_NOT_ALLOWED = 54;                 /* Not allowed the request now */
+    int EMPTY_RECORD = 55;                          /* The request record is empty */
+    int INVALID_SMS_FORMAT = 56;                    /* Invalid sms format */
+    int ENCODING_ERR = 57;                          /* Message not encoded properly */
+    int INVALID_SMSC_ADDRESS = 58;                  /* SMSC address specified is invalid */
+    int NO_SUCH_ENTRY = 59;                         /* No such entry present to perform the
+                                                       request */
+    int NETWORK_NOT_READY = 60;                     /* Network is not ready to perform the
+                                                       request */
+    int NOT_PROVISIONED = 61;                       /* Device doesnot have this value
+                                                       provisioned */
+    int NO_SUBSCRIPTION = 62;                       /* Device doesnot have subscription */
+    int NO_NETWORK_FOUND = 63;                      /* Network cannot be found */
+    int DEVICE_IN_USE = 64;                         /* Operation cannot be performed because the
+                                                       device is currently in use */
+    int ABORTED = 65;                               /* Operation aborted */
+    int INVALID_RESPONSE = 66;                      /* Invalid response sent by vendor code */
+    int SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED = 67; /* 1X voice and SMS are not allowed
+                                                       simulteneously */
+    int ACCESS_BARRED = 68;                         /* SMS access is barred */
+    int BLOCKED_DUE_TO_CALL = 69;                   /* SMS is blocked due to call control */
+    int RF_HARDWARE_ISSUE = 70;                     /* RF HW issue is detected */
+    int NO_RF_CALIBRATION_INFO = 71;                /* No RF calibration in device */
 
     // Below is list of OEM specific error codes which can by used by OEMs in case they don't want to
     // reveal particular replacement for Generic failure
@@ -494,6 +513,8 @@
     int RIL_REQUEST_SET_SYSTEM_SELECTION_CHANNELS = 210;
     int RIL_REQUEST_GET_BARRING_INFO = 211;
     int RIL_REQUEST_ENTER_SIM_DEPERSONALIZATION = 212;
+    int RIL_REQUEST_ENABLE_NR_DUAL_CONNECTIVITY = 213;
+    int RIL_REQUEST_IS_NR_DUAL_CONNECTIVITY_ENABLED = 214;
     int RIL_REQUEST_ALLOCATE_PDU_SESSION_ID = 215;
     int RIL_REQUEST_RELEASE_PDU_SESSION_ID = 216;
     int RIL_REQUEST_BEGIN_HANDOVER = 217;
diff --git a/tests/net/common/java/android/net/NetworkCapabilitiesTest.java b/tests/net/common/java/android/net/NetworkCapabilitiesTest.java
index 11a83eb..6b7ea66 100644
--- a/tests/net/common/java/android/net/NetworkCapabilitiesTest.java
+++ b/tests/net/common/java/android/net/NetworkCapabilitiesTest.java
@@ -359,7 +359,7 @@
         assertFalse(nr.satisfiedByNetworkCapabilities(new NetworkCapabilities()));
     }
 
-    @Test
+    @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
diff --git a/tests/net/java/com/android/server/connectivity/MultipathPolicyTrackerTest.java b/tests/net/java/com/android/server/connectivity/MultipathPolicyTrackerTest.java
index de1028c..c53462c 100644
--- a/tests/net/java/com/android/server/connectivity/MultipathPolicyTrackerTest.java
+++ b/tests/net/java/com/android/server/connectivity/MultipathPolicyTrackerTest.java
@@ -34,6 +34,7 @@
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.argThat;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -53,6 +54,7 @@
 import android.net.StringNetworkSpecifier;
 import android.net.TelephonyNetworkSpecifier;
 import android.os.Handler;
+import android.os.UserHandle;
 import android.provider.Settings;
 import android.telephony.TelephonyManager;
 import android.test.mock.MockContentResolver;
@@ -91,6 +93,7 @@
     private static final int POLICY_SNOOZED = -100;
 
     @Mock private Context mContext;
+    @Mock private Context mUserAllContext;
     @Mock private Resources mResources;
     @Mock private Handler mHandler;
     @Mock private MultipathPolicyTracker.Dependencies mDeps;
@@ -127,8 +130,11 @@
 
         when(mContext.getResources()).thenReturn(mResources);
         when(mContext.getApplicationInfo()).thenReturn(new ApplicationInfo());
-        when(mContext.registerReceiverAsUser(mConfigChangeReceiverCaptor.capture(),
-                any(), argThat(f -> f.hasAction(ACTION_CONFIGURATION_CHANGED)), any(), any()))
+        doReturn(UserHandle.ALL.getIdentifier()).when(mUserAllContext).getUserId();
+        when(mContext.createContextAsUser(eq(UserHandle.ALL), anyInt()))
+                .thenReturn(mUserAllContext);
+        when(mUserAllContext.registerReceiver(mConfigChangeReceiverCaptor.capture(),
+                argThat(f -> f.hasAction(ACTION_CONFIGURATION_CHANGED)), any(), any()))
                 .thenReturn(null);
 
         when(mDeps.getClock()).thenReturn(mClock);
diff --git a/tests/net/java/com/android/server/connectivity/VpnTest.java b/tests/net/java/com/android/server/connectivity/VpnTest.java
index 2fa0914..a553b58 100644
--- a/tests/net/java/com/android/server/connectivity/VpnTest.java
+++ b/tests/net/java/com/android/server/connectivity/VpnTest.java
@@ -241,7 +241,7 @@
         doNothing().when(mNetService).registerObserver(any());
 
         // Deny all appops by default.
-        when(mAppOps.noteOpNoThrow(anyInt(), anyInt(), anyString()))
+        when(mAppOps.noteOpNoThrow(anyString(), anyInt(), anyString(), any(), any()))
                 .thenReturn(AppOpsManager.MODE_IGNORED);
 
         // Setup IpSecService
@@ -729,26 +729,27 @@
         assertEquals(expected, vpn.getProfileNameForPackage(TEST_VPN_PKG));
     }
 
-    private Vpn createVpnAndSetupUidChecks(int... grantedOps) throws Exception {
+    private Vpn createVpnAndSetupUidChecks(String... grantedOps) throws Exception {
         return createVpnAndSetupUidChecks(primaryUser, grantedOps);
     }
 
-    private Vpn createVpnAndSetupUidChecks(UserInfo user, int... grantedOps) throws Exception {
+    private Vpn createVpnAndSetupUidChecks(UserInfo user, String... grantedOps) throws Exception {
         final Vpn vpn = createVpn(user.id);
         setMockedUsers(user);
 
         when(mPackageManager.getPackageUidAsUser(eq(TEST_VPN_PKG), anyInt()))
                 .thenReturn(Process.myUid());
 
-        for (final int op : grantedOps) {
-            when(mAppOps.noteOpNoThrow(op, Process.myUid(), TEST_VPN_PKG))
+        for (final String opStr : grantedOps) {
+            when(mAppOps.noteOpNoThrow(opStr, Process.myUid(), TEST_VPN_PKG,
+                    null /* attributionTag */, null /* message */))
                     .thenReturn(AppOpsManager.MODE_ALLOWED);
         }
 
         return vpn;
     }
 
-    private void checkProvisionVpnProfile(Vpn vpn, boolean expectedResult, int... checkedOps) {
+    private void checkProvisionVpnProfile(Vpn vpn, boolean expectedResult, String... checkedOps) {
         assertEquals(expectedResult, vpn.provisionVpnProfile(TEST_VPN_PKG, mVpnProfile, mKeyStore));
 
         // The profile should always be stored, whether or not consent has been previously granted.
@@ -759,8 +760,9 @@
                         eq(Process.SYSTEM_UID),
                         eq(0));
 
-        for (final int checkedOp : checkedOps) {
-            verify(mAppOps).noteOpNoThrow(checkedOp, Process.myUid(), TEST_VPN_PKG);
+        for (final String checkedOpStr : checkedOps) {
+            verify(mAppOps).noteOpNoThrow(checkedOpStr, Process.myUid(), TEST_VPN_PKG,
+                    null /* attributionTag */, null /* message */);
         }
     }
 
@@ -768,11 +770,11 @@
     public void testProvisionVpnProfileNoIpsecTunnels() throws Exception {
         when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_IPSEC_TUNNELS))
                 .thenReturn(false);
-        final Vpn vpn = createVpnAndSetupUidChecks(AppOpsManager.OP_ACTIVATE_PLATFORM_VPN);
+        final Vpn vpn = createVpnAndSetupUidChecks(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN);
 
         try {
             checkProvisionVpnProfile(
-                    vpn, true /* expectedResult */, AppOpsManager.OP_ACTIVATE_PLATFORM_VPN);
+                    vpn, true /* expectedResult */, AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN);
             fail("Expected exception due to missing feature");
         } catch (UnsupportedOperationException expected) {
         }
@@ -780,10 +782,10 @@
 
     @Test
     public void testProvisionVpnProfilePreconsented() throws Exception {
-        final Vpn vpn = createVpnAndSetupUidChecks(AppOpsManager.OP_ACTIVATE_PLATFORM_VPN);
+        final Vpn vpn = createVpnAndSetupUidChecks(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN);
 
         checkProvisionVpnProfile(
-                vpn, true /* expectedResult */, AppOpsManager.OP_ACTIVATE_PLATFORM_VPN);
+                vpn, true /* expectedResult */, AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN);
     }
 
     @Test
@@ -793,19 +795,19 @@
         // Expect that both the ACTIVATE_VPN and ACTIVATE_PLATFORM_VPN were tried, but the caller
         // had neither.
         checkProvisionVpnProfile(vpn, false /* expectedResult */,
-                AppOpsManager.OP_ACTIVATE_PLATFORM_VPN, AppOpsManager.OP_ACTIVATE_VPN);
+                AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN, AppOpsManager.OPSTR_ACTIVATE_VPN);
     }
 
     @Test
     public void testProvisionVpnProfileVpnServicePreconsented() throws Exception {
-        final Vpn vpn = createVpnAndSetupUidChecks(AppOpsManager.OP_ACTIVATE_VPN);
+        final Vpn vpn = createVpnAndSetupUidChecks(AppOpsManager.OPSTR_ACTIVATE_VPN);
 
-        checkProvisionVpnProfile(vpn, true /* expectedResult */, AppOpsManager.OP_ACTIVATE_VPN);
+        checkProvisionVpnProfile(vpn, true /* expectedResult */, AppOpsManager.OPSTR_ACTIVATE_VPN);
     }
 
     @Test
     public void testProvisionVpnProfileTooLarge() throws Exception {
-        final Vpn vpn = createVpnAndSetupUidChecks(AppOpsManager.OP_ACTIVATE_PLATFORM_VPN);
+        final Vpn vpn = createVpnAndSetupUidChecks(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN);
 
         final VpnProfile bigProfile = new VpnProfile("");
         bigProfile.name = new String(new byte[Vpn.MAX_VPN_PROFILE_SIZE_BYTES + 1]);
@@ -821,7 +823,7 @@
     public void testProvisionVpnProfileRestrictedUser() throws Exception {
         final Vpn vpn =
                 createVpnAndSetupUidChecks(
-                        restrictedProfileA, AppOpsManager.OP_ACTIVATE_PLATFORM_VPN);
+                        restrictedProfileA, AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN);
 
         try {
             vpn.provisionVpnProfile(TEST_VPN_PKG, mVpnProfile, mKeyStore);
@@ -844,7 +846,7 @@
     public void testDeleteVpnProfileRestrictedUser() throws Exception {
         final Vpn vpn =
                 createVpnAndSetupUidChecks(
-                        restrictedProfileA, AppOpsManager.OP_ACTIVATE_PLATFORM_VPN);
+                        restrictedProfileA, AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN);
 
         try {
             vpn.deleteVpnProfile(TEST_VPN_PKG, mKeyStore);
@@ -867,7 +869,7 @@
 
     @Test
     public void testStartVpnProfile() throws Exception {
-        final Vpn vpn = createVpnAndSetupUidChecks(AppOpsManager.OP_ACTIVATE_PLATFORM_VPN);
+        final Vpn vpn = createVpnAndSetupUidChecks(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN);
 
         when(mKeyStore.get(vpn.getProfileNameForPackage(TEST_VPN_PKG)))
                 .thenReturn(mVpnProfile.encode());
@@ -877,14 +879,16 @@
         verify(mKeyStore).get(eq(vpn.getProfileNameForPackage(TEST_VPN_PKG)));
         verify(mAppOps)
                 .noteOpNoThrow(
-                        eq(AppOpsManager.OP_ACTIVATE_PLATFORM_VPN),
+                        eq(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN),
                         eq(Process.myUid()),
-                        eq(TEST_VPN_PKG));
+                        eq(TEST_VPN_PKG),
+                        eq(null) /* attributionTag */,
+                        eq(null) /* message */);
     }
 
     @Test
     public void testStartVpnProfileVpnServicePreconsented() throws Exception {
-        final Vpn vpn = createVpnAndSetupUidChecks(AppOpsManager.OP_ACTIVATE_VPN);
+        final Vpn vpn = createVpnAndSetupUidChecks(AppOpsManager.OPSTR_ACTIVATE_VPN);
 
         when(mKeyStore.get(vpn.getProfileNameForPackage(TEST_VPN_PKG)))
                 .thenReturn(mVpnProfile.encode());
@@ -892,7 +896,8 @@
         vpn.startVpnProfile(TEST_VPN_PKG, mKeyStore);
 
         // Verify that the the ACTIVATE_VPN appop was checked, but no error was thrown.
-        verify(mAppOps).noteOpNoThrow(AppOpsManager.OP_ACTIVATE_VPN, Process.myUid(), TEST_VPN_PKG);
+        verify(mAppOps).noteOpNoThrow(AppOpsManager.OPSTR_ACTIVATE_VPN, Process.myUid(),
+                TEST_VPN_PKG, null /* attributionTag */, null /* message */);
     }
 
     @Test
@@ -908,10 +913,13 @@
         // Verify both appops were checked.
         verify(mAppOps)
                 .noteOpNoThrow(
-                        eq(AppOpsManager.OP_ACTIVATE_PLATFORM_VPN),
+                        eq(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN),
                         eq(Process.myUid()),
-                        eq(TEST_VPN_PKG));
-        verify(mAppOps).noteOpNoThrow(AppOpsManager.OP_ACTIVATE_VPN, Process.myUid(), TEST_VPN_PKG);
+                        eq(TEST_VPN_PKG),
+                        eq(null) /* attributionTag */,
+                        eq(null) /* message */);
+        verify(mAppOps).noteOpNoThrow(AppOpsManager.OPSTR_ACTIVATE_VPN, Process.myUid(),
+                TEST_VPN_PKG, null /* attributionTag */, null /* message */);
 
         // Keystore should never have been accessed.
         verify(mKeyStore, never()).get(any());
@@ -919,7 +927,7 @@
 
     @Test
     public void testStartVpnProfileMissingProfile() throws Exception {
-        final Vpn vpn = createVpnAndSetupUidChecks(AppOpsManager.OP_ACTIVATE_PLATFORM_VPN);
+        final Vpn vpn = createVpnAndSetupUidChecks(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN);
 
         when(mKeyStore.get(vpn.getProfileNameForPackage(TEST_VPN_PKG))).thenReturn(null);
 
@@ -932,16 +940,18 @@
         verify(mKeyStore).get(vpn.getProfileNameForPackage(TEST_VPN_PKG));
         verify(mAppOps)
                 .noteOpNoThrow(
-                        eq(AppOpsManager.OP_ACTIVATE_PLATFORM_VPN),
+                        eq(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN),
                         eq(Process.myUid()),
-                        eq(TEST_VPN_PKG));
+                        eq(TEST_VPN_PKG),
+                        eq(null) /* attributionTag */,
+                        eq(null) /* message */);
     }
 
     @Test
     public void testStartVpnProfileRestrictedUser() throws Exception {
         final Vpn vpn =
                 createVpnAndSetupUidChecks(
-                        restrictedProfileA, AppOpsManager.OP_ACTIVATE_PLATFORM_VPN);
+                        restrictedProfileA, AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN);
 
         try {
             vpn.startVpnProfile(TEST_VPN_PKG, mKeyStore);
@@ -954,7 +964,7 @@
     public void testStopVpnProfileRestrictedUser() throws Exception {
         final Vpn vpn =
                 createVpnAndSetupUidChecks(
-                        restrictedProfileA, AppOpsManager.OP_ACTIVATE_PLATFORM_VPN);
+                        restrictedProfileA, AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN);
 
         try {
             vpn.stopVpnProfile(TEST_VPN_PKG);
@@ -970,7 +980,7 @@
         assertTrue(vpn.setPackageAuthorization(TEST_VPN_PKG, VpnManager.TYPE_VPN_SERVICE));
         verify(mAppOps)
                 .setMode(
-                        eq(AppOpsManager.OP_ACTIVATE_VPN),
+                        eq(AppOpsManager.OPSTR_ACTIVATE_VPN),
                         eq(Process.myUid()),
                         eq(TEST_VPN_PKG),
                         eq(AppOpsManager.MODE_ALLOWED));
@@ -983,7 +993,7 @@
         assertTrue(vpn.setPackageAuthorization(TEST_VPN_PKG, VpnManager.TYPE_VPN_PLATFORM));
         verify(mAppOps)
                 .setMode(
-                        eq(AppOpsManager.OP_ACTIVATE_PLATFORM_VPN),
+                        eq(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN),
                         eq(Process.myUid()),
                         eq(TEST_VPN_PKG),
                         eq(AppOpsManager.MODE_ALLOWED));
@@ -996,13 +1006,13 @@
         assertTrue(vpn.setPackageAuthorization(TEST_VPN_PKG, VpnManager.TYPE_VPN_NONE));
         verify(mAppOps)
                 .setMode(
-                        eq(AppOpsManager.OP_ACTIVATE_VPN),
+                        eq(AppOpsManager.OPSTR_ACTIVATE_VPN),
                         eq(Process.myUid()),
                         eq(TEST_VPN_PKG),
                         eq(AppOpsManager.MODE_IGNORED));
         verify(mAppOps)
                 .setMode(
-                        eq(AppOpsManager.OP_ACTIVATE_PLATFORM_VPN),
+                        eq(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN),
                         eq(Process.myUid()),
                         eq(TEST_VPN_PKG),
                         eq(AppOpsManager.MODE_IGNORED));
@@ -1059,7 +1069,7 @@
 
         verify(mKeyStore).get(eq(vpn.getProfileNameForPackage(TEST_VPN_PKG)));
         verify(mAppOps).setMode(
-                eq(AppOpsManager.OP_ACTIVATE_PLATFORM_VPN), eq(uid), eq(TEST_VPN_PKG),
+                eq(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN), eq(uid), eq(TEST_VPN_PKG),
                 eq(AppOpsManager.MODE_ALLOWED));
 
         verify(mSystemServices).settingsSecurePutStringForUser(
diff --git a/tests/net/java/com/android/server/net/NetworkStatsAccessTest.java b/tests/net/java/com/android/server/net/NetworkStatsAccessTest.java
index 858358c..8b730af 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsAccessTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsAccessTest.java
@@ -22,7 +22,6 @@
 import android.Manifest;
 import android.Manifest.permission;
 import android.app.AppOpsManager;
-import android.app.admin.DeviceAdminInfo;
 import android.app.admin.DevicePolicyManagerInternal;
 import android.content.Context;
 import android.content.pm.PackageManager;
@@ -167,13 +166,11 @@
     }
 
     private void setIsDeviceOwner(boolean isOwner) {
-        when(mDpmi.isActiveAdminWithPolicy(TEST_UID, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER))
-                .thenReturn(isOwner);
+        when(mDpmi.isActiveDeviceOwner(TEST_UID)).thenReturn(isOwner);
     }
 
     private void setIsProfileOwner(boolean isOwner) {
-        when(mDpmi.isActiveAdminWithPolicy(TEST_UID, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER))
-                .thenReturn(isOwner);
+        when(mDpmi.isActiveProfileOwner(TEST_UID)).thenReturn(isOwner);
     }
 
     private void setHasAppOpsPermission(int appOpsMode, boolean hasPermission) {
diff --git a/tests/utils/hostutils/src/com/android/internal/util/test/SystemPreparer.java b/tests/utils/hostutils/src/com/android/internal/util/test/SystemPreparer.java
index f30c35a..1733386 100644
--- a/tests/utils/hostutils/src/com/android/internal/util/test/SystemPreparer.java
+++ b/tests/utils/hostutils/src/com/android/internal/util/test/SystemPreparer.java
@@ -186,7 +186,7 @@
     private File copyResourceToTemp(String resourcePath) throws IOException {
         final File tempFile = mHostTempFolder.newFile();
         final ClassLoader classLoader = getClass().getClassLoader();
-        try (InputStream assetIs = classLoader.getResource(resourcePath).openStream();
+        try (InputStream assetIs = classLoader.getResourceAsStream(resourcePath);
              FileOutputStream assetOs = new FileOutputStream(tempFile)) {
             if (assetIs == null) {
                 throw new IllegalStateException("Failed to find resource " + resourcePath);
diff --git a/tests/vcn/Android.bp b/tests/vcn/Android.bp
new file mode 100644
index 0000000..f967bf0
--- /dev/null
+++ b/tests/vcn/Android.bp
@@ -0,0 +1,27 @@
+//########################################################################
+// Build FrameworksVcnTests package
+//########################################################################
+
+android_test {
+    name: "FrameworksVcnTests",
+    srcs: [
+        "java/**/*.java",
+        "java/**/*.kt",
+    ],
+    platform_apis: true,
+    test_suites: ["device-tests"],
+    certificate: "platform",
+    static_libs: [
+        "androidx.test.rules",
+        "frameworks-base-testutils",
+        "framework-protos",
+        "mockito-target-minus-junit4",
+        "platform-test-annotations",
+        "services.core",
+    ],
+    libs: [
+        "android.test.runner",
+        "android.test.base",
+        "android.test.mock",
+    ],
+}
diff --git a/tests/vcn/AndroidManifest.xml b/tests/vcn/AndroidManifest.xml
new file mode 100644
index 0000000..2ad9aac
--- /dev/null
+++ b/tests/vcn/AndroidManifest.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="com.android.frameworks.tests.vcn">
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation
+        android:name="androidx.test.runner.AndroidJUnitRunner"
+        android:targetPackage="com.android.frameworks.tests.vcn"
+        android:label="Frameworks VCN Tests" />
+</manifest>
diff --git a/tests/vcn/AndroidTest.xml b/tests/vcn/AndroidTest.xml
new file mode 100644
index 0000000..dc521fd
--- /dev/null
+++ b/tests/vcn/AndroidTest.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 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.
+-->
+<configuration description="Runs VCN Tests.">
+    <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
+        <option name="test-file-name" value="FrameworksVcnTests.apk" />
+    </target_preparer>
+
+    <option name="test-suite-tag" value="apct" />
+    <option name="test-tag" value="FrameworksVcnTests" />
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="com.android.frameworks.tests.vcn" />
+        <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
+        <option name="hidden-api-checks" value="false"/>
+    </test>
+</configuration>
diff --git a/tests/vcn/TEST_MAPPING b/tests/vcn/TEST_MAPPING
new file mode 100644
index 0000000..54fa411
--- /dev/null
+++ b/tests/vcn/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "presubmit": [
+    {
+      "name": "FrameworksVcnTests"
+    }
+  ]
+}
\ No newline at end of file
diff --git a/tools/stats_log_api_gen/Android.bp b/tools/stats_log_api_gen/Android.bp
index e3b6db0..c0893f7 100644
--- a/tools/stats_log_api_gen/Android.bp
+++ b/tools/stats_log_api_gen/Android.bp
@@ -126,6 +126,9 @@
         host: {
             static_libs: ["libstatssocket"],
         },
+        darwin: {
+            enabled: false,
+        },
     },
 }