diff --git a/Android.bp b/Android.bp
index 36ed865..9e65646 100644
--- a/Android.bp
+++ b/Android.bp
@@ -50,12 +50,8 @@
         "SPDX-license-identifier-Apache-2.0",
         "SPDX-license-identifier-BSD",
         "SPDX-license-identifier-CC-BY",
-        "SPDX-license-identifier-CPL-1.0",
-        "SPDX-license-identifier-GPL",
-        "SPDX-license-identifier-GPL-2.0",
         "SPDX-license-identifier-MIT",
         "SPDX-license-identifier-Unicode-DFS",
-        "SPDX-license-identifier-W3C",
         "legacy_unencumbered",
     ],
     license_text: [
@@ -69,6 +65,7 @@
         // Java/AIDL sources under frameworks/base
         ":framework-annotations",
         ":framework-blobstore-sources",
+        ":framework-bluetooth-sources", // TODO(b/214988855) : Remove once framework-bluetooth jar is ready
         ":framework-connectivity-tiramisu-sources",
         ":framework-core-sources",
         ":framework-drm-sources",
@@ -81,7 +78,7 @@
         ":framework-mca-effect-sources",
         ":framework-mca-filterfw-sources",
         ":framework-mca-filterpacks-sources",
-        ":framework-media-sources",
+        ":framework-media-non-updatable-sources",
         ":framework-mms-sources",
         ":framework-omapi-sources",
         ":framework-opengl-sources",
@@ -141,27 +138,6 @@
 }
 
 java_library {
-    name: "framework-updatable-stubs-module_libs_api",
-    static_libs: [
-        "android.net.ipsec.ike.stubs.module_lib",
-        "framework-appsearch.stubs.module_lib",
-        "framework-connectivity.stubs.module_lib",
-        "framework-graphics.stubs.module_lib",
-        "framework-media.stubs.module_lib",
-        "framework-mediaprovider.stubs.module_lib",
-        "framework-permission.stubs.module_lib",
-        "framework-permission-s.stubs.module_lib",
-        "framework-scheduling.stubs.module_lib",
-        "framework-sdkextensions.stubs.module_lib",
-        "framework-statsd.stubs.module_lib",
-        "framework-tethering.stubs.module_lib",
-        "framework-wifi.stubs.module_lib",
-    ],
-    sdk_version: "module_current",
-    visibility: ["//visibility:private"],
-}
-
-java_library {
     name: "framework-all",
     installable: false,
     static_libs: [
@@ -169,6 +145,7 @@
         "framework-minus-apex",
         "framework-appsearch.impl",
         "framework-connectivity.impl",
+        "framework-connectivity-tiramisu.impl",
         "framework-graphics.impl",
         "framework-mediaprovider.impl",
         "framework-permission.impl",
@@ -419,7 +396,6 @@
     name: "framework-ike-shared-srcs",
     visibility: ["//packages/modules/IPsec"],
     srcs: [
-        "core/java/android/net/annotations/PolicyDirection.java",
         "core/java/com/android/internal/util/HexDump.java",
         "core/java/com/android/internal/util/WakeupMessage.java",
         "services/core/java/com/android/server/vcn/util/PersistableBundleUtils.java",
@@ -527,7 +503,9 @@
     visibility: ["//visibility:private"],
 }
 
-// These defaults are used for both the jar stubs and the doc stubs.
+// Defaults for all stubs that include the non-updatable framework. These defaults do not include
+// module symbols, so will not compile correctly on their own. Users must add module APIs to the
+// classpath (or sources) somehow.
 stubs_defaults {
     name: "android-non-updatable-stubs-defaults",
     srcs: [":android-non-updatable-stub-sources"],
@@ -535,17 +513,14 @@
     system_modules: "none",
     java_version: "1.8",
     arg_files: ["core/res/AndroidManifest.xml"],
-    // TODO(b/147699819): remove below aidl includes.
     aidl: {
         local_include_dirs: [
-            "apex/media/aidl/stable",
             "media/aidl",
             "telephony/java",
         ],
         include_dirs: [
             "frameworks/av/aidl",
             "frameworks/native/libs/permission/aidl",
-            "packages/modules/Connectivity/framework/aidl-export",
         ],
     },
     // These are libs from framework-internal-utils that are required (i.e. being referenced)
@@ -567,6 +542,30 @@
         "android.hardware.usb.gadget-V1.0-java",
         "android.hardware.vibrator-V1.3-java",
         "framework-protos",
+    ],
+    filter_packages: packages_to_document,
+    high_mem: true, // Lots of sources => high memory use, see b/170701554
+    installable: false,
+    annotations_enabled: true,
+    previous_api: ":android.api.public.latest",
+    merge_annotations_dirs: ["metalava-manual"],
+    defaults_visibility: ["//visibility:private"],
+    visibility: ["//frameworks/base/api"],
+}
+
+// Defaults with module APIs in the classpath (mostly from prebuilts).
+// Suitable for compiling android-non-updatable.
+stubs_defaults {
+    name: "module-classpath-stubs-defaults",
+    aidl: {
+        local_include_dirs: [
+            "apex/media/aidl/stable",
+        ],
+        include_dirs: [
+            "packages/modules/Connectivity/framework/aidl-export",
+        ],
+    },
+    libs: [
         "art.module.public.api",
         "sdk_module-lib_current_framework-tethering",
         // There are a few classes from modules used by the core that
@@ -577,14 +576,7 @@
         // NOTE: The below can be removed once the prebuilt stub contains IKE.
         "sdk_system_current_android.net.ipsec.ike",
     ],
-    filter_packages: packages_to_document,
-    high_mem: true, // Lots of sources => high memory use, see b/170701554
-    installable: false,
-    annotations_enabled: true,
-    previous_api: ":android.api.public.latest",
-    merge_annotations_dirs: ["metalava-manual"],
     defaults_visibility: ["//visibility:private"],
-    visibility: ["//frameworks/base/api"],
 }
 
 build = [
diff --git a/ApiDocs.bp b/ApiDocs.bp
index 8af2e02..f7bd34e 100644
--- a/ApiDocs.bp
+++ b/ApiDocs.bp
@@ -57,12 +57,15 @@
 
 stubs_defaults {
     name: "android-non-updatable-doc-stubs-defaults",
-    defaults: ["android-non-updatable-stubs-defaults"],
+    defaults: [
+        "android-non-updatable-stubs-defaults",
+        "module-classpath-stubs-defaults",
+    ],
     srcs: [
         // No longer part of the stubs, but are included in the docs.
-        "test-base/src/**/*.java",
-        "test-mock/src/**/*.java",
-        "test-runner/src/**/*.java",
+        ":android-test-base-sources",
+        ":android-test-mock-sources",
+        ":android-test-runner-sources",
     ],
     libs: framework_docs_only_libs,
     create_doc_stubs: true,
@@ -71,44 +74,21 @@
 
 stubs_defaults {
     name: "framework-doc-stubs-default",
+    defaults: ["android-non-updatable-stubs-defaults"],
     srcs: [
-        ":android-non-updatable-stub-sources",
-
-        // Module sources
-        ":art.module.public.api{.public.stubs.source}",
-        ":conscrypt.module.public.api{.public.stubs.source}",
-        ":i18n.module.public.api{.public.stubs.source}",
-
         // No longer part of the stubs, but are included in the docs.
         ":android-test-base-sources",
         ":android-test-mock-sources",
         ":android-test-runner-sources",
     ],
-    arg_files: [
-        "core/res/AndroidManifest.xml",
-    ],
     libs: framework_docs_only_libs,
     create_doc_stubs: true,
-    annotations_enabled: true,
-    filter_packages: packages_to_document,
     api_levels_annotations_enabled: true,
     api_levels_annotations_dirs: [
         "sdk-dir",
         "api-versions-jars-dir",
     ],
-    previous_api: ":android.api.public.latest",
-    merge_annotations_dirs: [
-        "metalava-manual",
-    ],
     write_sdk_values: true,
-    // TODO(b/169090544): remove below aidl includes.
-    aidl: {
-        local_include_dirs: ["media/aidl"],
-        include_dirs: [
-            "frameworks/av/aidl",
-            "frameworks/native/libs/permission/aidl",
-        ],
-    },
 }
 
 // Defaults module for doc-stubs targets that use module source code as input.
@@ -116,8 +96,13 @@
     name: "framework-doc-stubs-sources-default",
     defaults: ["framework-doc-stubs-default"],
     srcs: [
+        ":art.module.public.api{.public.stubs.source}",
+        ":conscrypt.module.public.api{.public.stubs.source}",
+        ":i18n.module.public.api{.public.stubs.source}",
+
         ":framework-appsearch-sources",
         ":framework-connectivity-sources",
+        ":framework-connectivity-tiramisu-updatable-sources",
         ":framework-graphics-srcs",
         ":framework-mediaprovider-sources",
         ":framework-permission-sources",
@@ -156,22 +141,8 @@
 droidstubs {
     name: "framework-doc-stubs",
     defaults: ["framework-doc-stubs-default"],
+    srcs: [":all-modules-public-stubs-source"],
     args: metalava_framework_docs_args,
-    srcs: [
-        ":android.net.ipsec.ike{.public.stubs.source}",
-        ":framework-appsearch{.public.stubs.source}",
-        ":framework-connectivity{.public.stubs.source}",
-        ":framework-graphics{.public.stubs.source}",
-        ":framework-media{.public.stubs.source}",
-        ":framework-mediaprovider{.public.stubs.source}",
-        ":framework-permission{.public.stubs.source}",
-        ":framework-permission-s{.public.stubs.source}",
-        ":framework-scheduling{.public.stubs.source}",
-        ":framework-sdkextensions{.public.stubs.source}",
-        ":framework-statsd{.public.stubs.source}",
-        ":framework-tethering{.public.stubs.source}",
-        ":framework-wifi{.public.stubs.source}",
-    ],
     aidl: {
         local_include_dirs: [
             "apex/media/aidl/stable",
@@ -182,42 +153,6 @@
     },
 }
 
-// This produces the same annotations.zip as framework-doc-stubs, but by using
-// outputs from individual modules instead of all the source code.
-genrule {
-    name: "sdk-annotations.zip",
-    srcs: [
-        ":android-non-updatable-doc-stubs{.annotations.zip}",
-
-        // Conscrypt and i18n currently do not enable annotations
-        // ":conscrypt.module.public.api{.public.annotations.zip}",
-        // ":i18n.module.public.api{.public.annotations.zip}",
-
-        // Modules that enable annotations below
-        ":android.net.ipsec.ike{.public.annotations.zip}",
-        ":art.module.public.api{.public.annotations.zip}",
-        ":framework-appsearch{.public.annotations.zip}",
-        ":framework-connectivity{.public.annotations.zip}",
-        ":framework-graphics{.public.annotations.zip}",
-        ":framework-media{.public.annotations.zip}",
-        ":framework-mediaprovider{.public.annotations.zip}",
-        ":framework-permission{.public.annotations.zip}",
-        ":framework-permission-s{.public.annotations.zip}",
-        ":framework-scheduling{.public.annotations.zip}",
-        ":framework-sdkextensions{.public.annotations.zip}",
-        ":framework-statsd{.public.annotations.zip}",
-        ":framework-tethering{.public.annotations.zip}",
-        ":framework-wifi{.public.annotations.zip}",
-    ],
-    out: ["annotations.zip"],
-    tools: [
-        "merge_annotation_zips",
-        "soong_zip",
-    ],
-    cmd: "$(location merge_annotation_zips) $(genDir)/out $(in) && " +
-        "$(location soong_zip) -o $(out) -C $(genDir)/out -D $(genDir)/out",
-}
-
 /////////////////////////////////////////////////////////////////////
 // API docs are created from the generated stub source files
 // using droiddoc
diff --git a/METADATA b/METADATA
index 95577d8..5c3f89c 100644
--- a/METADATA
+++ b/METADATA
@@ -1,4 +1,3 @@
 third_party {
-  # would be NOTICE save for libs/usb/tests/accessorytest/f_accessory.h
-  license_type: RESTRICTED
+  license_type: RECIPROCAL
 }
diff --git a/StubLibraries.bp b/StubLibraries.bp
index 31fecd1..9e8b707 100644
--- a/StubLibraries.bp
+++ b/StubLibraries.bp
@@ -24,23 +24,15 @@
 // with the latest frozen API signature.
 
 /////////////////////////////////////////////////////////////////////
-// Common metalava configs
-/////////////////////////////////////////////////////////////////////
-
-stubs_defaults {
-    name: "metalava-non-updatable-api-stubs-default",
-    defaults: ["android-non-updatable-stubs-defaults"],
-    api_levels_annotations_enabled: false,
-    defaults_visibility: ["//visibility:private"],
-}
-
-/////////////////////////////////////////////////////////////////////
 // These modules provide source files for the stub libraries
 /////////////////////////////////////////////////////////////////////
 
 droidstubs {
     name: "api-stubs-docs-non-updatable",
-    defaults: ["metalava-non-updatable-api-stubs-default"],
+    defaults: [
+        "android-non-updatable-stubs-defaults",
+        "module-classpath-stubs-defaults",
+    ],
     args: metalava_framework_docs_args,
     check_api: {
         current: {
@@ -89,7 +81,10 @@
 
 droidstubs {
     name: "system-api-stubs-docs-non-updatable",
-    defaults: ["metalava-non-updatable-api-stubs-default"],
+    defaults: [
+        "android-non-updatable-stubs-defaults",
+        "module-classpath-stubs-defaults",
+    ],
     args: metalava_framework_docs_args + priv_apps,
     check_api: {
         current: {
@@ -125,7 +120,10 @@
 
 droidstubs {
     name: "test-api-stubs-docs-non-updatable",
-    defaults: ["metalava-non-updatable-api-stubs-default"],
+    defaults: [
+        "android-non-updatable-stubs-defaults",
+        "module-classpath-stubs-defaults",
+    ],
     args: metalava_framework_docs_args + test + priv_apps_in_stubs,
     check_api: {
         current: {
@@ -167,7 +165,10 @@
 
 droidstubs {
     name: "module-lib-api-stubs-docs-non-updatable",
-    defaults: ["metalava-non-updatable-api-stubs-default"],
+    defaults: [
+        "android-non-updatable-stubs-defaults",
+        "module-classpath-stubs-defaults",
+    ],
     args: metalava_framework_docs_args + priv_apps_in_stubs + module_libs,
     check_api: {
         current: {
@@ -177,6 +178,7 @@
         last_released: {
             api_file: ":android-non-updatable.api.module-lib.latest",
             removed_api_file: ":android-non-updatable-removed.api.module-lib.latest",
+            baseline_file: ":android-non-updatable-incompatibilities.api.module-lib.latest",
         },
         api_lint: {
             enabled: true,
@@ -211,6 +213,7 @@
     "conscrypt.module.public.api.stubs",
     "framework-appsearch.stubs",
     "framework-connectivity.stubs",
+    "framework-connectivity-tiramisu.stubs",
     "framework-graphics.stubs",
     "framework-media.stubs",
     "framework-mediaprovider.stubs",
@@ -230,6 +233,7 @@
     "conscrypt.module.public.api.stubs", // Only has public stubs
     "framework-appsearch.stubs.system",
     "framework-connectivity.stubs.system",
+    "framework-connectivity-tiramisu.stubs.system",
     "framework-graphics.stubs.system",
     "framework-media.stubs.system",
     "framework-mediaprovider.stubs.system",
diff --git a/apex/jobscheduler/framework/java/android/os/PowerExemptionManager.java b/apex/jobscheduler/framework/java/android/os/PowerExemptionManager.java
index a1a46af..161a317 100644
--- a/apex/jobscheduler/framework/java/android/os/PowerExemptionManager.java
+++ b/apex/jobscheduler/framework/java/android/os/PowerExemptionManager.java
@@ -235,7 +235,6 @@
     public static final int REASON_LOCKED_BOOT_COMPLETED = 202;
     /**
      * All Bluetooth broadcasts.
-     * @hide
      */
     public static final int REASON_BLUETOOTH_BROADCAST = 203;
     /**
diff --git a/api/Android.bp b/api/Android.bp
index f89c557..0c3a3e6 100644
--- a/api/Android.bp
+++ b/api/Android.bp
@@ -32,6 +32,7 @@
         "soong",
         "soong-android",
         "soong-genrule",
+        "soong-java",
     ],
     srcs: ["api.go"],
     pluginFor: ["soong_build"],
@@ -102,43 +103,31 @@
     visibility: ["//visibility:public"],
 }
 
-genrule {
-    name: "frameworks-base-api-current.txt",
-    srcs: [
-        ":android.net.ipsec.ike{.public.api.txt}",
-        ":art.module.public.api{.public.api.txt}",
-        ":conscrypt.module.public.api{.public.api.txt}",
-        ":framework-appsearch{.public.api.txt}",
-        ":framework-connectivity{.public.api.txt}",
-        ":framework-graphics{.public.api.txt}",
-        ":framework-media{.public.api.txt}",
-        ":framework-mediaprovider{.public.api.txt}",
-        ":framework-permission{.public.api.txt}",
-        ":framework-permission-s{.public.api.txt}",
-        ":framework-scheduling{.public.api.txt}",
-        ":framework-sdkextensions{.public.api.txt}",
-        ":framework-statsd{.public.api.txt}",
-        ":framework-tethering{.public.api.txt}",
-        ":framework-wifi{.public.api.txt}",
-        ":i18n.module.public.api{.public.api.txt}",
-        ":non-updatable-current.txt",
+combined_apis {
+    name: "frameworks-base-api",
+    bootclasspath: [
+        "android.net.ipsec.ike",
+        "art.module.public.api",
+        "conscrypt.module.public.api",
+        "framework-appsearch",
+        "framework-connectivity",
+        "framework-connectivity-tiramisu",
+        "framework-graphics",
+        "framework-media",
+        "framework-mediaprovider",
+        "framework-permission",
+        "framework-permission-s",
+        "framework-scheduling",
+        "framework-sdkextensions",
+        "framework-statsd",
+        "framework-tethering",
+        "framework-wifi",
+        "i18n.module.public.api",
     ],
-    out: ["current.txt"],
-    tools: ["metalava"],
-    cmd: metalava_cmd + "$(in) --api $(out)",
-    dists: [
-        {
-            targets: ["droidcore"],
-            dir: "api",
-            dest: "current.txt",
-        },
-        {
-            targets: ["sdk"],
-            dir: "apistubs/android/public/api",
-            dest: "android.txt",
-        },
+    system_server_classpath: [
+        "service-media-s",
+        "service-permission",
     ],
-    visibility: ["//visibility:public"],
 }
 
 genrule {
@@ -158,108 +147,6 @@
 }
 
 genrule {
-    name: "frameworks-base-api-current.srcjar",
-    srcs: [
-        ":android.net.ipsec.ike{.public.stubs.source}",
-        ":api-stubs-docs-non-updatable",
-        ":art.module.public.api{.public.stubs.source}",
-        ":conscrypt.module.public.api{.public.stubs.source}",
-        ":framework-appsearch{.public.stubs.source}",
-        ":framework-connectivity{.public.stubs.source}",
-        ":framework-graphics{.public.stubs.source}",
-        ":framework-media{.public.stubs.source}",
-        ":framework-mediaprovider{.public.stubs.source}",
-        ":framework-permission{.public.stubs.source}",
-        ":framework-permission-s{.public.stubs.source}",
-        ":framework-scheduling{.public.stubs.source}",
-        ":framework-sdkextensions{.public.stubs.source}",
-        ":framework-statsd{.public.stubs.source}",
-        ":framework-tethering{.public.stubs.source}",
-        ":framework-wifi{.public.stubs.source}",
-        ":i18n.module.public.api{.public.stubs.source}",
-    ],
-    out: ["current.srcjar"],
-    tools: ["merge_zips"],
-    cmd: "$(location merge_zips) $(out) $(in)",
-    visibility: ["//visibility:private"], // Used by make module in //development, mind.
-}
-
-genrule {
-    name: "frameworks-base-api-removed.txt",
-    srcs: [
-        ":android.net.ipsec.ike{.public.removed-api.txt}",
-        ":art.module.public.api{.public.removed-api.txt}",
-        ":conscrypt.module.public.api{.public.removed-api.txt}",
-        ":framework-appsearch{.public.removed-api.txt}",
-        ":framework-connectivity{.public.removed-api.txt}",
-        ":framework-graphics{.public.removed-api.txt}",
-        ":framework-media{.public.removed-api.txt}",
-        ":framework-mediaprovider{.public.removed-api.txt}",
-        ":framework-permission{.public.removed-api.txt}",
-        ":framework-permission-s{.public.removed-api.txt}",
-        ":framework-scheduling{.public.removed-api.txt}",
-        ":framework-sdkextensions{.public.removed-api.txt}",
-        ":framework-statsd{.public.removed-api.txt}",
-        ":framework-tethering{.public.removed-api.txt}",
-        ":framework-wifi{.public.removed-api.txt}",
-        ":i18n.module.public.api{.public.removed-api.txt}",
-        ":non-updatable-removed.txt",
-    ],
-    out: ["removed.txt"],
-    tools: ["metalava"],
-    cmd: metalava_cmd + "$(in) --api $(out)",
-    dists: [
-        {
-            targets: ["droidcore"],
-            dir: "api",
-            dest: "removed.txt",
-        },
-        {
-            targets: ["sdk"],
-            dir: "apistubs/android/public/api",
-            dest: "removed.txt",
-        },
-    ],
-}
-
-genrule {
-    name: "frameworks-base-api-system-current.txt",
-    srcs: [
-        ":art.module.public.api{.system.api.txt}",
-        ":android.net.ipsec.ike{.system.api.txt}",
-        ":framework-appsearch{.system.api.txt}",
-        ":framework-connectivity{.system.api.txt}",
-        ":framework-graphics{.system.api.txt}",
-        ":framework-media{.system.api.txt}",
-        ":framework-mediaprovider{.system.api.txt}",
-        ":framework-permission{.system.api.txt}",
-        ":framework-permission-s{.system.api.txt}",
-        ":framework-scheduling{.system.api.txt}",
-        ":framework-sdkextensions{.system.api.txt}",
-        ":framework-statsd{.system.api.txt}",
-        ":framework-tethering{.system.api.txt}",
-        ":framework-wifi{.system.api.txt}",
-        ":non-updatable-system-current.txt",
-    ],
-    out: ["system-current.txt"],
-    tools: ["metalava"],
-    cmd: metalava_cmd + "$(in) --api $(out)",
-    dists: [
-        {
-            targets: ["droidcore"],
-            dir: "api",
-            dest: "system-current.txt",
-        },
-        {
-            targets: ["sdk"],
-            dir: "apistubs/android/system/api",
-            dest: "android.txt",
-        },
-    ],
-    visibility: ["//visibility:public"],
-}
-
-genrule {
     name: "frameworks-base-api-system-current-compat",
     srcs: [
         ":android.api.system.latest",
@@ -278,79 +165,6 @@
 }
 
 genrule {
-    name: "frameworks-base-api-system-removed.txt",
-    srcs: [
-        ":art.module.public.api{.system.removed-api.txt}",
-        ":android.net.ipsec.ike{.system.removed-api.txt}",
-        ":framework-appsearch{.system.removed-api.txt}",
-        ":framework-connectivity{.system.removed-api.txt}",
-        ":framework-graphics{.system.removed-api.txt}",
-        ":framework-media{.system.removed-api.txt}",
-        ":framework-mediaprovider{.system.removed-api.txt}",
-        ":framework-permission{.system.removed-api.txt}",
-        ":framework-permission-s{.system.removed-api.txt}",
-        ":framework-scheduling{.system.removed-api.txt}",
-        ":framework-sdkextensions{.system.removed-api.txt}",
-        ":framework-statsd{.system.removed-api.txt}",
-        ":framework-tethering{.system.removed-api.txt}",
-        ":framework-wifi{.system.removed-api.txt}",
-        ":non-updatable-system-removed.txt",
-    ],
-    out: ["system-removed.txt"],
-    tools: ["metalava"],
-    cmd: metalava_cmd + "$(in) --api $(out)",
-    dists: [
-        {
-            targets: ["droidcore"],
-            dir: "api",
-            dest: "system-removed.txt",
-        },
-        {
-            targets: ["sdk"],
-            dir: "apistubs/android/system/api",
-            dest: "removed.txt",
-        },
-    ],
-    visibility: ["//visibility:public"],
-}
-
-genrule {
-    name: "frameworks-base-api-module-lib-current.txt",
-    srcs: [
-        ":art.module.public.api{.module-lib.api.txt}",
-        ":android.net.ipsec.ike{.module-lib.api.txt}",
-        ":framework-appsearch{.module-lib.api.txt}",
-        ":framework-connectivity{.module-lib.api.txt}",
-        ":framework-graphics{.module-lib.api.txt}",
-        ":framework-media{.module-lib.api.txt}",
-        ":framework-mediaprovider{.module-lib.api.txt}",
-        ":framework-permission{.module-lib.api.txt}",
-        ":framework-permission-s{.module-lib.api.txt}",
-        ":framework-scheduling{.module-lib.api.txt}",
-        ":framework-sdkextensions{.module-lib.api.txt}",
-        ":framework-statsd{.module-lib.api.txt}",
-        ":framework-tethering{.module-lib.api.txt}",
-        ":framework-wifi{.module-lib.api.txt}",
-        ":non-updatable-module-lib-current.txt",
-    ],
-    out: ["module-lib-current.txt"],
-    tools: ["metalava"],
-    cmd: metalava_cmd + "$(in) --api $(out)",
-    dists: [
-        {
-            targets: ["droidcore"],
-            dir: "api",
-            dest: "module-lib-current.txt",
-        },
-        {
-            targets: ["sdk"],
-            dir: "apistubs/android/module-lib/api",
-            dest: "android.txt",
-        },
-    ],
-}
-
-genrule {
     name: "frameworks-base-api-module-lib-current-compat",
     srcs: [
         ":android.api.module-lib.latest",
@@ -372,42 +186,6 @@
 }
 
 genrule {
-    name: "frameworks-base-api-module-lib-removed.txt",
-    srcs: [
-        ":art.module.public.api{.module-lib.removed-api.txt}",
-        ":android.net.ipsec.ike{.module-lib.removed-api.txt}",
-        ":framework-appsearch{.module-lib.removed-api.txt}",
-        ":framework-connectivity{.module-lib.removed-api.txt}",
-        ":framework-graphics{.module-lib.removed-api.txt}",
-        ":framework-media{.module-lib.removed-api.txt}",
-        ":framework-mediaprovider{.module-lib.removed-api.txt}",
-        ":framework-permission{.module-lib.removed-api.txt}",
-        ":framework-permission-s{.module-lib.removed-api.txt}",
-        ":framework-scheduling{.module-lib.removed-api.txt}",
-        ":framework-sdkextensions{.module-lib.removed-api.txt}",
-        ":framework-statsd{.module-lib.removed-api.txt}",
-        ":framework-tethering{.module-lib.removed-api.txt}",
-        ":framework-wifi{.module-lib.removed-api.txt}",
-        ":non-updatable-module-lib-removed.txt",
-    ],
-    out: ["module-lib-removed.txt"],
-    tools: ["metalava"],
-    cmd: metalava_cmd + "$(in) --api $(out)",
-    dists: [
-        {
-            targets: ["droidcore"],
-            dir: "api",
-            dest: "module-lib-removed.txt",
-        },
-        {
-            targets: ["sdk"],
-            dir: "apistubs/android/module-lib/api",
-            dest: "removed.txt",
-        },
-    ],
-}
-
-genrule {
     name: "combined-removed-dex",
     visibility: [
         "//frameworks/base/boot",
@@ -423,86 +201,3 @@
     out: ["combined-removed-dex.txt"],
     cmd: "$(location gen_combined_removed_dex.sh) $(location metalava) $(genDir) $(in) > $(out)",
 }
-
-genrule {
-    name: "frameworks-base-api-system-server-current.txt",
-    srcs: [
-        ":service-media-s{.system-server.api.txt}",
-        ":service-permission{.system-server.api.txt}",
-        ":non-updatable-system-server-current.txt",
-    ],
-    out: ["system-server-current.txt"],
-    tools: ["metalava"],
-    cmd: metalava_cmd + "$(in) --api $(out)",
-    dists: [
-        {
-            targets: ["droidcore"],
-            dir: "api",
-            dest: "system-server-current.txt",
-        },
-        {
-            targets: ["sdk"],
-            dir: "apistubs/android/system-server/api",
-            dest: "android.txt",
-        },
-    ],
-}
-
-genrule {
-    name: "frameworks-base-api-system-server-removed.txt",
-    srcs: [
-        ":service-media-s{.system-server.removed-api.txt}",
-        ":service-permission{.system-server.removed-api.txt}",
-        ":non-updatable-system-server-removed.txt",
-    ],
-    out: ["system-server-removed.txt"],
-    tools: ["metalava"],
-    cmd: metalava_cmd + "$(in) --api $(out)",
-    dists: [
-        {
-            targets: ["droidcore"],
-            dir: "api",
-            dest: "system-server-removed.txt",
-        },
-        {
-            targets: ["sdk"],
-            dir: "apistubs/android/system-server/api",
-            dest: "removed.txt",
-        },
-    ],
-}
-
-// This rule will filter classes present in the jar files of mainline modules
-// from the lint database in api-versions.xml.
-// This is done to reduce the number of false positive NewApi findings in
-// java libraries that compile against the module SDK
-genrule {
-    name: "api-versions-xml-public-filtered",
-    srcs: [
-        // Note: order matters: first parameter is the full api-versions.xml
-        // after that the stubs files in any order
-        // stubs files are all modules that export API surfaces EXCEPT ART
-        ":framework-doc-stubs{.api_versions.xml}",
-        ":android.net.ipsec.ike.stubs{.jar}",
-        ":conscrypt.module.public.api.stubs{.jar}",
-        ":framework-appsearch.stubs{.jar}",
-        ":framework-connectivity.stubs{.jar}",
-        ":framework-graphics.stubs{.jar}",
-        ":framework-media.stubs{.jar}",
-        ":framework-mediaprovider.stubs{.jar}",
-        ":framework-permission.stubs{.jar}",
-        ":framework-permission-s.stubs{.jar}",
-        ":framework-scheduling.stubs{.jar}",
-        ":framework-sdkextensions.stubs{.jar}",
-        ":framework-statsd.stubs{.jar}",
-        ":framework-tethering.stubs{.jar}",
-        ":framework-wifi.stubs{.jar}",
-        ":i18n.module.public.api.stubs{.jar}",
-    ],
-    out: ["api-versions-public-filtered.xml"],
-    tools: ["api_versions_trimmer"],
-    cmd: "$(location api_versions_trimmer) $(out) $(in)",
-    dist: {
-        targets: ["sdk"],
-    },
-}
diff --git a/api/api.go b/api/api.go
index 976b140..4b6ebc1 100644
--- a/api/api.go
+++ b/api/api.go
@@ -15,12 +15,19 @@
 package api
 
 import (
+	"sort"
+
 	"github.com/google/blueprint/proptools"
 
 	"android/soong/android"
 	"android/soong/genrule"
+	"android/soong/java"
 )
 
+const art = "art.module.public.api"
+const conscrypt = "conscrypt.module.public.api"
+const i18n = "i18n.module.public.api"
+
 // The intention behind this soong plugin is to generate a number of "merged"
 // API-related modules that would otherwise require a large amount of very
 // similar Android.bp boilerplate to define. For example, the merged current.txt
@@ -30,22 +37,12 @@
 
 // The properties of the combined_apis module type.
 type CombinedApisProperties struct {
-	// Module libraries that have public APIs
-	Public []string
-	// Module libraries that have system APIs
-	System []string
-	// Module libraries that have module_library APIs
-	Module_lib []string
-	// Module libraries that have system_server APIs
-	System_server []string
-	// ART module library. The only API library not removed from the filtered api database, because
-	// 1) ART apis are available by default to all modules, while other module-to-module deps are
-	//    explicit and probably receive more scrutiny anyway
-	// 2) The number of ART/libcore APIs is large, so not linting them would create a large gap
-	// 3) It's a compromise. Ideally we wouldn't be filtering out any module APIs, and have
-	//    per-module lint databases that excludes just that module's APIs. Alas, that's more
-	//    difficult to achieve.
-	Art_module string
+	// Module libraries in the bootclasspath
+	Bootclasspath []string
+	// Module libraries on the bootclasspath if include_nonpublic_framework_api is true.
+	Conditional_bootclasspath []string
+	// Module libraries in system server
+	System_server_classpath []string
 }
 
 type CombinedApis struct {
@@ -77,6 +74,19 @@
 	Visibility []string
 }
 
+type libraryProps struct {
+	Name        *string
+	Sdk_version *string
+	Static_libs []string
+	Visibility  []string
+}
+
+type fgProps struct {
+	Name       *string
+	Srcs       []string
+	Visibility []string
+}
+
 // Struct to pass parameters for the various merged [current|removed].txt file modules we create.
 type MergedTxtDefinition struct {
 	// "current.txt" or "removed.txt"
@@ -105,9 +115,9 @@
 	props := genruleProps{}
 	props.Name = proptools.StringPtr(ctx.ModuleName() + "-" + filename)
 	props.Tools = []string{"metalava"}
-	props.Out = []string{txt.TxtFilename}
+	props.Out = []string{filename}
 	props.Cmd = proptools.StringPtr(metalavaCmd + "$(in) --api $(out)")
-	props.Srcs = createSrcs(txt.BaseTxt, txt.Modules, txt.ModuleTag)
+	props.Srcs = append([]string{txt.BaseTxt}, createSrcs(txt.Modules, txt.ModuleTag)...)
 	props.Dists = []android.Dist{
 		{
 			Targets: []string{"droidcore"},
@@ -130,12 +140,36 @@
 	props.Tools = []string{"merge_zips"}
 	props.Out = []string{"current.srcjar"}
 	props.Cmd = proptools.StringPtr("$(location merge_zips) $(out) $(in)")
-	props.Srcs = createSrcs(":api-stubs-docs-non-updatable", modules, "{.public.stubs.source}")
+	props.Srcs = append([]string{":api-stubs-docs-non-updatable"}, createSrcs(modules, "{.public.stubs.source}")...)
 	props.Visibility = []string{"//visibility:private"} // Used by make module in //development, mind
 	ctx.CreateModule(genrule.GenRuleFactory, &props)
 }
 
+// This produces the same annotations.zip as framework-doc-stubs, but by using
+// outputs from individual modules instead of all the source code.
+func createMergedAnnotations(ctx android.LoadHookContext, modules []string) {
+	// Conscrypt and i18n currently do not enable annotations
+	modules = removeAll(modules, []string{conscrypt, i18n})
+	props := genruleProps{}
+	props.Name = proptools.StringPtr("sdk-annotations.zip")
+	props.Tools = []string{"merge_annotation_zips", "soong_zip"}
+	props.Out = []string{"annotations.zip"}
+	props.Cmd = proptools.StringPtr("$(location merge_annotation_zips) $(genDir)/out $(in) && " +
+		"$(location soong_zip) -o $(out) -C $(genDir)/out -D $(genDir)/out")
+	props.Srcs = append([]string{":android-non-updatable-doc-stubs{.annotations.zip}"}, createSrcs(modules, "{.public.annotations.zip}")...)
+	ctx.CreateModule(genrule.GenRuleFactory, &props)
+}
+
 func createFilteredApiVersions(ctx android.LoadHookContext, modules []string) {
+	// For the filtered api versions, we prune all APIs except art module's APIs. because
+	// 1) ART apis are available by default to all modules, while other module-to-module deps are
+	//    explicit and probably receive more scrutiny anyway
+	// 2) The number of ART/libcore APIs is large, so not linting them would create a large gap
+	// 3) It's a compromise. Ideally we wouldn't be filtering out any module APIs, and have
+	//    per-module lint databases that excludes just that module's APIs. Alas, that's more
+	//    difficult to achieve.
+	modules = remove(modules, art)
+
 	props := genruleProps{}
 	props.Name = proptools.StringPtr("api-versions-xml-public-filtered")
 	props.Tools = []string{"api_versions_trimmer"}
@@ -144,59 +178,62 @@
 	// Note: order matters: first parameter is the full api-versions.xml
 	// after that the stubs files in any order
 	// stubs files are all modules that export API surfaces EXCEPT ART
-	props.Srcs = createSrcs(":framework-doc-stubs{.api_versions.xml}", modules, ".stubs{.jar}")
+	props.Srcs = append([]string{":framework-doc-stubs{.api_versions.xml}"}, createSrcs(modules, ".stubs{.jar}")...)
 	props.Dists = []android.Dist{{Targets: []string{"sdk"}}}
 	ctx.CreateModule(genrule.GenRuleFactory, &props)
 }
 
-func createSrcs(base string, modules []string, tag string) []string {
-	a := make([]string, 0, len(modules)+1)
-	a = append(a, base)
-	for _, module := range modules {
-		a = append(a, ":"+module+tag)
-	}
-	return a
+func createMergedModuleLibStubs(ctx android.LoadHookContext, modules []string) {
+	// The user of this module compiles against the "core" SDK, so remove core libraries to avoid dupes.
+	modules = removeAll(modules, []string{art, conscrypt, i18n})
+	props := libraryProps{}
+	props.Name = proptools.StringPtr("framework-updatable-stubs-module_libs_api")
+	props.Static_libs = transformArray(modules, "", ".stubs.module_lib")
+	props.Sdk_version = proptools.StringPtr("module_current")
+	props.Visibility = []string{"//frameworks/base"}
+	ctx.CreateModule(java.LibraryFactory, &props)
 }
 
-func remove(s []string, v string) []string {
-	s2 := make([]string, 0, len(s))
-	for _, sv := range s {
-		if sv != v {
-			s2 = append(s2, sv)
-		}
-	}
-	return s2
+func createPublicStubsSourceFilegroup(ctx android.LoadHookContext, modules []string) {
+	props := fgProps{}
+	props.Name = proptools.StringPtr("all-modules-public-stubs-source")
+	props.Srcs = createSrcs(modules, "{.public.stubs.source}")
+	props.Visibility = []string{"//frameworks/base"}
+	ctx.CreateModule(android.FileGroupFactory, &props)
 }
 
-func createMergedTxts(ctx android.LoadHookContext, props CombinedApisProperties) {
+func createMergedTxts(ctx android.LoadHookContext, bootclasspath, system_server_classpath []string) {
 	var textFiles []MergedTxtDefinition
+	// Two module libraries currently do not support @SystemApi so only have the public scope.
+	bcpWithSystemApi := removeAll(bootclasspath, []string{conscrypt, i18n})
+
 	tagSuffix := []string{".api.txt}", ".removed-api.txt}"}
 	for i, f := range []string{"current.txt", "removed.txt"} {
 		textFiles = append(textFiles, MergedTxtDefinition{
 			TxtFilename: f,
 			BaseTxt:     ":non-updatable-" + f,
-			Modules:     props.Public,
+			Modules:     bootclasspath,
 			ModuleTag:   "{.public" + tagSuffix[i],
 			Scope:       "public",
 		})
 		textFiles = append(textFiles, MergedTxtDefinition{
 			TxtFilename: f,
 			BaseTxt:     ":non-updatable-system-" + f,
-			Modules:     props.System,
+			Modules:     bcpWithSystemApi,
 			ModuleTag:   "{.system" + tagSuffix[i],
 			Scope:       "system",
 		})
 		textFiles = append(textFiles, MergedTxtDefinition{
 			TxtFilename: f,
 			BaseTxt:     ":non-updatable-module-lib-" + f,
-			Modules:     props.Module_lib,
+			Modules:     bcpWithSystemApi,
 			ModuleTag:   "{.module-lib" + tagSuffix[i],
 			Scope:       "module-lib",
 		})
 		textFiles = append(textFiles, MergedTxtDefinition{
 			TxtFilename: f,
 			BaseTxt:     ":non-updatable-system-server-" + f,
-			Modules:     props.System_server,
+			Modules:     system_server_classpath,
 			ModuleTag:   "{.system-server" + tagSuffix[i],
 			Scope:       "system-server",
 		})
@@ -207,12 +244,22 @@
 }
 
 func (a *CombinedApis) createInternalModules(ctx android.LoadHookContext) {
-	createMergedTxts(ctx, a.properties)
+	bootclasspath := a.properties.Bootclasspath
+	if ctx.Config().VendorConfig("ANDROID").Bool("include_nonpublic_framework_api") {
+		bootclasspath = append(bootclasspath, a.properties.Conditional_bootclasspath...)
+		sort.Strings(bootclasspath)
+	}
+	createMergedTxts(ctx, bootclasspath, a.properties.System_server_classpath)
 
-	createMergedStubsSrcjar(ctx, a.properties.Public)
+	createMergedStubsSrcjar(ctx, bootclasspath)
 
-	// For the filtered api versions, we prune all APIs except art module's APIs.
-	createFilteredApiVersions(ctx, remove(a.properties.Public, a.properties.Art_module))
+	createMergedModuleLibStubs(ctx, bootclasspath)
+
+	createMergedAnnotations(ctx, bootclasspath)
+
+	createFilteredApiVersions(ctx, bootclasspath)
+
+	createPublicStubsSourceFilegroup(ctx, bootclasspath)
 }
 
 func combinedApisModuleFactory() android.Module {
@@ -222,3 +269,36 @@
 	android.AddLoadHook(module, func(ctx android.LoadHookContext) { module.createInternalModules(ctx) })
 	return module
 }
+
+// Various utility methods below.
+
+// Creates an array of ":<m><tag>" for each m in <modules>.
+func createSrcs(modules []string, tag string) []string {
+	return transformArray(modules, ":", tag)
+}
+
+// Creates an array of "<prefix><m><suffix>", for each m in <modules>.
+func transformArray(modules []string, prefix, suffix string) []string {
+	a := make([]string, 0, len(modules))
+	for _, module := range modules {
+		a = append(a, prefix+module+suffix)
+	}
+	return a
+}
+
+func removeAll(s []string, vs []string) []string {
+	for _, v := range vs {
+		s = remove(s, v)
+	}
+	return s
+}
+
+func remove(s []string, v string) []string {
+	s2 := make([]string, 0, len(s))
+	for _, sv := range s {
+		if sv != v {
+			s2 = append(s2, sv)
+		}
+	}
+	return s2
+}
diff --git a/boot/hiddenapi/hiddenapi-max-target-o.txt b/boot/hiddenapi/hiddenapi-max-target-o.txt
index 0ec918b..9153426 100644
--- a/boot/hiddenapi/hiddenapi-max-target-o.txt
+++ b/boot/hiddenapi/hiddenapi-max-target-o.txt
@@ -36441,93 +36441,6 @@
 Landroid/net/MobileLinkQualityInfo;->mLteSignalStrength:I
 Landroid/net/MobileLinkQualityInfo;->mMobileNetworkType:I
 Landroid/net/MobileLinkQualityInfo;->mRssi:I
-Landroid/net/nsd/DnsSdTxtRecord;-><init>()V
-Landroid/net/nsd/DnsSdTxtRecord;-><init>(Landroid/net/nsd/DnsSdTxtRecord;)V
-Landroid/net/nsd/DnsSdTxtRecord;-><init>([B)V
-Landroid/net/nsd/DnsSdTxtRecord;->contains(Ljava/lang/String;)Z
-Landroid/net/nsd/DnsSdTxtRecord;->CREATOR:Landroid/os/Parcelable$Creator;
-Landroid/net/nsd/DnsSdTxtRecord;->get(Ljava/lang/String;)Ljava/lang/String;
-Landroid/net/nsd/DnsSdTxtRecord;->getKey(I)Ljava/lang/String;
-Landroid/net/nsd/DnsSdTxtRecord;->getRawData()[B
-Landroid/net/nsd/DnsSdTxtRecord;->getValue(I)[B
-Landroid/net/nsd/DnsSdTxtRecord;->getValue(Ljava/lang/String;)[B
-Landroid/net/nsd/DnsSdTxtRecord;->getValueAsString(I)Ljava/lang/String;
-Landroid/net/nsd/DnsSdTxtRecord;->insert([B[BI)V
-Landroid/net/nsd/DnsSdTxtRecord;->keyCount()I
-Landroid/net/nsd/DnsSdTxtRecord;->mData:[B
-Landroid/net/nsd/DnsSdTxtRecord;->mSeperator:B
-Landroid/net/nsd/DnsSdTxtRecord;->remove(Ljava/lang/String;)I
-Landroid/net/nsd/DnsSdTxtRecord;->set(Ljava/lang/String;Ljava/lang/String;)V
-Landroid/net/nsd/DnsSdTxtRecord;->size()I
-Landroid/net/nsd/INsdManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Landroid/net/nsd/INsdManager$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String;
-Landroid/net/nsd/INsdManager$Stub$Proxy;->getMessenger()Landroid/os/Messenger;
-Landroid/net/nsd/INsdManager$Stub$Proxy;->mRemote:Landroid/os/IBinder;
-Landroid/net/nsd/INsdManager$Stub$Proxy;->setEnabled(Z)V
-Landroid/net/nsd/INsdManager$Stub;-><init>()V
-Landroid/net/nsd/INsdManager$Stub;->DESCRIPTOR:Ljava/lang/String;
-Landroid/net/nsd/INsdManager$Stub;->TRANSACTION_getMessenger:I
-Landroid/net/nsd/INsdManager$Stub;->TRANSACTION_setEnabled:I
-Landroid/net/nsd/INsdManager;->setEnabled(Z)V
-Landroid/net/nsd/NsdManager;-><init>(Landroid/content/Context;Landroid/net/nsd/INsdManager;)V
-Landroid/net/nsd/NsdManager;->BASE:I
-Landroid/net/nsd/NsdManager;->checkListener(Ljava/lang/Object;)V
-Landroid/net/nsd/NsdManager;->checkProtocol(I)V
-Landroid/net/nsd/NsdManager;->checkServiceInfo(Landroid/net/nsd/NsdServiceInfo;)V
-Landroid/net/nsd/NsdManager;->DBG:Z
-Landroid/net/nsd/NsdManager;->DISABLE:I
-Landroid/net/nsd/NsdManager;->disconnect()V
-Landroid/net/nsd/NsdManager;->DISCOVER_SERVICES:I
-Landroid/net/nsd/NsdManager;->DISCOVER_SERVICES_FAILED:I
-Landroid/net/nsd/NsdManager;->DISCOVER_SERVICES_STARTED:I
-Landroid/net/nsd/NsdManager;->ENABLE:I
-Landroid/net/nsd/NsdManager;->EVENT_NAMES:Landroid/util/SparseArray;
-Landroid/net/nsd/NsdManager;->fatal(Ljava/lang/String;)V
-Landroid/net/nsd/NsdManager;->FIRST_LISTENER_KEY:I
-Landroid/net/nsd/NsdManager;->getListenerKey(Ljava/lang/Object;)I
-Landroid/net/nsd/NsdManager;->getMessenger()Landroid/os/Messenger;
-Landroid/net/nsd/NsdManager;->getNsdServiceInfoType(Landroid/net/nsd/NsdServiceInfo;)Ljava/lang/String;
-Landroid/net/nsd/NsdManager;->init()V
-Landroid/net/nsd/NsdManager;->mAsyncChannel:Lcom/android/internal/util/AsyncChannel;
-Landroid/net/nsd/NsdManager;->mConnected:Ljava/util/concurrent/CountDownLatch;
-Landroid/net/nsd/NsdManager;->mContext:Landroid/content/Context;
-Landroid/net/nsd/NsdManager;->mHandler:Landroid/net/nsd/NsdManager$ServiceHandler;
-Landroid/net/nsd/NsdManager;->mListenerKey:I
-Landroid/net/nsd/NsdManager;->mListenerMap:Landroid/util/SparseArray;
-Landroid/net/nsd/NsdManager;->mMapLock:Ljava/lang/Object;
-Landroid/net/nsd/NsdManager;->mService:Landroid/net/nsd/INsdManager;
-Landroid/net/nsd/NsdManager;->mServiceMap:Landroid/util/SparseArray;
-Landroid/net/nsd/NsdManager;->nameOf(I)Ljava/lang/String;
-Landroid/net/nsd/NsdManager;->NATIVE_DAEMON_EVENT:I
-Landroid/net/nsd/NsdManager;->nextListenerKey()I
-Landroid/net/nsd/NsdManager;->putListener(Ljava/lang/Object;Landroid/net/nsd/NsdServiceInfo;)I
-Landroid/net/nsd/NsdManager;->REGISTER_SERVICE:I
-Landroid/net/nsd/NsdManager;->REGISTER_SERVICE_FAILED:I
-Landroid/net/nsd/NsdManager;->REGISTER_SERVICE_SUCCEEDED:I
-Landroid/net/nsd/NsdManager;->removeListener(I)V
-Landroid/net/nsd/NsdManager;->RESOLVE_SERVICE:I
-Landroid/net/nsd/NsdManager;->RESOLVE_SERVICE_FAILED:I
-Landroid/net/nsd/NsdManager;->RESOLVE_SERVICE_SUCCEEDED:I
-Landroid/net/nsd/NsdManager;->SERVICE_FOUND:I
-Landroid/net/nsd/NsdManager;->SERVICE_LOST:I
-Landroid/net/nsd/NsdManager;->setEnabled(Z)V
-Landroid/net/nsd/NsdManager;->STOP_DISCOVERY:I
-Landroid/net/nsd/NsdManager;->STOP_DISCOVERY_FAILED:I
-Landroid/net/nsd/NsdManager;->STOP_DISCOVERY_SUCCEEDED:I
-Landroid/net/nsd/NsdManager;->TAG:Ljava/lang/String;
-Landroid/net/nsd/NsdManager;->UNREGISTER_SERVICE:I
-Landroid/net/nsd/NsdManager;->UNREGISTER_SERVICE_FAILED:I
-Landroid/net/nsd/NsdManager;->UNREGISTER_SERVICE_SUCCEEDED:I
-Landroid/net/nsd/NsdServiceInfo;-><init>(Ljava/lang/String;Ljava/lang/String;)V
-Landroid/net/nsd/NsdServiceInfo;->getTxtRecord()[B
-Landroid/net/nsd/NsdServiceInfo;->getTxtRecordSize()I
-Landroid/net/nsd/NsdServiceInfo;->mHost:Ljava/net/InetAddress;
-Landroid/net/nsd/NsdServiceInfo;->mPort:I
-Landroid/net/nsd/NsdServiceInfo;->mServiceName:Ljava/lang/String;
-Landroid/net/nsd/NsdServiceInfo;->mServiceType:Ljava/lang/String;
-Landroid/net/nsd/NsdServiceInfo;->mTxtRecord:Landroid/util/ArrayMap;
-Landroid/net/nsd/NsdServiceInfo;->setTxtRecords(Ljava/lang/String;)V
-Landroid/net/nsd/NsdServiceInfo;->TAG:Ljava/lang/String;
 Landroid/net/PacProxySelector;-><init>()V
 Landroid/net/PacProxySelector;->mDefaultList:Ljava/util/List;
 Landroid/net/PacProxySelector;->mProxyService:Lcom/android/net/IProxyService;
diff --git a/boot/hiddenapi/hiddenapi-max-target-r-loprio.txt b/boot/hiddenapi/hiddenapi-max-target-r-loprio.txt
index 79d2521..20d7cc0 100644
--- a/boot/hiddenapi/hiddenapi-max-target-r-loprio.txt
+++ b/boot/hiddenapi/hiddenapi-max-target-r-loprio.txt
@@ -21,7 +21,6 @@
 Landroid/Manifest$permission;->READ_FRAME_BUFFER:Ljava/lang/String;
 Landroid/media/IVolumeController$Stub;->asInterface(Landroid/os/IBinder;)Landroid/media/IVolumeController;
 Landroid/net/INetworkPolicyListener$Stub;-><init>()V
-Landroid/net/nsd/INsdManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/nsd/INsdManager;
 Landroid/net/sip/ISipSession$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/sip/ISipSession;
 Landroid/nfc/INfcAdapter$Stub;->TRANSACTION_enable:I
 Landroid/os/IPowerManager$Stub;->TRANSACTION_acquireWakeLock:I
diff --git a/cmds/app_process/Android.bp b/cmds/app_process/Android.bp
index a157517..6a685a79 100644
--- a/cmds/app_process/Android.bp
+++ b/cmds/app_process/Android.bp
@@ -64,6 +64,8 @@
         "libwilhelm",
     ],
 
+    header_libs: ["bionic_libc_platform_headers"],
+
     compile_multilib: "both",
 
     cflags: [
diff --git a/cmds/app_process/app_main.cpp b/cmds/app_process/app_main.cpp
index 12083b6..815f945 100644
--- a/cmds/app_process/app_main.cpp
+++ b/cmds/app_process/app_main.cpp
@@ -15,6 +15,7 @@
 
 #include <android-base/macros.h>
 #include <binder/IPCThreadState.h>
+#include <bionic/pac.h>
 #include <hwbinder/IPCThreadState.h>
 #include <utils/Log.h>
 #include <cutils/memory.h>
@@ -182,6 +183,10 @@
       ALOGV("app_process main with argv: %s", argv_String.string());
     }
 
+    // Because of applications that are using PAC instructions incorrectly, PAC
+    // is disabled in application processes for now.
+    ScopedDisablePAC x;
+
     AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
     // Process command line arguments
     // ignore argv[0]
diff --git a/core/api/current.txt b/core/api/current.txt
index 95435f7..add4158 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -7185,6 +7185,7 @@
     method @Nullable public java.util.List<java.lang.String> getPermittedCrossProfileNotificationListeners(@NonNull android.content.ComponentName);
     method @Nullable public java.util.List<java.lang.String> getPermittedInputMethods(@NonNull android.content.ComponentName);
     method public int getPersonalAppsSuspendedReasons(@NonNull android.content.ComponentName);
+    method @NonNull public android.app.admin.PreferentialNetworkServiceConfig getPreferentialNetworkServiceConfig();
     method public int getRequiredPasswordComplexity();
     method public long getRequiredStrongAuthTimeout(@Nullable android.content.ComponentName);
     method public boolean getScreenCaptureDisabled(@Nullable android.content.ComponentName);
@@ -7327,6 +7328,7 @@
     method public boolean setPermittedCrossProfileNotificationListeners(@NonNull android.content.ComponentName, @Nullable java.util.List<java.lang.String>);
     method public boolean setPermittedInputMethods(@NonNull android.content.ComponentName, java.util.List<java.lang.String>);
     method public void setPersonalAppsSuspended(@NonNull android.content.ComponentName, boolean);
+    method public void setPreferentialNetworkServiceConfig(@NonNull android.app.admin.PreferentialNetworkServiceConfig);
     method public void setPreferentialNetworkServiceEnabled(boolean);
     method public void setProfileEnabled(@NonNull android.content.ComponentName);
     method public void setProfileName(@NonNull android.content.ComponentName, String);
@@ -7572,6 +7574,32 @@
     field @NonNull public static final android.os.Parcelable.Creator<android.app.admin.NetworkEvent> CREATOR;
   }
 
+  public final class PreferentialNetworkServiceConfig implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public int[] getExcludedUids();
+    method @NonNull public int[] getIncludedUids();
+    method public int getNetworkId();
+    method public boolean isEnabled();
+    method public boolean isFallbackToDefaultConnectionAllowed();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.app.admin.PreferentialNetworkServiceConfig> CREATOR;
+    field public static final int PREFERENTIAL_NETWORK_ID_1 = 1; // 0x1
+    field public static final int PREFERENTIAL_NETWORK_ID_2 = 2; // 0x2
+    field public static final int PREFERENTIAL_NETWORK_ID_3 = 3; // 0x3
+    field public static final int PREFERENTIAL_NETWORK_ID_4 = 4; // 0x4
+    field public static final int PREFERENTIAL_NETWORK_ID_5 = 5; // 0x5
+  }
+
+  public static final class PreferentialNetworkServiceConfig.Builder {
+    ctor public PreferentialNetworkServiceConfig.Builder();
+    method @NonNull public android.app.admin.PreferentialNetworkServiceConfig build();
+    method @NonNull public android.app.admin.PreferentialNetworkServiceConfig.Builder setEnabled(boolean);
+    method @NonNull public android.app.admin.PreferentialNetworkServiceConfig.Builder setExcludedUids(@NonNull int[]);
+    method @NonNull public android.app.admin.PreferentialNetworkServiceConfig.Builder setFallbackToDefaultConnectionAllowed(boolean);
+    method @NonNull public android.app.admin.PreferentialNetworkServiceConfig.Builder setIncludedUids(@NonNull int[]);
+    method @NonNull public android.app.admin.PreferentialNetworkServiceConfig.Builder setNetworkId(int);
+  }
+
   public class SecurityLog {
     ctor public SecurityLog();
     field public static final int LEVEL_ERROR = 3; // 0x3
@@ -8642,6 +8670,7 @@
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public java.util.Set<android.bluetooth.BluetoothDevice> getBondedDevices();
     method @Deprecated public static android.bluetooth.BluetoothAdapter getDefaultAdapter();
     method public int getLeMaximumAdvertisingDataLength();
+    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int getMaxConnectedAudioDevices();
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public String getName();
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int getProfileConnectionState(int);
     method public boolean getProfileProxy(android.content.Context, android.bluetooth.BluetoothProfile.ServiceListener, int);
@@ -8652,11 +8681,12 @@
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public boolean isDiscovering();
     method public boolean isEnabled();
     method public boolean isLe2MPhySupported();
+    method public int isLeAudioBroadcastAssistantSupported();
+    method public int isLeAudioBroadcastSourceSupported();
     method public int isLeAudioSupported();
     method public boolean isLeCodedPhySupported();
     method public boolean isLeExtendedAdvertisingSupported();
     method public boolean isLePeriodicAdvertisingSupported();
-    method public int isLePeriodicAdvertisingSyncTransferSenderSupported();
     method public boolean isMultipleAdvertisementSupported();
     method public boolean isOffloadedFilteringSupported();
     method public boolean isOffloadedScanBatchingSupported();
@@ -9061,6 +9091,7 @@
     field public static final int SOURCE_CODEC_TYPE_APTX = 2; // 0x2
     field public static final int SOURCE_CODEC_TYPE_APTX_HD = 3; // 0x3
     field public static final int SOURCE_CODEC_TYPE_INVALID = 1000000; // 0xf4240
+    field public static final int SOURCE_CODEC_TYPE_LC3 = 5; // 0x5
     field public static final int SOURCE_CODEC_TYPE_LDAC = 4; // 0x4
     field public static final int SOURCE_CODEC_TYPE_SBC = 0; // 0x0
   }
@@ -9153,6 +9184,7 @@
     field public static final String EXTRA_PAIRING_VARIANT = "android.bluetooth.device.extra.PAIRING_VARIANT";
     field public static final String EXTRA_PREVIOUS_BOND_STATE = "android.bluetooth.device.extra.PREVIOUS_BOND_STATE";
     field public static final String EXTRA_RSSI = "android.bluetooth.device.extra.RSSI";
+    field public static final String EXTRA_TRANSPORT = "android.bluetooth.device.extra.TRANSPORT";
     field public static final String EXTRA_UUID = "android.bluetooth.device.extra.UUID";
     field public static final int PAIRING_VARIANT_PASSKEY_CONFIRMATION = 2; // 0x2
     field public static final int PAIRING_VARIANT_PIN = 0; // 0x0
@@ -9515,24 +9547,61 @@
     method public void close();
     method protected void finalize();
     method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices();
+    method @Nullable @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public android.bluetooth.BluetoothDevice getConnectedGroupLeadDevice(int);
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int getConnectionState(@NonNull android.bluetooth.BluetoothDevice);
     method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public java.util.List<android.bluetooth.BluetoothDevice> getDevicesMatchingConnectionStates(@NonNull int[]);
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int getGroupId(@NonNull android.bluetooth.BluetoothDevice);
     field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_LE_AUDIO_CONNECTION_STATE_CHANGED = "android.bluetooth.action.LE_AUDIO_CONNECTION_STATE_CHANGED";
   }
 
-  public final class BluetoothLeAudioCodecConfig {
+  public final class BluetoothLeAudioCodecConfig implements android.os.Parcelable {
+    method public int describeContents();
+    method public int getBitsPerSample();
+    method public int getChannelMode();
     method @NonNull public String getCodecName();
+    method public int getCodecPriority();
     method public int getCodecType();
+    method public int getFrameDuration();
     method public static int getMaxCodecType();
+    method public int getOctetsPerFrame();
+    method public int getSampleRate();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field public static final int BITS_PER_SAMPLE_16 = 1; // 0x1
+    field public static final int BITS_PER_SAMPLE_24 = 2; // 0x2
+    field public static final int BITS_PER_SAMPLE_32 = 3; // 0x3
+    field public static final int BITS_PER_SAMPLE_NONE = 0; // 0x0
+    field public static final int CHANNEL_MODE_MONO = 1; // 0x1
+    field public static final int CHANNEL_MODE_NONE = 0; // 0x0
+    field public static final int CHANNEL_MODE_STEREO = 2; // 0x2
+    field public static final int CODEC_PRIORITY_DEFAULT = 0; // 0x0
+    field public static final int CODEC_PRIORITY_DISABLED = -1; // 0xffffffff
+    field public static final int CODEC_PRIORITY_HIGHEST = 1000000; // 0xf4240
+    field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BluetoothLeAudioCodecConfig> CREATOR;
+    field public static final int FRAME_DURATION_10000 = 2; // 0x2
+    field public static final int FRAME_DURATION_7500 = 1; // 0x1
+    field public static final int FRAME_DURATION_NONE = 0; // 0x0
+    field public static final int SAMPLE_RATE_16000 = 2; // 0x2
+    field public static final int SAMPLE_RATE_24000 = 3; // 0x3
+    field public static final int SAMPLE_RATE_32000 = 4; // 0x4
+    field public static final int SAMPLE_RATE_44100 = 5; // 0x5
+    field public static final int SAMPLE_RATE_48000 = 6; // 0x6
+    field public static final int SAMPLE_RATE_8000 = 1; // 0x1
+    field public static final int SAMPLE_RATE_NONE = 0; // 0x0
     field public static final int SOURCE_CODEC_TYPE_INVALID = 1000000; // 0xf4240
     field public static final int SOURCE_CODEC_TYPE_LC3 = 0; // 0x0
   }
 
   public static final class BluetoothLeAudioCodecConfig.Builder {
     ctor public BluetoothLeAudioCodecConfig.Builder();
+    ctor public BluetoothLeAudioCodecConfig.Builder(@NonNull android.bluetooth.BluetoothLeAudioCodecConfig);
     method @NonNull public android.bluetooth.BluetoothLeAudioCodecConfig build();
+    method @NonNull public android.bluetooth.BluetoothLeAudioCodecConfig.Builder setBitsPerSample(int);
+    method @NonNull public android.bluetooth.BluetoothLeAudioCodecConfig.Builder setChannelMode(int);
+    method @NonNull public android.bluetooth.BluetoothLeAudioCodecConfig.Builder setCodecPriority(int);
     method @NonNull public android.bluetooth.BluetoothLeAudioCodecConfig.Builder setCodecType(int);
+    method @NonNull public android.bluetooth.BluetoothLeAudioCodecConfig.Builder setFrameDuration(int);
+    method @NonNull public android.bluetooth.BluetoothLeAudioCodecConfig.Builder setOctetsPerFrame(int);
+    method @NonNull public android.bluetooth.BluetoothLeAudioCodecConfig.Builder setSampleRate(int);
   }
 
   public final class BluetoothManager {
@@ -9553,6 +9622,7 @@
     field public static final String EXTRA_STATE = "android.bluetooth.profile.extra.STATE";
     field public static final int GATT = 7; // 0x7
     field public static final int GATT_SERVER = 8; // 0x8
+    field public static final int HAP_CLIENT = 28; // 0x1c
     field public static final int HEADSET = 1; // 0x1
     field @Deprecated public static final int HEALTH = 3; // 0x3
     field public static final int HEARING_AID = 21; // 0x15
@@ -17980,10 +18050,12 @@
     ctor public BiometricPrompt.CryptoObject(@NonNull java.security.Signature);
     ctor public BiometricPrompt.CryptoObject(@NonNull javax.crypto.Cipher);
     ctor public BiometricPrompt.CryptoObject(@NonNull javax.crypto.Mac);
-    ctor public BiometricPrompt.CryptoObject(@NonNull android.security.identity.IdentityCredential);
+    ctor @Deprecated public BiometricPrompt.CryptoObject(@NonNull android.security.identity.IdentityCredential);
+    ctor public BiometricPrompt.CryptoObject(@NonNull android.security.identity.PresentationSession);
     method public javax.crypto.Cipher getCipher();
-    method @Nullable public android.security.identity.IdentityCredential getIdentityCredential();
+    method @Deprecated @Nullable public android.security.identity.IdentityCredential getIdentityCredential();
     method public javax.crypto.Mac getMac();
+    method @Nullable public android.security.identity.PresentationSession getPresentationSession();
     method public java.security.Signature getSignature();
   }
 
@@ -21879,9 +21951,11 @@
     field public static final int COLOR_Format24bitBGR888 = 12; // 0xc
     field @Deprecated public static final int COLOR_Format24bitRGB888 = 11; // 0xb
     field @Deprecated public static final int COLOR_Format25bitARGB1888 = 14; // 0xe
+    field public static final int COLOR_Format32bitABGR2101010 = 2130750114; // 0x7f00aaa2
     field public static final int COLOR_Format32bitABGR8888 = 2130747392; // 0x7f00a000
     field @Deprecated public static final int COLOR_Format32bitARGB8888 = 16; // 0x10
     field @Deprecated public static final int COLOR_Format32bitBGRA8888 = 15; // 0xf
+    field public static final int COLOR_Format64bitABGRFloat = 2130710294; // 0x7f000f16
     field @Deprecated public static final int COLOR_Format8bitRGB332 = 2; // 0x2
     field @Deprecated public static final int COLOR_FormatCbYCrY = 27; // 0x1b
     field @Deprecated public static final int COLOR_FormatCrYCbY = 28; // 0x1c
@@ -21914,10 +21988,12 @@
     field @Deprecated public static final int COLOR_FormatYUV422SemiPlanar = 24; // 0x18
     field public static final int COLOR_FormatYUV444Flexible = 2135181448; // 0x7f444888
     field @Deprecated public static final int COLOR_FormatYUV444Interleaved = 29; // 0x1d
+    field public static final int COLOR_FormatYUVP010 = 54; // 0x36
     field @Deprecated public static final int COLOR_QCOM_FormatYUV420SemiPlanar = 2141391872; // 0x7fa30c00
     field @Deprecated public static final int COLOR_TI_FormatYUV420PackedSemiPlanar = 2130706688; // 0x7f000100
     field public static final String FEATURE_AdaptivePlayback = "adaptive-playback";
     field public static final String FEATURE_DynamicTimestamp = "dynamic-timestamp";
+    field public static final String FEATURE_EncodingStatistics = "encoding-statistics";
     field public static final String FEATURE_FrameParsing = "frame-parsing";
     field public static final String FEATURE_IntraRefresh = "intra-refresh";
     field public static final String FEATURE_LowLatency = "low-latency";
@@ -22691,6 +22767,7 @@
     field public static final String KEY_OPERATING_RATE = "operating-rate";
     field public static final String KEY_OUTPUT_REORDER_DEPTH = "output-reorder-depth";
     field public static final String KEY_PCM_ENCODING = "pcm-encoding";
+    field public static final String KEY_PICTURE_TYPE = "picture-type";
     field public static final String KEY_PIXEL_ASPECT_RATIO_HEIGHT = "sar-height";
     field public static final String KEY_PIXEL_ASPECT_RATIO_WIDTH = "sar-width";
     field public static final String KEY_PREPEND_HEADER_TO_SYNC_FRAMES = "prepend-sps-pps-to-idr-frames";
@@ -22708,6 +22785,8 @@
     field public static final String KEY_TILE_HEIGHT = "tile-height";
     field public static final String KEY_TILE_WIDTH = "tile-width";
     field public static final String KEY_TRACK_ID = "track-id";
+    field public static final String KEY_VIDEO_ENCODING_STATISTICS_LEVEL = "video-encoding-statistics-level";
+    field public static final String KEY_VIDEO_QP_AVERAGE = "video-qp-average";
     field public static final String KEY_VIDEO_QP_B_MAX = "video-qp-b-max";
     field public static final String KEY_VIDEO_QP_B_MIN = "video-qp-b-min";
     field public static final String KEY_VIDEO_QP_I_MAX = "video-qp-i-max";
@@ -22752,12 +22831,18 @@
     field public static final String MIMETYPE_VIDEO_SCRAMBLED = "video/scrambled";
     field public static final String MIMETYPE_VIDEO_VP8 = "video/x-vnd.on2.vp8";
     field public static final String MIMETYPE_VIDEO_VP9 = "video/x-vnd.on2.vp9";
+    field public static final int PICTURE_TYPE_B = 3; // 0x3
+    field public static final int PICTURE_TYPE_I = 1; // 0x1
+    field public static final int PICTURE_TYPE_P = 2; // 0x2
+    field public static final int PICTURE_TYPE_UNKNOWN = 0; // 0x0
     field public static final int TYPE_BYTE_BUFFER = 5; // 0x5
     field public static final int TYPE_FLOAT = 3; // 0x3
     field public static final int TYPE_INTEGER = 1; // 0x1
     field public static final int TYPE_LONG = 2; // 0x2
     field public static final int TYPE_NULL = 0; // 0x0
     field public static final int TYPE_STRING = 4; // 0x4
+    field public static final int VIDEO_ENCODING_STATISTICS_LEVEL_1 = 1; // 0x1
+    field public static final int VIDEO_ENCODING_STATISTICS_LEVEL_NONE = 0; // 0x0
   }
 
   public final class MediaMetadata implements android.os.Parcelable {
@@ -26982,65 +27067,6 @@
 
 }
 
-package android.net.nsd {
-
-  public final class NsdManager {
-    method public void discoverServices(String, int, android.net.nsd.NsdManager.DiscoveryListener);
-    method public void registerService(android.net.nsd.NsdServiceInfo, int, android.net.nsd.NsdManager.RegistrationListener);
-    method public void resolveService(android.net.nsd.NsdServiceInfo, android.net.nsd.NsdManager.ResolveListener);
-    method public void stopServiceDiscovery(android.net.nsd.NsdManager.DiscoveryListener);
-    method public void unregisterService(android.net.nsd.NsdManager.RegistrationListener);
-    field public static final String ACTION_NSD_STATE_CHANGED = "android.net.nsd.STATE_CHANGED";
-    field public static final String EXTRA_NSD_STATE = "nsd_state";
-    field public static final int FAILURE_ALREADY_ACTIVE = 3; // 0x3
-    field public static final int FAILURE_INTERNAL_ERROR = 0; // 0x0
-    field public static final int FAILURE_MAX_LIMIT = 4; // 0x4
-    field public static final int NSD_STATE_DISABLED = 1; // 0x1
-    field public static final int NSD_STATE_ENABLED = 2; // 0x2
-    field public static final int PROTOCOL_DNS_SD = 1; // 0x1
-  }
-
-  public static interface NsdManager.DiscoveryListener {
-    method public void onDiscoveryStarted(String);
-    method public void onDiscoveryStopped(String);
-    method public void onServiceFound(android.net.nsd.NsdServiceInfo);
-    method public void onServiceLost(android.net.nsd.NsdServiceInfo);
-    method public void onStartDiscoveryFailed(String, int);
-    method public void onStopDiscoveryFailed(String, int);
-  }
-
-  public static interface NsdManager.RegistrationListener {
-    method public void onRegistrationFailed(android.net.nsd.NsdServiceInfo, int);
-    method public void onServiceRegistered(android.net.nsd.NsdServiceInfo);
-    method public void onServiceUnregistered(android.net.nsd.NsdServiceInfo);
-    method public void onUnregistrationFailed(android.net.nsd.NsdServiceInfo, int);
-  }
-
-  public static interface NsdManager.ResolveListener {
-    method public void onResolveFailed(android.net.nsd.NsdServiceInfo, int);
-    method public void onServiceResolved(android.net.nsd.NsdServiceInfo);
-  }
-
-  public final class NsdServiceInfo implements android.os.Parcelable {
-    ctor public NsdServiceInfo();
-    method public int describeContents();
-    method public java.util.Map<java.lang.String,byte[]> getAttributes();
-    method public java.net.InetAddress getHost();
-    method public int getPort();
-    method public String getServiceName();
-    method public String getServiceType();
-    method public void removeAttribute(String);
-    method public void setAttribute(String, String);
-    method public void setHost(java.net.InetAddress);
-    method public void setPort(int);
-    method public void setServiceName(String);
-    method public void setServiceType(String);
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.nsd.NsdServiceInfo> CREATOR;
-  }
-
-}
-
 package android.net.rtp {
 
   @Deprecated public class AudioCodec {
@@ -27290,6 +27316,8 @@
     ctor public VcnCellUnderlyingNetworkTemplate.Builder();
     method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate build();
     method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setMetered(int);
+    method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setMinDownstreamBandwidthKbps(int, int);
+    method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setMinUpstreamBandwidthKbps(int, int);
     method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setOperatorPlmnIds(@NonNull java.util.Set<java.lang.String>);
     method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setOpportunistic(int);
     method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setRoaming(int);
@@ -27350,6 +27378,10 @@
 
   public abstract class VcnUnderlyingNetworkTemplate {
     method public int getMetered();
+    method public int getMinEntryDownstreamBandwidthKbps();
+    method public int getMinEntryUpstreamBandwidthKbps();
+    method public int getMinExitDownstreamBandwidthKbps();
+    method public int getMinExitUpstreamBandwidthKbps();
     field public static final int MATCH_ANY = 0; // 0x0
     field public static final int MATCH_FORBIDDEN = 2; // 0x2
     field public static final int MATCH_REQUIRED = 1; // 0x1
@@ -27363,6 +27395,8 @@
     ctor public VcnWifiUnderlyingNetworkTemplate.Builder();
     method @NonNull public android.net.vcn.VcnWifiUnderlyingNetworkTemplate build();
     method @NonNull public android.net.vcn.VcnWifiUnderlyingNetworkTemplate.Builder setMetered(int);
+    method @NonNull public android.net.vcn.VcnWifiUnderlyingNetworkTemplate.Builder setMinDownstreamBandwidthKbps(int, int);
+    method @NonNull public android.net.vcn.VcnWifiUnderlyingNetworkTemplate.Builder setMinUpstreamBandwidthKbps(int, int);
     method @NonNull public android.net.vcn.VcnWifiUnderlyingNetworkTemplate.Builder setSsids(@NonNull java.util.Set<java.lang.String>);
   }
 
@@ -31637,7 +31671,7 @@
     method @Deprecated public void readMap(@NonNull java.util.Map, @Nullable ClassLoader);
     method public <K, V> void readMap(@NonNull java.util.Map<? super K,? super V>, @Nullable ClassLoader, @NonNull Class<K>, @NonNull Class<V>);
     method @Deprecated @Nullable public <T extends android.os.Parcelable> T readParcelable(@Nullable ClassLoader);
-    method @Nullable public <T> T readParcelable(@Nullable ClassLoader, @NonNull Class<T>);
+    method @Nullable public <T extends android.os.Parcelable> T readParcelable(@Nullable ClassLoader, @NonNull Class<? super T>);
     method @Deprecated @Nullable public android.os.Parcelable[] readParcelableArray(@Nullable ClassLoader);
     method @Nullable public <T> T[] readParcelableArray(@Nullable ClassLoader, @NonNull Class<T>);
     method @Deprecated @Nullable public android.os.Parcelable.Creator<?> readParcelableCreator(@Nullable ClassLoader);
@@ -31647,7 +31681,7 @@
     method @Nullable public android.os.PersistableBundle readPersistableBundle();
     method @Nullable public android.os.PersistableBundle readPersistableBundle(@Nullable ClassLoader);
     method @Deprecated @Nullable public java.io.Serializable readSerializable();
-    method @Nullable public <T> T readSerializable(@Nullable ClassLoader, @NonNull Class<T>);
+    method @Nullable public <T extends java.io.Serializable> T readSerializable(@Nullable ClassLoader, @NonNull Class<? super T>);
     method @NonNull public android.util.Size readSize();
     method @NonNull public android.util.SizeF readSizeF();
     method @Deprecated @Nullable public <T> android.util.SparseArray<T> readSparseArray(@Nullable ClassLoader);
@@ -37542,6 +37576,51 @@
     ctor public CipherSuiteNotSupportedException(@NonNull String, @NonNull Throwable);
   }
 
+  public class CredentialDataRequest {
+    method @NonNull public java.util.Map<java.lang.String,java.util.Collection<java.lang.String>> getDeviceSignedEntriesToRequest();
+    method @NonNull public java.util.Map<java.lang.String,java.util.Collection<java.lang.String>> getIssuerSignedEntriesToRequest();
+    method @Nullable public byte[] getReaderSignature();
+    method @Nullable public byte[] getRequestMessage();
+    method public boolean isAllowUsingExhaustedKeys();
+    method public boolean isAllowUsingExpiredKeys();
+    method public boolean isIncrementUseCount();
+  }
+
+  public static final class CredentialDataRequest.Builder {
+    ctor public CredentialDataRequest.Builder();
+    method @NonNull public android.security.identity.CredentialDataRequest build();
+    method @NonNull public android.security.identity.CredentialDataRequest.Builder setAllowUsingExhaustedKeys(boolean);
+    method @NonNull public android.security.identity.CredentialDataRequest.Builder setAllowUsingExpiredKeys(boolean);
+    method @NonNull public android.security.identity.CredentialDataRequest.Builder setDeviceSignedEntriesToRequest(@NonNull java.util.Map<java.lang.String,java.util.Collection<java.lang.String>>);
+    method @NonNull public android.security.identity.CredentialDataRequest.Builder setIncrementUseCount(boolean);
+    method @NonNull public android.security.identity.CredentialDataRequest.Builder setIssuerSignedEntriesToRequest(@NonNull java.util.Map<java.lang.String,java.util.Collection<java.lang.String>>);
+    method @NonNull public android.security.identity.CredentialDataRequest.Builder setReaderSignature(@NonNull byte[]);
+    method @NonNull public android.security.identity.CredentialDataRequest.Builder setRequestMessage(@NonNull byte[]);
+  }
+
+  public abstract class CredentialDataResult {
+    method @Nullable public abstract byte[] getDeviceMac();
+    method @NonNull public abstract byte[] getDeviceNameSpaces();
+    method @NonNull public abstract android.security.identity.CredentialDataResult.Entries getDeviceSignedEntries();
+    method @NonNull public abstract android.security.identity.CredentialDataResult.Entries getIssuerSignedEntries();
+    method @NonNull public abstract byte[] getStaticAuthenticationData();
+  }
+
+  public static interface CredentialDataResult.Entries {
+    method @Nullable public byte[] getEntry(@NonNull String, @NonNull String);
+    method @NonNull public java.util.Collection<java.lang.String> getEntryNames(@NonNull String);
+    method @NonNull public java.util.Collection<java.lang.String> getNamespaces();
+    method @NonNull public java.util.Collection<java.lang.String> getRetrievedEntryNames(@NonNull String);
+    method public int getStatus(@NonNull String, @NonNull String);
+    field public static final int STATUS_NOT_IN_REQUEST_MESSAGE = 3; // 0x3
+    field public static final int STATUS_NOT_REQUESTED = 2; // 0x2
+    field public static final int STATUS_NO_ACCESS_CONTROL_PROFILES = 6; // 0x6
+    field public static final int STATUS_NO_SUCH_ENTRY = 1; // 0x1
+    field public static final int STATUS_OK = 0; // 0x0
+    field public static final int STATUS_READER_AUTHENTICATION_FAILED = 5; // 0x5
+    field public static final int STATUS_USER_AUTHENTICATION_FAILED = 4; // 0x4
+  }
+
   public class DocTypeNotSupportedException extends android.security.identity.IdentityCredentialException {
     ctor public DocTypeNotSupportedException(@NonNull String);
     ctor public DocTypeNotSupportedException(@NonNull String, @NonNull Throwable);
@@ -37553,19 +37632,19 @@
   }
 
   public abstract class IdentityCredential {
-    method @NonNull public abstract java.security.KeyPair createEphemeralKeyPair();
-    method @NonNull public abstract byte[] decryptMessageFromReader(@NonNull byte[]) throws android.security.identity.MessageDecryptionException;
+    method @Deprecated @NonNull public abstract java.security.KeyPair createEphemeralKeyPair();
+    method @Deprecated @NonNull public abstract byte[] decryptMessageFromReader(@NonNull byte[]) throws android.security.identity.MessageDecryptionException;
     method @NonNull public byte[] delete(@NonNull byte[]);
-    method @NonNull public abstract byte[] encryptMessageToReader(@NonNull byte[]);
+    method @Deprecated @NonNull public abstract byte[] encryptMessageToReader(@NonNull byte[]);
     method @NonNull public abstract java.util.Collection<java.security.cert.X509Certificate> getAuthKeysNeedingCertification();
     method @NonNull public abstract int[] getAuthenticationDataUsageCount();
     method @NonNull public abstract java.util.Collection<java.security.cert.X509Certificate> getCredentialKeyCertificateChain();
-    method @NonNull public abstract android.security.identity.ResultData getEntries(@Nullable byte[], @NonNull java.util.Map<java.lang.String,java.util.Collection<java.lang.String>>, @Nullable byte[], @Nullable byte[]) throws android.security.identity.EphemeralPublicKeyNotFoundException, android.security.identity.InvalidReaderSignatureException, android.security.identity.InvalidRequestMessageException, android.security.identity.NoAuthenticationKeyAvailableException, android.security.identity.SessionTranscriptMismatchException;
+    method @Deprecated @NonNull public abstract android.security.identity.ResultData getEntries(@Nullable byte[], @NonNull java.util.Map<java.lang.String,java.util.Collection<java.lang.String>>, @Nullable byte[], @Nullable byte[]) throws android.security.identity.EphemeralPublicKeyNotFoundException, android.security.identity.InvalidReaderSignatureException, android.security.identity.InvalidRequestMessageException, android.security.identity.NoAuthenticationKeyAvailableException, android.security.identity.SessionTranscriptMismatchException;
     method @NonNull public byte[] proveOwnership(@NonNull byte[]);
-    method public abstract void setAllowUsingExhaustedKeys(boolean);
-    method public void setAllowUsingExpiredKeys(boolean);
+    method @Deprecated public abstract void setAllowUsingExhaustedKeys(boolean);
+    method @Deprecated public void setAllowUsingExpiredKeys(boolean);
     method public abstract void setAvailableAuthenticationKeys(int, int);
-    method public abstract void setReaderEphemeralPublicKey(@NonNull java.security.PublicKey) throws java.security.InvalidKeyException;
+    method @Deprecated public abstract void setReaderEphemeralPublicKey(@NonNull java.security.PublicKey) throws java.security.InvalidKeyException;
     method @Deprecated public abstract void storeStaticAuthenticationData(@NonNull java.security.cert.X509Certificate, @NonNull byte[]) throws android.security.identity.UnknownAuthenticationKeyException;
     method public void storeStaticAuthenticationData(@NonNull java.security.cert.X509Certificate, @NonNull java.time.Instant, @NonNull byte[]) throws android.security.identity.UnknownAuthenticationKeyException;
     method @NonNull public byte[] update(@NonNull android.security.identity.PersonalizationData);
@@ -37578,6 +37657,7 @@
 
   public abstract class IdentityCredentialStore {
     method @NonNull public abstract android.security.identity.WritableIdentityCredential createCredential(@NonNull String, @NonNull String) throws android.security.identity.AlreadyPersonalizedException, android.security.identity.DocTypeNotSupportedException;
+    method @NonNull public android.security.identity.PresentationSession createPresentationSession(int) throws android.security.identity.CipherSuiteNotSupportedException;
     method @Deprecated @Nullable public abstract byte[] deleteCredentialByName(@NonNull String);
     method @Nullable public abstract android.security.identity.IdentityCredential getCredentialByName(@NonNull String, int) throws android.security.identity.CipherSuiteNotSupportedException;
     method @Nullable public static android.security.identity.IdentityCredentialStore getDirectAccessInstance(@NonNull android.content.Context);
@@ -37616,22 +37696,29 @@
     method @NonNull public android.security.identity.PersonalizationData.Builder putEntry(@NonNull String, @NonNull String, @NonNull java.util.Collection<android.security.identity.AccessControlProfileId>, @NonNull byte[]);
   }
 
-  public abstract class ResultData {
-    method @NonNull public abstract byte[] getAuthenticatedData();
-    method @Nullable public abstract byte[] getEntry(@NonNull String, @NonNull String);
-    method @Nullable public abstract java.util.Collection<java.lang.String> getEntryNames(@NonNull String);
-    method @Nullable public abstract byte[] getMessageAuthenticationCode();
-    method @NonNull public abstract java.util.Collection<java.lang.String> getNamespaces();
-    method @Nullable public abstract java.util.Collection<java.lang.String> getRetrievedEntryNames(@NonNull String);
-    method @NonNull public abstract byte[] getStaticAuthenticationData();
-    method public abstract int getStatus(@NonNull String, @NonNull String);
-    field public static final int STATUS_NOT_IN_REQUEST_MESSAGE = 3; // 0x3
-    field public static final int STATUS_NOT_REQUESTED = 2; // 0x2
-    field public static final int STATUS_NO_ACCESS_CONTROL_PROFILES = 6; // 0x6
-    field public static final int STATUS_NO_SUCH_ENTRY = 1; // 0x1
-    field public static final int STATUS_OK = 0; // 0x0
-    field public static final int STATUS_READER_AUTHENTICATION_FAILED = 5; // 0x5
-    field public static final int STATUS_USER_AUTHENTICATION_FAILED = 4; // 0x4
+  public abstract class PresentationSession {
+    method @Nullable public abstract android.security.identity.CredentialDataResult getCredentialData(@NonNull String, @NonNull android.security.identity.CredentialDataRequest) throws android.security.identity.EphemeralPublicKeyNotFoundException, android.security.identity.InvalidReaderSignatureException, android.security.identity.InvalidRequestMessageException, android.security.identity.NoAuthenticationKeyAvailableException;
+    method @NonNull public abstract java.security.KeyPair getEphemeralKeyPair();
+    method public abstract void setReaderEphemeralPublicKey(@NonNull java.security.PublicKey) throws java.security.InvalidKeyException;
+    method public abstract void setSessionTranscript(@NonNull byte[]);
+  }
+
+  @Deprecated public abstract class ResultData {
+    method @Deprecated @NonNull public abstract byte[] getAuthenticatedData();
+    method @Deprecated @Nullable public abstract byte[] getEntry(@NonNull String, @NonNull String);
+    method @Deprecated @Nullable public abstract java.util.Collection<java.lang.String> getEntryNames(@NonNull String);
+    method @Deprecated @Nullable public abstract byte[] getMessageAuthenticationCode();
+    method @Deprecated @NonNull public abstract java.util.Collection<java.lang.String> getNamespaces();
+    method @Deprecated @Nullable public abstract java.util.Collection<java.lang.String> getRetrievedEntryNames(@NonNull String);
+    method @Deprecated @NonNull public abstract byte[] getStaticAuthenticationData();
+    method @Deprecated public abstract int getStatus(@NonNull String, @NonNull String);
+    field @Deprecated public static final int STATUS_NOT_IN_REQUEST_MESSAGE = 3; // 0x3
+    field @Deprecated public static final int STATUS_NOT_REQUESTED = 2; // 0x2
+    field @Deprecated public static final int STATUS_NO_ACCESS_CONTROL_PROFILES = 6; // 0x6
+    field @Deprecated public static final int STATUS_NO_SUCH_ENTRY = 1; // 0x1
+    field @Deprecated public static final int STATUS_OK = 0; // 0x0
+    field @Deprecated public static final int STATUS_READER_AUTHENTICATION_FAILED = 5; // 0x5
+    field @Deprecated public static final int STATUS_USER_AUTHENTICATION_FAILED = 4; // 0x4
   }
 
   public class SessionTranscriptMismatchException extends android.security.identity.IdentityCredentialException {
@@ -41254,6 +41341,7 @@
     field public static final int EPDG_ADDRESS_PCO = 2; // 0x2
     field public static final int EPDG_ADDRESS_PLMN = 1; // 0x1
     field public static final int EPDG_ADDRESS_STATIC = 0; // 0x0
+    field public static final int EPDG_ADDRESS_VISITED_COUNTRY = 4; // 0x4
     field public static final int ID_TYPE_FQDN = 2; // 0x2
     field public static final int ID_TYPE_KEY_ID = 11; // 0xb
     field public static final int ID_TYPE_RFC822_ADDR = 3; // 0x3
@@ -41285,6 +41373,7 @@
     field public static final String KEY_SUPPORTED_IKE_SESSION_ENCRYPTION_ALGORITHMS_INT_ARRAY = "iwlan.supported_ike_session_encryption_algorithms_int_array";
     field public static final String KEY_SUPPORTED_INTEGRITY_ALGORITHMS_INT_ARRAY = "iwlan.supported_integrity_algorithms_int_array";
     field public static final String KEY_SUPPORTED_PRF_ALGORITHMS_INT_ARRAY = "iwlan.supported_prf_algorithms_int_array";
+    field public static final String KEY_SUPPORTS_EAP_AKA_FAST_REAUTH_BOOL = "iwlan.supports_eap_aka_fast_reauth_bool";
   }
 
   public abstract class CellIdentity implements android.os.Parcelable {
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index 3300ea0..74ec189 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -54,7 +54,30 @@
 package android.app.usage {
 
   public class NetworkStatsManager {
+    method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK}) public void forceUpdate();
     method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK}) public void notifyNetworkStatus(@NonNull java.util.List<android.net.Network>, @NonNull java.util.List<android.net.NetworkStateSnapshot>, @Nullable String, @NonNull java.util.List<android.net.UnderlyingNetworkInfo>);
+    method @NonNull @WorkerThread public android.app.usage.NetworkStats queryDetailsForDevice(@NonNull android.net.NetworkTemplate, long, long);
+    method @NonNull @WorkerThread public android.app.usage.NetworkStats queryDetailsForUidTagState(@NonNull android.net.NetworkTemplate, long, long, int, int, int) throws java.lang.SecurityException;
+    method @NonNull @WorkerThread public android.app.usage.NetworkStats querySummary(@NonNull android.net.NetworkTemplate, long, long) throws java.lang.SecurityException;
+    method @NonNull @WorkerThread public android.app.usage.NetworkStats.Bucket querySummaryForDevice(@NonNull android.net.NetworkTemplate, long, long);
+    method @NonNull @WorkerThread public android.app.usage.NetworkStats queryTaggedSummary(@NonNull android.net.NetworkTemplate, long, long) throws java.lang.SecurityException;
+    method public void registerUsageCallback(@NonNull android.net.NetworkTemplate, long, @NonNull java.util.concurrent.Executor, @NonNull android.app.usage.NetworkStatsManager.UsageCallback);
+    method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK}) public void setDefaultGlobalAlert(long);
+    method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK}) public void setPollOnOpen(boolean);
+    method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK}) public void setStatsProviderWarningAndLimitAsync(@NonNull String, long, long);
+    method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK}) public void setUidForeground(int, boolean);
+  }
+
+  public abstract static class NetworkStatsManager.UsageCallback {
+    method public void onThresholdReached(@NonNull android.net.NetworkTemplate);
+  }
+
+}
+
+package android.bluetooth {
+
+  public final class BluetoothPan implements android.bluetooth.BluetoothProfile {
+    method @Nullable @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED, android.Manifest.permission.TETHER_PRIVILEGED}) public android.net.TetheringManager.TetheredInterfaceRequest requestTetheredInterface(@NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.TetheredInterfaceCallback);
   }
 
 }
@@ -135,6 +158,7 @@
 
   public final class BtProfileConnectionInfo implements android.os.Parcelable {
     method @NonNull public static android.media.BtProfileConnectionInfo a2dpInfo(boolean, int);
+    method @NonNull public static android.media.BtProfileConnectionInfo a2dpSinkInfo(int);
     method public int describeContents();
     method public boolean getIsLeOutput();
     method public int getProfile();
@@ -200,10 +224,6 @@
 
 package android.net {
 
-  public final class ConnectivityFrameworkInitializerTiramisu {
-    method public static void registerServiceWrappers();
-  }
-
   public final class EthernetNetworkSpecifier extends android.net.NetworkSpecifier implements android.os.Parcelable {
     ctor public EthernetNetworkSpecifier(@NonNull String);
     method public int describeContents();
@@ -220,11 +240,43 @@
     method public int getResourceId();
   }
 
+  public class LocalSocket implements java.io.Closeable {
+    ctor public LocalSocket(@NonNull java.io.FileDescriptor);
+  }
+
+  public class NetworkIdentity {
+    method public int getOemManaged();
+    method public int getRatType();
+    method @Nullable public String getSubscriberId();
+    method public int getType();
+    method @Nullable public String getWifiNetworkKey();
+    method public boolean isDefaultNetwork();
+    method public boolean isMetered();
+    method public boolean isRoaming();
+  }
+
+  public static final class NetworkIdentity.Builder {
+    ctor public NetworkIdentity.Builder();
+    method @NonNull public android.net.NetworkIdentity build();
+    method @NonNull public android.net.NetworkIdentity.Builder clearRatType();
+    method @NonNull public android.net.NetworkIdentity.Builder setDefaultNetwork(boolean);
+    method @NonNull public android.net.NetworkIdentity.Builder setMetered(boolean);
+    method @NonNull public android.net.NetworkIdentity.Builder setNetworkStateSnapshot(@NonNull android.net.NetworkStateSnapshot);
+    method @NonNull public android.net.NetworkIdentity.Builder setOemManaged(int);
+    method @NonNull public android.net.NetworkIdentity.Builder setRatType(int);
+    method @NonNull public android.net.NetworkIdentity.Builder setRoaming(boolean);
+    method @NonNull public android.net.NetworkIdentity.Builder setSubscriberId(@Nullable String);
+    method @NonNull public android.net.NetworkIdentity.Builder setType(int);
+    method @NonNull public android.net.NetworkIdentity.Builder setWifiNetworkKey(@Nullable String);
+  }
+
   public class NetworkPolicyManager {
     method @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public int getMultipathPreference(@NonNull android.net.Network);
     method @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public int getRestrictBackgroundStatus(int);
+    method @Nullable @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK}) public android.telephony.SubscriptionPlan getSubscriptionPlan(@NonNull android.net.NetworkTemplate);
     method @RequiresPermission(android.Manifest.permission.OBSERVE_NETWORK_POLICY) public boolean isUidNetworkingBlocked(int, boolean);
     method @RequiresPermission(android.Manifest.permission.OBSERVE_NETWORK_POLICY) public boolean isUidRestrictedOnMeteredNetworks(int);
+    method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK}) public void notifyStatsProviderWarningOrLimitReached();
     method @RequiresPermission(android.Manifest.permission.OBSERVE_NETWORK_POLICY) public void registerNetworkPolicyCallback(@Nullable java.util.concurrent.Executor, @NonNull android.net.NetworkPolicyManager.NetworkPolicyCallback);
     method @RequiresPermission(android.Manifest.permission.OBSERVE_NETWORK_POLICY) public void unregisterNetworkPolicyCallback(@NonNull android.net.NetworkPolicyManager.NetworkPolicyCallback);
   }
@@ -245,6 +297,44 @@
     field @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkStateSnapshot> CREATOR;
   }
 
+  public class NetworkStatsCollection {
+    method @NonNull public java.util.Map<android.net.NetworkStatsCollection.Key,android.net.NetworkStatsHistory> getEntries();
+  }
+
+  public static final class NetworkStatsCollection.Builder {
+    ctor public NetworkStatsCollection.Builder(long);
+    method @NonNull public android.net.NetworkStatsCollection.Builder addEntry(@NonNull android.net.NetworkStatsCollection.Key, @NonNull android.net.NetworkStatsHistory);
+    method @NonNull public android.net.NetworkStatsCollection build();
+  }
+
+  public static class NetworkStatsCollection.Key {
+    ctor public NetworkStatsCollection.Key(@NonNull java.util.Set<android.net.NetworkIdentity>, int, int, int);
+  }
+
+  public final class NetworkStatsHistory implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public java.util.List<android.net.NetworkStatsHistory.Entry> getEntries();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkStatsHistory> CREATOR;
+  }
+
+  public static final class NetworkStatsHistory.Builder {
+    ctor public NetworkStatsHistory.Builder(long, int);
+    method @NonNull public android.net.NetworkStatsHistory.Builder addEntry(@NonNull android.net.NetworkStatsHistory.Entry);
+    method @NonNull public android.net.NetworkStatsHistory build();
+  }
+
+  public static final class NetworkStatsHistory.Entry {
+    ctor public NetworkStatsHistory.Entry(long, long, long, long, long, long, long);
+    method public long getActiveTime();
+    method public long getBucketStart();
+    method public long getOperations();
+    method public long getRxBytes();
+    method public long getRxPackets();
+    method public long getTxBytes();
+    method public long getTxPackets();
+  }
+
   public final class NetworkTemplate implements android.os.Parcelable {
     method public int describeContents();
     method public int getDefaultNetworkStatus();
@@ -255,6 +345,7 @@
     method public int getRoaming();
     method @NonNull public java.util.Set<java.lang.String> getSubscriberIds();
     method @NonNull public java.util.Set<java.lang.String> getWifiNetworkKeys();
+    method public boolean matches(@NonNull android.net.NetworkIdentity);
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkTemplate> CREATOR;
     field public static final int MATCH_BLUETOOTH = 8; // 0x8
@@ -300,6 +391,11 @@
     method public static void setHttpProxyConfiguration(@Nullable android.net.ProxyInfo);
   }
 
+  public class TrafficStats {
+    method public static void attachSocketTagger();
+    method public static void init(@NonNull android.content.Context);
+  }
+
   public final class UnderlyingNetworkInfo implements android.os.Parcelable {
     ctor public UnderlyingNetworkInfo(int, @NonNull String, @NonNull java.util.List<java.lang.String>);
     method public int describeContents();
@@ -343,6 +439,7 @@
   }
 
   public class Process {
+    field public static final int NFC_UID = 1027; // 0x403
     field public static final int VPN_UID = 1016; // 0x3f8
   }
 
@@ -374,6 +471,16 @@
     method @NonNull public java.util.List<android.content.ComponentName> getEnabledComponentOverrides(@NonNull String);
   }
 
+  public final class Trace {
+    method public static void asyncTraceBegin(long, @NonNull String, int);
+    method public static void asyncTraceEnd(long, @NonNull String, int);
+    method public static boolean isTagEnabled(long);
+    method public static void traceBegin(long, @NonNull String);
+    method public static void traceCounter(long, @NonNull String, int);
+    method public static void traceEnd(long);
+    field public static final long TRACE_TAG_NETWORK = 2097152L; // 0x200000L
+  }
+
 }
 
 package android.os.storage {
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index b4a82ff..9e061d58 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -138,6 +138,7 @@
     field public static final String MANAGE_APP_PREDICTIONS = "android.permission.MANAGE_APP_PREDICTIONS";
     field public static final String MANAGE_APP_TOKENS = "android.permission.MANAGE_APP_TOKENS";
     field public static final String MANAGE_AUTO_FILL = "android.permission.MANAGE_AUTO_FILL";
+    field public static final String MANAGE_BLUETOOTH_WHEN_WIRELESS_CONSENT_REQUIRED = "android.permission.MANAGE_BLUETOOTH_WHEN_WIRELESS_CONSENT_REQUIRED";
     field public static final String MANAGE_CARRIER_OEM_UNLOCK_STATE = "android.permission.MANAGE_CARRIER_OEM_UNLOCK_STATE";
     field public static final String MANAGE_CA_CERTIFICATES = "android.permission.MANAGE_CA_CERTIFICATES";
     field public static final String MANAGE_CONTENT_CAPTURE = "android.permission.MANAGE_CONTENT_CAPTURE";
@@ -273,6 +274,7 @@
     field public static final String SIGNAL_REBOOT_READINESS = "android.permission.SIGNAL_REBOOT_READINESS";
     field public static final String SOUND_TRIGGER_RUN_IN_BATTERY_SAVER = "android.permission.SOUND_TRIGGER_RUN_IN_BATTERY_SAVER";
     field public static final String START_ACTIVITIES_FROM_BACKGROUND = "android.permission.START_ACTIVITIES_FROM_BACKGROUND";
+    field public static final String START_CROSS_PROFILE_ACTIVITIES = "android.permission.START_CROSS_PROFILE_ACTIVITIES";
     field public static final String STATUS_BAR_SERVICE = "android.permission.STATUS_BAR_SERVICE";
     field public static final String STOP_APP_SWITCHES = "android.permission.STOP_APP_SWITCHES";
     field public static final String SUBSTITUTE_NOTIFICATION_APP_NAME = "android.permission.SUBSTITUTE_NOTIFICATION_APP_NAME";
@@ -314,6 +316,7 @@
 
   public static final class R.array {
     field public static final int config_keySystemUuidMapping = 17235973; // 0x1070005
+    field public static final int config_optionalIpSecAlgorithms;
   }
 
   public static final class R.attr {
@@ -1848,6 +1851,8 @@
   }
 
   public class NetworkStatsManager {
+    method @NonNull @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public android.net.NetworkStats getMobileUidStats();
+    method @NonNull @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public android.net.NetworkStats getWifiUidStats();
     method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STATS_PROVIDER, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void registerNetworkStatsProvider(@NonNull String, @NonNull android.net.netstats.provider.NetworkStatsProvider);
     method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STATS_PROVIDER, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void unregisterNetworkStatsProvider(@NonNull android.net.netstats.provider.NetworkStatsProvider);
   }
@@ -2013,6 +2018,7 @@
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean isEncrypted();
     method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean isInSilenceMode();
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean removeBond();
+    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setLowLatencyAudioAllowed(boolean);
     method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setMessageAccessPermission(int);
     method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setMetadata(int, @NonNull byte[]);
     method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setPhonebookAccessPermission(int);
@@ -2022,9 +2028,11 @@
     field public static final int ACCESS_REJECTED = 2; // 0x2
     field public static final int ACCESS_UNKNOWN = 0; // 0x0
     field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_SILENCE_MODE_CHANGED = "android.bluetooth.device.action.SILENCE_MODE_CHANGED";
+    field @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public static final String ACTION_SWITCH_BUFFER_SIZE = "android.bluetooth.device.action.SWITCH_BUFFER_SIZE";
     field public static final String DEVICE_TYPE_DEFAULT = "Default";
     field public static final String DEVICE_TYPE_UNTETHERED_HEADSET = "Untethered Headset";
     field public static final String DEVICE_TYPE_WATCH = "Watch";
+    field public static final String EXTRA_LOW_LATENCY_BUFFER_SIZE = "android.bluetooth.device.extra.LOW_LATENCY_BUFFER_SIZE";
     field public static final int METADATA_COMPANION_APP = 4; // 0x4
     field public static final int METADATA_DEVICE_TYPE = 17; // 0x11
     field public static final int METADATA_ENHANCED_SETTINGS_UI_URI = 16; // 0x10
@@ -2062,6 +2070,15 @@
     method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.MODIFY_PHONE_STATE}) public boolean stopScoUsingVirtualVoiceCall();
   }
 
+  public final class BluetoothHeadsetClient implements java.lang.AutoCloseable android.bluetooth.BluetoothProfile {
+    method @NonNull @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices();
+    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice);
+    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getConnectionState(@NonNull android.bluetooth.BluetoothDevice);
+    method @NonNull @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public java.util.List<android.bluetooth.BluetoothDevice> getDevicesMatchingConnectionStates(@NonNull int[]);
+    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int);
+    field @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.headsetprofile.action.CONNECTION_STATE_CHANGED";
+  }
+
   public final class BluetoothHearingAid implements android.bluetooth.BluetoothProfile {
     method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice);
     method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public long getHiSyncId(@NonNull android.bluetooth.BluetoothDevice);
@@ -2080,6 +2097,10 @@
     field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.input.profile.action.CONNECTION_STATE_CHANGED";
   }
 
+  public final class BluetoothLeAudio implements java.lang.AutoCloseable android.bluetooth.BluetoothProfile {
+    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getAudioLocation(@NonNull android.bluetooth.BluetoothDevice);
+  }
+
   public final class BluetoothMap implements java.lang.AutoCloseable android.bluetooth.BluetoothProfile {
     method public void close();
     method protected void finalize();
@@ -2089,15 +2110,21 @@
     field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.map.profile.action.CONNECTION_STATE_CHANGED";
   }
 
-  public final class BluetoothMapClient implements android.bluetooth.BluetoothProfile {
+  public final class BluetoothMapClient implements java.lang.AutoCloseable android.bluetooth.BluetoothProfile {
+    method @NonNull @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices();
+    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice);
+    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getConnectionState(@NonNull android.bluetooth.BluetoothDevice);
+    method @NonNull @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public java.util.List<android.bluetooth.BluetoothDevice> getDevicesMatchingConnectionStates(@NonNull int[]);
     method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.SEND_SMS}) public boolean sendMessage(@NonNull android.bluetooth.BluetoothDevice, @NonNull java.util.Collection<android.net.Uri>, @NonNull String, @Nullable android.app.PendingIntent, @Nullable android.app.PendingIntent);
+    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int);
+    field @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.mapmce.profile.action.CONNECTION_STATE_CHANGED";
   }
 
   public final class BluetoothPan implements android.bluetooth.BluetoothProfile {
     method @NonNull @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices();
     method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getConnectionState(@NonNull android.bluetooth.BluetoothDevice);
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean isTetheringOn();
-    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED, android.Manifest.permission.TETHER_PRIVILEGED}) public void setBluetoothTethering(boolean);
+    method @Deprecated @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED, android.Manifest.permission.TETHER_PRIVILEGED}) public void setBluetoothTethering(boolean);
     method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int);
     field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.pan.profile.action.CONNECTION_STATE_CHANGED";
     field public static final String ACTION_TETHERING_STATE_CHANGED = "android.bluetooth.action.TETHERING_STATE_CHANGED";
@@ -2118,6 +2145,15 @@
     field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.pbap.profile.action.CONNECTION_STATE_CHANGED";
   }
 
+  public final class BluetoothPbapClient implements java.lang.AutoCloseable android.bluetooth.BluetoothProfile {
+    method @NonNull @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices();
+    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice);
+    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getConnectionState(@NonNull android.bluetooth.BluetoothDevice);
+    method @NonNull @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public java.util.List<android.bluetooth.BluetoothDevice> getDevicesMatchingConnectionStates(@NonNull int[]);
+    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int);
+    field @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.pbapclient.profile.action.CONNECTION_STATE_CHANGED";
+  }
+
   public interface BluetoothProfile {
     field public static final int A2DP_SINK = 11; // 0xb
     field public static final int AVRCP_CONTROLLER = 12; // 0xc
@@ -2151,6 +2187,7 @@
     field @NonNull public static final android.os.ParcelUuid COORDINATED_SET;
     field @NonNull public static final android.os.ParcelUuid DIP;
     field @NonNull public static final android.os.ParcelUuid GENERIC_MEDIA_CONTROL;
+    field @NonNull public static final android.os.ParcelUuid HAS;
     field @NonNull public static final android.os.ParcelUuid HEARING_AID;
     field @NonNull public static final android.os.ParcelUuid HFP;
     field @NonNull public static final android.os.ParcelUuid HFP_AG;
@@ -5880,6 +5917,7 @@
 
   public static final class TvInputManager.Hardware {
     method public void overrideAudioSink(int, String, int, int, int);
+    method public void overrideAudioSink(@NonNull android.media.AudioDeviceInfo, @IntRange(from=0) int, int, int);
     method public void setStreamVolume(float);
     method public boolean setSurface(android.view.Surface, android.media.tv.TvStreamConfig);
   }
@@ -7520,11 +7558,12 @@
     field public static final String PERMISSION_MAINLINE_NETWORK_STACK = "android.permission.MAINLINE_NETWORK_STACK";
   }
 
-  public final class NetworkStats implements android.os.Parcelable {
+  public final class NetworkStats implements java.lang.Iterable<android.net.NetworkStats.Entry> android.os.Parcelable {
     ctor public NetworkStats(long, int);
     method @NonNull public android.net.NetworkStats add(@NonNull android.net.NetworkStats);
     method @NonNull public android.net.NetworkStats addEntry(@NonNull android.net.NetworkStats.Entry);
     method public int describeContents();
+    method @NonNull public java.util.Iterator<android.net.NetworkStats.Entry> iterator();
     method @NonNull public android.net.NetworkStats subtract(@NonNull android.net.NetworkStats);
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkStats> CREATOR;
@@ -7548,6 +7587,17 @@
 
   public static class NetworkStats.Entry {
     ctor public NetworkStats.Entry(@Nullable String, int, int, int, int, int, int, long, long, long, long, long);
+    method public int getDefaultNetwork();
+    method public int getMetered();
+    method public long getOperations();
+    method public int getRoaming();
+    method public long getRxBytes();
+    method public long getRxPackets();
+    method public int getSet();
+    method public int getTag();
+    method public long getTxBytes();
+    method public long getTxPackets();
+    method public int getUid();
   }
 
   public class RssiCurve implements android.os.Parcelable {
@@ -7584,6 +7634,7 @@
   public class TrafficStats {
     method public static void setThreadStatsTagApp();
     method public static void setThreadStatsTagBackup();
+    method public static void setThreadStatsTagDownload();
     method public static void setThreadStatsTagRestore();
     field public static final int TAG_NETWORK_STACK_IMPERSONATION_RANGE_END = -113; // 0xffffff8f
     field public static final int TAG_NETWORK_STACK_IMPERSONATION_RANGE_START = -128; // 0xffffff80
@@ -8506,6 +8557,7 @@
     field public static final int EVENT_UNSPECIFIED = 0; // 0x0
     field public static final int REASON_ACCOUNT_TRANSFER = 104; // 0x68
     field public static final int REASON_ACTIVITY_RECOGNITION = 103; // 0x67
+    field public static final int REASON_BLUETOOTH_BROADCAST = 203; // 0xcb
     field public static final int REASON_GEOFENCING = 100; // 0x64
     field public static final int REASON_LOCATION_PROVIDER = 312; // 0x138
     field public static final int REASON_OTHER = 1; // 0x1
@@ -12309,6 +12361,7 @@
   }
 
   public static class TelephonyManager.ModemActivityInfoException extends java.lang.Exception {
+    ctor public TelephonyManager.ModemActivityInfoException(int);
     method public int getErrorCode();
     field public static final int ERROR_INVALID_INFO_RECEIVED = 2; // 0x2
     field public static final int ERROR_MODEM_RESPONSE_ERROR = 3; // 0x3
@@ -13675,6 +13728,7 @@
     field public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_3G = 6; // 0x6
     field public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_EHRPD = 4; // 0x4
     field public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_HSPAPLUS = 5; // 0x5
+    field public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_INTERNET_PDN = 12; // 0xc
     field public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_IWLAN = 9; // 0x9
     field public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_LTE_VOPS_DISABLED = 2; // 0x2
     field public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_LTE_VOPS_ENABLED = 3; // 0x3
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 3b0a5f3..6d7835f 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -97,6 +97,7 @@
 import android.media.MediaServiceManager;
 import android.net.ConnectivityManager;
 import android.net.Proxy;
+import android.net.TrafficStats;
 import android.net.Uri;
 import android.os.AsyncTask;
 import android.os.Binder;
@@ -6663,6 +6664,13 @@
         NetworkSecurityConfigProvider.install(appContext);
         Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
 
+        // For backward compatibility, TrafficStats needs static access to the application context.
+        // But for isolated apps which cannot access network related services, service discovery
+        // is restricted. Hence, calling this would result in NPE.
+        if (!Process.isIsolated()) {
+            TrafficStats.init(appContext);
+        }
+
         // Continue loading instrumentation.
         if (ii != null) {
             initInstrumentation(ii, data, appContext);
diff --git a/core/java/android/app/ActivityTransitionState.java b/core/java/android/app/ActivityTransitionState.java
index 6261950..877e7d3 100644
--- a/core/java/android/app/ActivityTransitionState.java
+++ b/core/java/android/app/ActivityTransitionState.java
@@ -119,7 +119,7 @@
         for (int i = mExitTransitionCoordinators.size() - 1; i >= 0; i--) {
             WeakReference<ExitTransitionCoordinator> oldRef
                     = mExitTransitionCoordinators.valueAt(i);
-            if (oldRef.get() == null) {
+            if (oldRef.refersTo(null)) {
                 mExitTransitionCoordinators.removeAt(i);
             }
         }
diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java
index 198c33e..ab82398 100644
--- a/core/java/android/app/ResourcesManager.java
+++ b/core/java/android/app/ResourcesManager.java
@@ -678,8 +678,7 @@
         int refCount = mResourceImpls.size();
         for (int i = 0; i < refCount; i++) {
             WeakReference<ResourcesImpl> weakImplRef = mResourceImpls.valueAt(i);
-            ResourcesImpl impl = weakImplRef != null ? weakImplRef.get() : null;
-            if (resourceImpl == impl) {
+            if (weakImplRef != null && weakImplRef.refersTo(resourceImpl)) {
                 return mResourceImpls.keyAt(i);
             }
         }
@@ -1671,7 +1670,7 @@
                 for (int i = mResourceImpls.size() - 1; i >= 0; i--) {
                     final ResourcesKey key = mResourceImpls.keyAt(i);
                     final WeakReference<ResourcesImpl> impl = mResourceImpls.valueAt(i);
-                    if (impl == null || impl.get() == null
+                    if (impl == null || impl.refersTo(null)
                             || !ArrayUtils.contains(key.mLoaders, loader)) {
                         continue;
                     }
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 0fe80c4..3840f76 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -10177,6 +10177,9 @@
      * On fully-managed devices this method is unsupported because all traffic is considered
      * work traffic.
      *
+     * <p> This method enables preferential network service with a default configuration.
+     * To fine-tune the configuration, use {@link #setPreferentialNetworkServiceConfig) instead.
+     *
      * <p>This method can only be called by the profile owner of a managed profile.
      * @param enabled whether preferential network service should be enabled.
      * @throws SecurityException if the caller is not the profile owner.
@@ -10215,6 +10218,56 @@
     }
 
     /**
+     * Sets preferential network configuration on the work profile.
+     * {@see PreferentialNetworkServiceConfig}
+     *
+     * An example of a supported preferential network service is the Enterprise
+     * slice on 5G networks.
+     *
+     * By default, preferential network service is disabled on the work profile on supported
+     * carriers and devices. Admins can explicitly enable it with this API.
+     * On fully-managed devices this method is unsupported because all traffic is considered
+     * work traffic.
+     *
+     * <p>This method can only be called by the profile owner of a managed profile.
+     * @param preferentialNetworkServiceConfig preferential network configuration.
+     * @throws SecurityException if the caller is not the profile owner.
+     **/
+    public void setPreferentialNetworkServiceConfig(
+            @NonNull PreferentialNetworkServiceConfig preferentialNetworkServiceConfig) {
+        throwIfParentInstance("setPreferentialNetworkServiceConfig");
+        if (mService == null) {
+            return;
+        }
+        try {
+            mService.setPreferentialNetworkServiceConfig(preferentialNetworkServiceConfig);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Get preferential network configuration
+     * {@see PreferentialNetworkServiceConfig}
+     *
+     * <p>This method can be called by the profile owner of a managed profile.
+     *
+     * @return preferential network configuration.
+     * @throws SecurityException if the caller is not the profile owner.
+     */
+    public @NonNull PreferentialNetworkServiceConfig getPreferentialNetworkServiceConfig() {
+        throwIfParentInstance("getPreferentialNetworkServiceConfig");
+        if (mService == null) {
+            return PreferentialNetworkServiceConfig.DEFAULT;
+        }
+        try {
+            return mService.getPreferentialNetworkServiceConfig();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * This method is mostly deprecated.
      * Most of the settings that still have an effect have dedicated setter methods or user
      * restrictions. See individual settings for details.
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index d287437..c78a5a0 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -21,6 +21,7 @@
 import android.app.IApplicationThread;
 import android.app.IServiceConnection;
 import android.app.admin.ParcelableGranteeMap;
+import android.app.admin.PreferentialNetworkServiceConfig;
 import android.app.admin.StartInstallingUpdateCallback;
 import android.app.admin.SystemUpdateInfo;
 import android.app.admin.SystemUpdatePolicy;
@@ -278,6 +279,10 @@
     void setPreferentialNetworkServiceEnabled(in boolean enabled);
     boolean isPreferentialNetworkServiceEnabled(int userHandle);
 
+    void setPreferentialNetworkServiceConfig(
+            in PreferentialNetworkServiceConfig preferentialNetworkServiceConfig);
+    PreferentialNetworkServiceConfig getPreferentialNetworkServiceConfig();
+
     void setLockTaskPackages(in ComponentName who, in String[] packages);
     String[] getLockTaskPackages(in ComponentName who);
     boolean isLockTaskPermitted(in String pkg);
diff --git a/core/java/android/app/admin/PreferentialNetworkServiceConfig.aidl b/core/java/android/app/admin/PreferentialNetworkServiceConfig.aidl
new file mode 100644
index 0000000..6b6ee7d
--- /dev/null
+++ b/core/java/android/app/admin/PreferentialNetworkServiceConfig.aidl
@@ -0,0 +1,20 @@
+/*
+**
+** Copyright 2022, 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.app.admin;
+
+parcelable PreferentialNetworkServiceConfig;
\ No newline at end of file
diff --git a/core/java/android/app/admin/PreferentialNetworkServiceConfig.java b/core/java/android/app/admin/PreferentialNetworkServiceConfig.java
new file mode 100644
index 0000000..2849139
--- /dev/null
+++ b/core/java/android/app/admin/PreferentialNetworkServiceConfig.java
@@ -0,0 +1,335 @@
+/*
+ * Copyright (C) 2022 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.app.admin;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.SuppressLint;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
+
+/**
+ * Network configuration to be set for the user profile
+ * {@see DevicePolicyManager#setPreferentialNetworkServiceConfig}.
+ */
+public final class PreferentialNetworkServiceConfig implements Parcelable {
+    final boolean mIsEnabled;
+    final int mNetworkId;
+    final boolean mAllowFallbackToDefaultConnection;
+    final int[] mIncludedUids;
+    final int[] mExcludedUids;
+
+    /** @hide */
+    public static final PreferentialNetworkServiceConfig DEFAULT =
+            (new PreferentialNetworkServiceConfig.Builder()).build();
+
+    /**
+     * Preferential network identifier 1.
+     */
+    public static final int PREFERENTIAL_NETWORK_ID_1 = 1;
+
+    /**
+     * Preferential network identifier 2.
+     */
+    public static final int PREFERENTIAL_NETWORK_ID_2 = 2;
+
+    /**
+     * Preferential network identifier 3.
+     */
+    public static final int PREFERENTIAL_NETWORK_ID_3 = 3;
+
+    /**
+     * Preferential network identifier 4.
+     */
+    public static final int PREFERENTIAL_NETWORK_ID_4 = 4;
+
+    /**
+     * Preferential network identifier 5.
+     */
+    public static final int PREFERENTIAL_NETWORK_ID_5 = 5;
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = { "PREFERENTIAL_NETWORK_ID_" }, value = {
+            PREFERENTIAL_NETWORK_ID_1,
+            PREFERENTIAL_NETWORK_ID_2,
+            PREFERENTIAL_NETWORK_ID_3,
+            PREFERENTIAL_NETWORK_ID_4,
+            PREFERENTIAL_NETWORK_ID_5,
+    })
+
+    public @interface PreferentialNetworkPreferenceId {
+    }
+
+    private PreferentialNetworkServiceConfig(boolean isEnabled,
+            boolean allowFallbackToDefaultConnection, int[] includedUids,
+            int[] excludedUids, @PreferentialNetworkPreferenceId int networkId) {
+        mIsEnabled = isEnabled;
+        mAllowFallbackToDefaultConnection = allowFallbackToDefaultConnection;
+        mIncludedUids = includedUids;
+        mExcludedUids = excludedUids;
+        mNetworkId = networkId;
+    }
+
+    private PreferentialNetworkServiceConfig(Parcel in) {
+        mIsEnabled = in.readBoolean();
+        mAllowFallbackToDefaultConnection = in.readBoolean();
+        mNetworkId = in.readInt();
+        mIncludedUids = in.createIntArray();
+        mExcludedUids = in.createIntArray();
+    }
+
+    /**
+     * Is the preferential network enabled.
+     * @return true if enabled else false
+     */
+    public boolean isEnabled() {
+        return mIsEnabled;
+    }
+
+    /**
+     * is fallback to default network allowed. This boolean configures whether default connection
+     * (default internet or wifi) should be used or not if a preferential network service
+     * connection is not available.
+     * @return true if fallback is allowed, else false.
+     */
+    public boolean isFallbackToDefaultConnectionAllowed() {
+        return mAllowFallbackToDefaultConnection;
+    }
+
+    /**
+     * Get the array of uids that are applicable for the profile preference.
+     *
+     * {@see #getExcludedUids()}
+     * Included UIDs and Excluded UIDs can't both be non-empty.
+     * if both are empty, it means this request applies to all uids in the user profile.
+     * if included is not empty, then only included UIDs are applied.
+     * if excluded is not empty, then it is all uids in the user profile except these UIDs.
+     * @return Array of uids applicable for the profile preference.
+     *      Empty array would mean that this request applies to all uids in the profile.
+     */
+    public @NonNull int[] getIncludedUids() {
+        return mIncludedUids;
+    }
+
+    /**
+     * Get the array of uids that are excluded for the profile preference.
+     *
+     * {@see #getIncludedUids()}
+     * Included UIDs and Excluded UIDs can't both be non-empty.
+     * if both are empty, it means this request applies to all uids in the user profile.
+     * if included is not empty, then only included UIDs are applied.
+     * if excluded is not empty, then it is all uids in the user profile except these UIDs.
+     * @return Array of uids that are excluded for the profile preference.
+     *      Empty array would mean that this request applies to all uids in the profile.
+     */
+    public @NonNull int[] getExcludedUids() {
+        return mExcludedUids;
+    }
+
+    /**
+     * @return preference enterprise identifier.
+     * valid values starts from
+     * {@link #PREFERENTIAL_NETWORK_ID_1} to {@link #PREFERENTIAL_NETWORK_ID_5}.
+     * preference identifier is applicable only if preference network service is enabled
+     *
+     */
+    public @PreferentialNetworkPreferenceId int getNetworkId() {
+        return mNetworkId;
+    }
+
+    @Override
+    public String toString() {
+        return "PreferentialNetworkServiceConfig{"
+                + "mIsEnabled=" + isEnabled()
+                + "mAllowFallbackToDefaultConnection=" + isFallbackToDefaultConnectionAllowed()
+                + "mIncludedUids=" + mIncludedUids.toString()
+                + "mExcludedUids=" + mExcludedUids.toString()
+                + "mNetworkId=" + mNetworkId
+                + '}';
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        final PreferentialNetworkServiceConfig that = (PreferentialNetworkServiceConfig) o;
+        return mIsEnabled == that.mIsEnabled
+                && mAllowFallbackToDefaultConnection == that.mAllowFallbackToDefaultConnection
+                && mNetworkId == that.mNetworkId
+                && Objects.equals(mIncludedUids, that.mIncludedUids)
+                && Objects.equals(mExcludedUids, that.mExcludedUids);
+    }
+
+    @Override
+    public int hashCode() {
+        return ((Objects.hashCode(mIsEnabled) * 17)
+                + (Objects.hashCode(mAllowFallbackToDefaultConnection) * 19)
+                + (Objects.hashCode(mIncludedUids) * 23)
+                + (Objects.hashCode(mExcludedUids) * 29)
+                + mNetworkId * 31);
+    }
+
+    /**
+     * Builder used to create {@link PreferentialNetworkServiceConfig} objects.
+     * Specify the preferred Network preference
+     */
+    public static final class Builder {
+        boolean mIsEnabled = false;
+        int mNetworkId = 0;
+        boolean mAllowFallbackToDefaultConnection = true;
+        int[] mIncludedUids = new int[0];
+        int[] mExcludedUids = new int[0];
+
+        /**
+         * Constructs an empty Builder with preferential network disabled by default.
+         */
+        public Builder() {}
+
+        /**
+         * Set the preferential network service enabled state.
+         * Default value is false.
+         * @param isEnabled  the desired network preference to use, true to enable else false
+         * @return The builder to facilitate chaining.
+         */
+        @NonNull
+        public PreferentialNetworkServiceConfig.Builder setEnabled(boolean isEnabled) {
+            mIsEnabled = isEnabled;
+            return this;
+        }
+
+        /**
+         * Set whether the default connection should be used as fallback.
+         * This boolean configures whether the default connection (default internet or wifi)
+         * should be used if a preferential network service connection is not available.
+         * Default value is true
+         * @param allowFallbackToDefaultConnection  true if fallback is allowed else false
+         * @return The builder to facilitate chaining.
+         */
+        @NonNull
+        @SuppressLint("MissingGetterMatchingBuilder")
+        public PreferentialNetworkServiceConfig.Builder setFallbackToDefaultConnectionAllowed(
+                boolean allowFallbackToDefaultConnection) {
+            mAllowFallbackToDefaultConnection = allowFallbackToDefaultConnection;
+            return this;
+        }
+
+        /**
+         * Set the array of uids whose network access will go through this preferential
+         * network service.
+         * {@see #setExcludedUids(int[])}
+         * Included UIDs and Excluded UIDs can't both be non-empty.
+         * if both are empty, it means this request applies to all uids in the user profile.
+         * if included is not empty, then only included UIDs are applied.
+         * if excluded is not empty, then it is all uids in the user profile except these UIDs.
+         * @param uids  array of included uids
+         * @return The builder to facilitate chaining.
+         */
+        @NonNull
+        public PreferentialNetworkServiceConfig.Builder setIncludedUids(
+                @NonNull int[] uids) {
+            Objects.requireNonNull(uids);
+            mIncludedUids = uids;
+            return this;
+        }
+
+        /**
+         * Set the array of uids who are not allowed through this preferential
+         * network service.
+         * {@see #setIncludedUids(int[])}
+         * Included UIDs and Excluded UIDs can't both be non-empty.
+         * if both are empty, it means this request applies to all uids in the user profile.
+         * if included is not empty, then only included UIDs are applied.
+         * if excluded is not empty, then it is all uids in the user profile except these UIDs.
+         * @param uids  array of excluded uids
+         * @return The builder to facilitate chaining.
+         */
+        @NonNull
+        public PreferentialNetworkServiceConfig.Builder setExcludedUids(
+                @NonNull int[] uids) {
+            Objects.requireNonNull(uids);
+            mExcludedUids = uids;
+            return this;
+        }
+
+        /**
+         * Returns an instance of {@link PreferentialNetworkServiceConfig} created from the
+         * fields set on this builder.
+         */
+        @NonNull
+        public PreferentialNetworkServiceConfig build() {
+            if (mIncludedUids.length > 0 && mExcludedUids.length > 0) {
+                throw new IllegalStateException("Both includedUids and excludedUids "
+                        + "cannot be nonempty");
+            }
+            return new PreferentialNetworkServiceConfig(mIsEnabled,
+                    mAllowFallbackToDefaultConnection, mIncludedUids, mExcludedUids, mNetworkId);
+        }
+
+        /**
+         * Set the preferential network identifier.
+         * Valid values starts from {@link #PREFERENTIAL_NETWORK_ID_1} to
+         * {@link #PREFERENTIAL_NETWORK_ID_5}.
+         * preference identifier is applicable only if preferential network service is enabled.
+         * @param preferenceId  preference Id
+         * @return The builder to facilitate chaining.
+         */
+        @NonNull
+        public PreferentialNetworkServiceConfig.Builder setNetworkId(
+                @PreferentialNetworkPreferenceId int preferenceId) {
+            if ((preferenceId < PREFERENTIAL_NETWORK_ID_1)
+                    || (preferenceId > PREFERENTIAL_NETWORK_ID_5)) {
+                throw new IllegalArgumentException("Invalid preference identifier");
+            }
+            mNetworkId = preferenceId;
+            return this;
+        }
+    }
+
+    @Override
+    public void writeToParcel(@NonNull android.os.Parcel dest, int flags) {
+        dest.writeBoolean(mIsEnabled);
+        dest.writeBoolean(mAllowFallbackToDefaultConnection);
+        dest.writeInt(mNetworkId);
+        dest.writeIntArray(mIncludedUids);
+        dest.writeIntArray(mExcludedUids);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @NonNull
+    public static final Creator<PreferentialNetworkServiceConfig> CREATOR =
+            new Creator<PreferentialNetworkServiceConfig>() {
+                @Override
+                public PreferentialNetworkServiceConfig[] newArray(int size) {
+                    return new PreferentialNetworkServiceConfig[size];
+                }
+
+                @Override
+                public PreferentialNetworkServiceConfig createFromParcel(
+                        @NonNull android.os.Parcel in) {
+                    return new PreferentialNetworkServiceConfig(in);
+                }
+            };
+}
diff --git a/core/java/android/app/trust/OWNERS b/core/java/android/app/trust/OWNERS
new file mode 100644
index 0000000..e2c6ce1
--- /dev/null
+++ b/core/java/android/app/trust/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/service/trust/OWNERS
diff --git a/core/java/android/app/wallpapereffectsgeneration/OWNERS b/core/java/android/app/wallpapereffectsgeneration/OWNERS
new file mode 100644
index 0000000..2bc0154
--- /dev/null
+++ b/core/java/android/app/wallpapereffectsgeneration/OWNERS
@@ -0,0 +1,5 @@
+susharon@google.com
+shanh@google.com
+huiwu@google.com
+srazdan@google.com
+
diff --git a/core/java/android/bluetooth/Attributable.java b/core/java/android/bluetooth/Attributable.java
deleted file mode 100644
index d9acbe3..0000000
--- a/core/java/android/bluetooth/Attributable.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.AttributionSource;
-
-import java.util.List;
-
-/**
- * Marker interface for a class which can have an {@link AttributionSource}
- * assigned to it; these are typically {@link android.os.Parcelable} classes
- * which need to be updated after crossing Binder transaction boundaries.
- *
- * @hide
- */
-public interface Attributable {
-    void setAttributionSource(@NonNull AttributionSource attributionSource);
-
-    static @Nullable <T extends Attributable> T setAttributionSource(
-            @Nullable T attributable,
-            @NonNull AttributionSource attributionSource) {
-        if (attributable != null) {
-            attributable.setAttributionSource(attributionSource);
-        }
-        return attributable;
-    }
-
-    static @Nullable <T extends Attributable> List<T> setAttributionSource(
-            @Nullable List<T> attributableList,
-            @NonNull AttributionSource attributionSource) {
-        if (attributableList != null) {
-            final int size = attributableList.size();
-            for (int i = 0; i < size; i++) {
-                setAttributionSource(attributableList.get(i), attributionSource);
-            }
-        }
-        return attributableList;
-    }
-}
diff --git a/core/java/android/bluetooth/BluetoothA2dp.java b/core/java/android/bluetooth/BluetoothA2dp.java
deleted file mode 100644
index 8b9cec1..0000000
--- a/core/java/android/bluetooth/BluetoothA2dp.java
+++ /dev/null
@@ -1,1149 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-import static android.bluetooth.BluetoothUtils.getSyncTimeout;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.RequiresNoPermission;
-import android.annotation.RequiresPermission;
-import android.annotation.SdkConstant;
-import android.annotation.SdkConstant.SdkConstantType;
-import android.annotation.SystemApi;
-import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
-import android.bluetooth.annotations.RequiresLegacyBluetoothAdminPermission;
-import android.bluetooth.annotations.RequiresLegacyBluetoothPermission;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.content.AttributionSource;
-import android.content.Context;
-import android.os.Build;
-import android.os.IBinder;
-import android.os.ParcelUuid;
-import android.os.RemoteException;
-import android.util.Log;
-
-import com.android.modules.utils.SynchronousResultReceiver;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.TimeoutException;
-
-
-/**
- * This class provides the public APIs to control the Bluetooth A2DP
- * profile.
- *
- * <p>BluetoothA2dp is a proxy object for controlling the Bluetooth A2DP
- * Service via IPC. Use {@link BluetoothAdapter#getProfileProxy} to get
- * the BluetoothA2dp proxy object.
- *
- * <p> Android only supports one connected Bluetooth A2dp device at a time.
- * Each method is protected with its appropriate permission.
- */
-public final class BluetoothA2dp implements BluetoothProfile {
-    private static final String TAG = "BluetoothA2dp";
-    private static final boolean DBG = true;
-    private static final boolean VDBG = false;
-
-    /**
-     * Intent used to broadcast the change in connection state of the A2DP
-     * profile.
-     *
-     * <p>This intent will have 3 extras:
-     * <ul>
-     * <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
-     * <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li>
-     * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
-     * </ul>
-     *
-     * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
-     * {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTING},
-     * {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTING}.
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_CONNECTION_STATE_CHANGED =
-            "android.bluetooth.a2dp.profile.action.CONNECTION_STATE_CHANGED";
-
-    /**
-     * Intent used to broadcast the change in the Playing state of the A2DP
-     * profile.
-     *
-     * <p>This intent will have 3 extras:
-     * <ul>
-     * <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
-     * <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile. </li>
-     * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
-     * </ul>
-     *
-     * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
-     * {@link #STATE_PLAYING}, {@link #STATE_NOT_PLAYING},
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_PLAYING_STATE_CHANGED =
-            "android.bluetooth.a2dp.profile.action.PLAYING_STATE_CHANGED";
-
-    /** @hide */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_AVRCP_CONNECTION_STATE_CHANGED =
-            "android.bluetooth.a2dp.profile.action.AVRCP_CONNECTION_STATE_CHANGED";
-
-    /**
-     * Intent used to broadcast the selection of a connected device as active.
-     *
-     * <p>This intent will have one extra:
-     * <ul>
-     * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. It can
-     * be null if no device is active. </li>
-     * </ul>
-     *
-     * @hide
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    @UnsupportedAppUsage(trackingBug = 171933273)
-    public static final String ACTION_ACTIVE_DEVICE_CHANGED =
-            "android.bluetooth.a2dp.profile.action.ACTIVE_DEVICE_CHANGED";
-
-    /**
-     * Intent used to broadcast the change in the Audio Codec state of the
-     * A2DP Source profile.
-     *
-     * <p>This intent will have 2 extras:
-     * <ul>
-     * <li> {@link BluetoothCodecStatus#EXTRA_CODEC_STATUS} - The codec status. </li>
-     * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device if the device is currently
-     * connected, otherwise it is not included.</li>
-     * </ul>
-     *
-     * @hide
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    @UnsupportedAppUsage(trackingBug = 181103983)
-    public static final String ACTION_CODEC_CONFIG_CHANGED =
-            "android.bluetooth.a2dp.profile.action.CODEC_CONFIG_CHANGED";
-
-    /**
-     * A2DP sink device is streaming music. This state can be one of
-     * {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} of
-     * {@link #ACTION_PLAYING_STATE_CHANGED} intent.
-     */
-    public static final int STATE_PLAYING = 10;
-
-    /**
-     * A2DP sink device is NOT streaming music. This state can be one of
-     * {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} of
-     * {@link #ACTION_PLAYING_STATE_CHANGED} intent.
-     */
-    public static final int STATE_NOT_PLAYING = 11;
-
-    /** @hide */
-    @IntDef(prefix = "OPTIONAL_CODECS_", value = {
-            OPTIONAL_CODECS_SUPPORT_UNKNOWN,
-            OPTIONAL_CODECS_NOT_SUPPORTED,
-            OPTIONAL_CODECS_SUPPORTED
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface OptionalCodecsSupportStatus {}
-
-    /**
-     * We don't have a stored preference for whether or not the given A2DP sink device supports
-     * optional codecs.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int OPTIONAL_CODECS_SUPPORT_UNKNOWN = -1;
-
-    /**
-     * The given A2DP sink device does not support optional codecs.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int OPTIONAL_CODECS_NOT_SUPPORTED = 0;
-
-    /**
-     * The given A2DP sink device does support optional codecs.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int OPTIONAL_CODECS_SUPPORTED = 1;
-
-    /** @hide */
-    @IntDef(prefix = "OPTIONAL_CODECS_PREF_", value = {
-            OPTIONAL_CODECS_PREF_UNKNOWN,
-            OPTIONAL_CODECS_PREF_DISABLED,
-            OPTIONAL_CODECS_PREF_ENABLED
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface OptionalCodecsPreferenceStatus {}
-
-    /**
-     * We don't have a stored preference for whether optional codecs should be enabled or
-     * disabled for the given A2DP device.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int OPTIONAL_CODECS_PREF_UNKNOWN = -1;
-
-    /**
-     * Optional codecs should be disabled for the given A2DP device.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int OPTIONAL_CODECS_PREF_DISABLED = 0;
-
-    /**
-     * Optional codecs should be enabled for the given A2DP device.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int OPTIONAL_CODECS_PREF_ENABLED = 1;
-
-    /** @hide */
-    @IntDef(prefix = "DYNAMIC_BUFFER_SUPPORT_", value = {
-            DYNAMIC_BUFFER_SUPPORT_NONE,
-            DYNAMIC_BUFFER_SUPPORT_A2DP_OFFLOAD,
-            DYNAMIC_BUFFER_SUPPORT_A2DP_SOFTWARE_ENCODING
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface Type {}
-
-    /**
-     * Indicates the supported type of Dynamic Audio Buffer is not supported.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int DYNAMIC_BUFFER_SUPPORT_NONE = 0;
-
-    /**
-     * Indicates the supported type of Dynamic Audio Buffer is A2DP offload.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int DYNAMIC_BUFFER_SUPPORT_A2DP_OFFLOAD = 1;
-
-    /**
-     * Indicates the supported type of Dynamic Audio Buffer is A2DP software encoding.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int DYNAMIC_BUFFER_SUPPORT_A2DP_SOFTWARE_ENCODING = 2;
-
-    private final BluetoothAdapter mAdapter;
-    private final AttributionSource mAttributionSource;
-    private final BluetoothProfileConnector<IBluetoothA2dp> mProfileConnector =
-            new BluetoothProfileConnector(this, BluetoothProfile.A2DP, "BluetoothA2dp",
-                    IBluetoothA2dp.class.getName()) {
-                @Override
-                public IBluetoothA2dp getServiceInterface(IBinder service) {
-                    return IBluetoothA2dp.Stub.asInterface(service);
-                }
-    };
-
-    /**
-     * Create a BluetoothA2dp proxy object for interacting with the local
-     * Bluetooth A2DP service.
-     */
-    /* package */ BluetoothA2dp(Context context, ServiceListener listener,
-            BluetoothAdapter adapter) {
-        mAdapter = adapter;
-        mAttributionSource = adapter.getAttributionSource();
-        mProfileConnector.connect(context, listener);
-    }
-
-    @UnsupportedAppUsage
-    /*package*/ void close() {
-        mProfileConnector.disconnect();
-    }
-
-    private IBluetoothA2dp getService() {
-        return mProfileConnector.getService();
-    }
-
-    @Override
-    public void finalize() {
-        // The empty finalize needs to be kept or the
-        // cts signature tests would fail.
-    }
-
-    /**
-     * Initiate connection to a profile of the remote Bluetooth device.
-     *
-     * <p> This API returns false in scenarios like the profile on the
-     * device is already connected or Bluetooth is not turned on.
-     * When this API returns true, it is guaranteed that
-     * connection state intent for the profile will be broadcasted with
-     * the state. Users can get the connection state of the profile
-     * from this intent.
-     *
-     *
-     * @param device Remote Bluetooth Device
-     * @return false on immediate error, true otherwise
-     * @hide
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @UnsupportedAppUsage
-    public boolean connect(BluetoothDevice device) {
-        if (DBG) log("connect(" + device + ")");
-        final IBluetoothA2dp service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.connectWithAttribution(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Initiate disconnection from a profile
-     *
-     * <p> This API will return false in scenarios like the profile on the
-     * Bluetooth device is not in connected state etc. When this API returns,
-     * true, it is guaranteed that the connection state change
-     * intent will be broadcasted with the state. Users can get the
-     * disconnection state of the profile from this intent.
-     *
-     * <p> If the disconnection is initiated by a remote device, the state
-     * will transition from {@link #STATE_CONNECTED} to
-     * {@link #STATE_DISCONNECTED}. If the disconnect is initiated by the
-     * host (local) device the state will transition from
-     * {@link #STATE_CONNECTED} to state {@link #STATE_DISCONNECTING} to
-     * state {@link #STATE_DISCONNECTED}. The transition to
-     * {@link #STATE_DISCONNECTING} can be used to distinguish between the
-     * two scenarios.
-     *
-     *
-     * @param device Remote Bluetooth Device
-     * @return false on immediate error, true otherwise
-     * @hide
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @UnsupportedAppUsage
-    public boolean disconnect(BluetoothDevice device) {
-        if (DBG) log("disconnect(" + device + ")");
-        final IBluetoothA2dp service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.disconnectWithAttribution(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public List<BluetoothDevice> getConnectedDevices() {
-        if (VDBG) log("getConnectedDevices()");
-        final IBluetoothA2dp service = getService();
-        final List<BluetoothDevice> defaultValue = new ArrayList<BluetoothDevice>();
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<List<BluetoothDevice>> recv =
-                        new SynchronousResultReceiver();
-                service.getConnectedDevicesWithAttribution(mAttributionSource, recv);
-                return Attributable.setAttributionSource(
-                        recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
-                        mAttributionSource);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
-        if (VDBG) log("getDevicesMatchingStates()");
-        final IBluetoothA2dp service = getService();
-        final List<BluetoothDevice> defaultValue = new ArrayList<BluetoothDevice>();
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<List<BluetoothDevice>> recv =
-                        new SynchronousResultReceiver();
-                service.getDevicesMatchingConnectionStatesWithAttribution(states,
-                        mAttributionSource, recv);
-                return Attributable.setAttributionSource(
-                        recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
-                        mAttributionSource);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public @BtProfileState int getConnectionState(BluetoothDevice device) {
-        if (VDBG) log("getState(" + device + ")");
-        final IBluetoothA2dp service = getService();
-        final int defaultValue = BluetoothProfile.STATE_DISCONNECTED;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
-                service.getConnectionStateWithAttribution(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Select a connected device as active.
-     *
-     * The active device selection is per profile. An active device's
-     * purpose is profile-specific. For example, A2DP audio streaming
-     * is to the active A2DP Sink device. If a remote device is not
-     * connected, it cannot be selected as active.
-     *
-     * <p> This API returns false in scenarios like the profile on the
-     * device is not connected or Bluetooth is not turned on.
-     * When this API returns true, it is guaranteed that the
-     * {@link #ACTION_ACTIVE_DEVICE_CHANGED} intent will be broadcasted
-     * with the active device.
-     *
-     * @param device the remote Bluetooth device. Could be null to clear
-     * the active device and stop streaming audio to a Bluetooth device.
-     * @return false on immediate error, true otherwise
-     * @hide
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @UnsupportedAppUsage(trackingBug = 171933273)
-    public boolean setActiveDevice(@Nullable BluetoothDevice device) {
-        if (DBG) log("setActiveDevice(" + device + ")");
-        final IBluetoothA2dp service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && ((device == null) || isValidDevice(device))) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.setActiveDevice(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Get the connected device that is active.
-     *
-     * @return the connected device that is active or null if no device
-     * is active
-     * @hide
-     */
-    @UnsupportedAppUsage(trackingBug = 171933273)
-    @Nullable
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public BluetoothDevice getActiveDevice() {
-        if (VDBG) log("getActiveDevice()");
-        final IBluetoothA2dp service = getService();
-        final BluetoothDevice defaultValue = null;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<BluetoothDevice> recv =
-                        new SynchronousResultReceiver();
-                service.getActiveDevice(mAttributionSource, recv);
-                return Attributable.setAttributionSource(
-                        recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
-                        mAttributionSource);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Set priority of the profile
-     *
-     * <p> The device should already be paired.
-     * Priority can be one of {@link #PRIORITY_ON} or {@link #PRIORITY_OFF}
-     *
-     * @param device Paired bluetooth device
-     * @param priority
-     * @return true if priority is set, false on error
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public boolean setPriority(BluetoothDevice device, int priority) {
-        if (DBG) log("setPriority(" + device + ", " + priority + ")");
-        return setConnectionPolicy(device, BluetoothAdapter.priorityToConnectionPolicy(priority));
-    }
-
-    /**
-     * Set connection policy of the profile
-     *
-     * <p> The device should already be paired.
-     * Connection policy can be one of {@link #CONNECTION_POLICY_ALLOWED},
-     * {@link #CONNECTION_POLICY_FORBIDDEN}, {@link #CONNECTION_POLICY_UNKNOWN}
-     *
-     * @param device Paired bluetooth device
-     * @param connectionPolicy is the connection policy to set to for this profile
-     * @return true if connectionPolicy is set, false on error
-     * @hide
-     */
-    @SystemApi
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public boolean setConnectionPolicy(@NonNull BluetoothDevice device,
-            @ConnectionPolicy int connectionPolicy) {
-        if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
-        final IBluetoothA2dp service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)
-                    && (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_FORBIDDEN
-                        || connectionPolicy == BluetoothProfile.CONNECTION_POLICY_ALLOWED)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.setConnectionPolicy(device, connectionPolicy, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Get the priority of the profile.
-     *
-     * <p> The priority can be any of:
-     * {@link #PRIORITY_OFF}, {@link #PRIORITY_ON}, {@link #PRIORITY_UNDEFINED}
-     *
-     * @param device Bluetooth device
-     * @return priority of the device
-     * @hide
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
-    public int getPriority(BluetoothDevice device) {
-        if (VDBG) log("getPriority(" + device + ")");
-        return BluetoothAdapter.connectionPolicyToPriority(getConnectionPolicy(device));
-    }
-
-    /**
-     * Get the connection policy of the profile.
-     *
-     * <p> The connection policy can be any of:
-     * {@link #CONNECTION_POLICY_ALLOWED}, {@link #CONNECTION_POLICY_FORBIDDEN},
-     * {@link #CONNECTION_POLICY_UNKNOWN}
-     *
-     * @param device Bluetooth device
-     * @return connection policy of the device
-     * @hide
-     */
-    @SystemApi
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public @ConnectionPolicy int getConnectionPolicy(@NonNull BluetoothDevice device) {
-        if (VDBG) log("getConnectionPolicy(" + device + ")");
-        final IBluetoothA2dp service = getService();
-        final int defaultValue = BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
-                service.getConnectionPolicy(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Checks if Avrcp device supports the absolute volume feature.
-     *
-     * @return true if device supports absolute volume
-     * @hide
-     */
-    @RequiresNoPermission
-    public boolean isAvrcpAbsoluteVolumeSupported() {
-        if (DBG) Log.d(TAG, "isAvrcpAbsoluteVolumeSupported");
-        final IBluetoothA2dp service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.isAvrcpAbsoluteVolumeSupported(recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Tells remote device to set an absolute volume. Only if absolute volume is supported
-     *
-     * @param volume Absolute volume to be set on AVRCP side
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public void setAvrcpAbsoluteVolume(int volume) {
-        if (DBG) Log.d(TAG, "setAvrcpAbsoluteVolume");
-        final IBluetoothA2dp service = getService();
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                service.setAvrcpAbsoluteVolume(volume, mAttributionSource);
-            } catch (RemoteException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-    }
-
-    /**
-     * Check if A2DP profile is streaming music.
-     *
-     * @param device BluetoothDevice device
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean isA2dpPlaying(BluetoothDevice device) {
-        if (DBG) log("isA2dpPlaying(" + device + ")");
-        final IBluetoothA2dp service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.isA2dpPlaying(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * This function checks if the remote device is an AVCRP
-     * target and thus whether we should send volume keys
-     * changes or not.
-     *
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean shouldSendVolumeKeys(BluetoothDevice device) {
-        if (isEnabled() && isValidDevice(device)) {
-            ParcelUuid[] uuids = device.getUuids();
-            if (uuids == null) return false;
-
-            for (ParcelUuid uuid : uuids) {
-                if (uuid.equals(BluetoothUuid.AVRCP_TARGET)) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Gets the current codec status (configuration and capability).
-     *
-     * @param device the remote Bluetooth device.
-     * @return the current codec status
-     * @hide
-     */
-    @UnsupportedAppUsage(trackingBug = 181103983)
-    @Nullable
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public BluetoothCodecStatus getCodecStatus(@NonNull BluetoothDevice device) {
-        if (DBG) Log.d(TAG, "getCodecStatus(" + device + ")");
-        verifyDeviceNotNull(device, "getCodecStatus");
-        final IBluetoothA2dp service = getService();
-        final BluetoothCodecStatus defaultValue = null;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<BluetoothCodecStatus> recv =
-                        new SynchronousResultReceiver();
-                service.getCodecStatus(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Sets the codec configuration preference.
-     *
-     * @param device the remote Bluetooth device.
-     * @param codecConfig the codec configuration preference
-     * @hide
-     */
-    @UnsupportedAppUsage(trackingBug = 181103983)
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public void setCodecConfigPreference(@NonNull BluetoothDevice device,
-                                         @NonNull BluetoothCodecConfig codecConfig) {
-        if (DBG) Log.d(TAG, "setCodecConfigPreference(" + device + ")");
-        verifyDeviceNotNull(device, "setCodecConfigPreference");
-        if (codecConfig == null) {
-            Log.e(TAG, "setCodecConfigPreference: Codec config can't be null");
-            throw new IllegalArgumentException("codecConfig cannot be null");
-        }
-        final IBluetoothA2dp service = getService();
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                service.setCodecConfigPreference(device, codecConfig, mAttributionSource);
-            } catch (RemoteException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-    }
-
-    /**
-     * Enables the optional codecs.
-     *
-     * @param device the remote Bluetooth device.
-     * @hide
-     */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public void enableOptionalCodecs(@NonNull BluetoothDevice device) {
-        if (DBG) Log.d(TAG, "enableOptionalCodecs(" + device + ")");
-        verifyDeviceNotNull(device, "enableOptionalCodecs");
-        enableDisableOptionalCodecs(device, true);
-    }
-
-    /**
-     * Disables the optional codecs.
-     *
-     * @param device the remote Bluetooth device.
-     * @hide
-     */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public void disableOptionalCodecs(@NonNull BluetoothDevice device) {
-        if (DBG) Log.d(TAG, "disableOptionalCodecs(" + device + ")");
-        verifyDeviceNotNull(device, "disableOptionalCodecs");
-        enableDisableOptionalCodecs(device, false);
-    }
-
-    /**
-     * Enables or disables the optional codecs.
-     *
-     * @param device the remote Bluetooth device.
-     * @param enable if true, enable the optional codecs, other disable them
-     */
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    private void enableDisableOptionalCodecs(BluetoothDevice device, boolean enable) {
-        final IBluetoothA2dp service = getService();
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                if (enable) {
-                    service.enableOptionalCodecs(device, mAttributionSource);
-                } else {
-                    service.disableOptionalCodecs(device, mAttributionSource);
-                }
-            } catch (RemoteException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-    }
-
-    /**
-     * Returns whether this device supports optional codecs.
-     *
-     * @param device The device to check
-     * @return one of OPTIONAL_CODECS_SUPPORT_UNKNOWN, OPTIONAL_CODECS_NOT_SUPPORTED, or
-     * OPTIONAL_CODECS_SUPPORTED.
-     * @hide
-     */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @OptionalCodecsSupportStatus
-    public int isOptionalCodecsSupported(@NonNull BluetoothDevice device) {
-        if (DBG) log("isOptionalCodecsSupported(" + device + ")");
-        verifyDeviceNotNull(device, "isOptionalCodecsSupported");
-        final IBluetoothA2dp service = getService();
-        final int defaultValue = OPTIONAL_CODECS_SUPPORT_UNKNOWN;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
-                service.supportsOptionalCodecs(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Returns whether this device should have optional codecs enabled.
-     *
-     * @param device The device in question.
-     * @return one of OPTIONAL_CODECS_PREF_UNKNOWN, OPTIONAL_CODECS_PREF_ENABLED, or
-     * OPTIONAL_CODECS_PREF_DISABLED.
-     * @hide
-     */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @OptionalCodecsPreferenceStatus
-    public int isOptionalCodecsEnabled(@NonNull BluetoothDevice device) {
-        if (DBG) log("isOptionalCodecsEnabled(" + device + ")");
-        verifyDeviceNotNull(device, "isOptionalCodecsEnabled");
-        final IBluetoothA2dp service = getService();
-        final int defaultValue = OPTIONAL_CODECS_PREF_UNKNOWN;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
-                service.getOptionalCodecsEnabled(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Sets a persistent preference for whether a given device should have optional codecs enabled.
-     *
-     * @param device The device to set this preference for.
-     * @param value Whether the optional codecs should be enabled for this device.  This should be
-     * one of OPTIONAL_CODECS_PREF_UNKNOWN, OPTIONAL_CODECS_PREF_ENABLED, or
-     * OPTIONAL_CODECS_PREF_DISABLED.
-     * @hide
-     */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public void setOptionalCodecsEnabled(@NonNull BluetoothDevice device,
-            @OptionalCodecsPreferenceStatus int value) {
-        if (DBG) log("setOptionalCodecsEnabled(" + device + ")");
-        verifyDeviceNotNull(device, "setOptionalCodecsEnabled");
-        if (value != BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN
-                && value != BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED
-                && value != BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED) {
-            Log.e(TAG, "Invalid value passed to setOptionalCodecsEnabled: " + value);
-            return;
-        }
-        final IBluetoothA2dp service = getService();
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                service.setOptionalCodecsEnabled(device, value, mAttributionSource);
-            } catch (RemoteException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-    }
-
-    /**
-     * Get the supported type of the Dynamic Audio Buffer.
-     * <p>Possible return values are
-     * {@link #DYNAMIC_BUFFER_SUPPORT_NONE},
-     * {@link #DYNAMIC_BUFFER_SUPPORT_A2DP_OFFLOAD},
-     * {@link #DYNAMIC_BUFFER_SUPPORT_A2DP_SOFTWARE_ENCODING}.
-     *
-     * @return supported type of Dynamic Audio Buffer feature
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public @Type int getDynamicBufferSupport() {
-        if (VDBG) log("getDynamicBufferSupport()");
-        final IBluetoothA2dp service = getService();
-        final int defaultValue = DYNAMIC_BUFFER_SUPPORT_NONE;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
-                service.getDynamicBufferSupport(mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Return the record of {@link BufferConstraints} object that
-     * has the default/maximum/minimum audio buffer. This can be used to inform what the controller
-     * has support for the audio buffer.
-     *
-     * @return a record with {@link BufferConstraints} or null if report is unavailable
-     * or unsupported
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public @Nullable BufferConstraints getBufferConstraints() {
-        if (VDBG) log("getBufferConstraints()");
-        final IBluetoothA2dp service = getService();
-        final BufferConstraints defaultValue = null;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<BufferConstraints> recv =
-                        new SynchronousResultReceiver();
-                service.getBufferConstraints(mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Set Dynamic Audio Buffer Size.
-     *
-     * @param codec audio codec
-     * @param value buffer millis
-     * @return true to indicate success, or false on immediate error
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public boolean setBufferLengthMillis(@BluetoothCodecConfig.SourceCodecType int codec,
-            int value) {
-        if (VDBG) log("setBufferLengthMillis(" + codec + ", " + value + ")");
-        if (value < 0) {
-            Log.e(TAG, "Trying to set audio buffer length to a negative value: " + value);
-            return false;
-        }
-        final IBluetoothA2dp service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.setBufferLengthMillis(codec, value, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Helper for converting a state to a string.
-     *
-     * For debug use only - strings are not internationalized.
-     *
-     * @hide
-     */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
-    public static String stateToString(int state) {
-        switch (state) {
-            case STATE_DISCONNECTED:
-                return "disconnected";
-            case STATE_CONNECTING:
-                return "connecting";
-            case STATE_CONNECTED:
-                return "connected";
-            case STATE_DISCONNECTING:
-                return "disconnecting";
-            case STATE_PLAYING:
-                return "playing";
-            case STATE_NOT_PLAYING:
-                return "not playing";
-            default:
-                return "<unknown state " + state + ">";
-        }
-    }
-
-    private boolean isEnabled() {
-        if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true;
-        return false;
-    }
-
-    private void verifyDeviceNotNull(BluetoothDevice device, String methodName) {
-        if (device == null) {
-            Log.e(TAG, methodName + ": device param is null");
-            throw new IllegalArgumentException("Device cannot be null");
-        }
-    }
-
-    private boolean isValidDevice(BluetoothDevice device) {
-        if (device == null) return false;
-
-        if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
-        return false;
-    }
-
-    private static void log(String msg) {
-        Log.d(TAG, msg);
-    }
-}
diff --git a/core/java/android/bluetooth/BluetoothA2dpSink.java b/core/java/android/bluetooth/BluetoothA2dpSink.java
deleted file mode 100755
index 5941681..0000000
--- a/core/java/android/bluetooth/BluetoothA2dpSink.java
+++ /dev/null
@@ -1,516 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-import static android.bluetooth.BluetoothUtils.getSyncTimeout;
-
-import android.Manifest;
-import android.annotation.NonNull;
-import android.annotation.RequiresPermission;
-import android.annotation.SdkConstant;
-import android.annotation.SdkConstant.SdkConstantType;
-import android.annotation.SuppressLint;
-import android.annotation.SystemApi;
-import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
-import android.bluetooth.annotations.RequiresLegacyBluetoothAdminPermission;
-import android.bluetooth.annotations.RequiresLegacyBluetoothPermission;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.content.AttributionSource;
-import android.content.Context;
-import android.os.Build;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.util.Log;
-
-import com.android.modules.utils.SynchronousResultReceiver;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.TimeoutException;
-
-/**
- * This class provides the public APIs to control the Bluetooth A2DP Sink
- * profile.
- *
- * <p>BluetoothA2dpSink is a proxy object for controlling the Bluetooth A2DP Sink
- * Service via IPC. Use {@link BluetoothAdapter#getProfileProxy} to get
- * the BluetoothA2dpSink proxy object.
- *
- * @hide
- */
-@SystemApi
-public final class BluetoothA2dpSink implements BluetoothProfile {
-    private static final String TAG = "BluetoothA2dpSink";
-    private static final boolean DBG = true;
-    private static final boolean VDBG = false;
-
-    /**
-     * Intent used to broadcast the change in connection state of the A2DP Sink
-     * profile.
-     *
-     * <p>This intent will have 3 extras:
-     * <ul>
-     * <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
-     * <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li>
-     * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
-     * </ul>
-     *
-     * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
-     * {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTING},
-     * {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTING}.
-     *
-     * @hide
-     */
-    @SystemApi
-    @SuppressLint("ActionValue")
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_CONNECTION_STATE_CHANGED =
-            "android.bluetooth.a2dp-sink.profile.action.CONNECTION_STATE_CHANGED";
-
-    private final BluetoothAdapter mAdapter;
-    private final AttributionSource mAttributionSource;
-    private final BluetoothProfileConnector<IBluetoothA2dpSink> mProfileConnector =
-            new BluetoothProfileConnector(this, BluetoothProfile.A2DP_SINK,
-                    "BluetoothA2dpSink", IBluetoothA2dpSink.class.getName()) {
-                @Override
-                public IBluetoothA2dpSink getServiceInterface(IBinder service) {
-                    return IBluetoothA2dpSink.Stub.asInterface(service);
-                }
-    };
-
-    /**
-     * Create a BluetoothA2dp proxy object for interacting with the local
-     * Bluetooth A2DP service.
-     */
-    /* package */ BluetoothA2dpSink(Context context, ServiceListener listener,
-            BluetoothAdapter adapter) {
-        mAdapter = adapter;
-        mAttributionSource = adapter.getAttributionSource();
-        mProfileConnector.connect(context, listener);
-    }
-
-    /*package*/ void close() {
-        mProfileConnector.disconnect();
-    }
-
-    private IBluetoothA2dpSink getService() {
-        return mProfileConnector.getService();
-    }
-
-    @Override
-    public void finalize() {
-        close();
-    }
-
-    /**
-     * Initiate connection to a profile of the remote bluetooth device.
-     *
-     * <p> Currently, the system supports only 1 connection to the
-     * A2DP profile. The API will automatically disconnect connected
-     * devices before connecting.
-     *
-     * <p> This API returns false in scenarios like the profile on the
-     * device is already connected or Bluetooth is not turned on.
-     * When this API returns true, it is guaranteed that
-     * connection state intent for the profile will be broadcasted with
-     * the state. Users can get the connection state of the profile
-     * from this intent.
-     *
-     * @param device Remote Bluetooth Device
-     * @return false on immediate error, true otherwise
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public boolean connect(BluetoothDevice device) {
-        if (DBG) log("connect(" + device + ")");
-        final IBluetoothA2dpSink service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.connect(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Initiate disconnection from a profile
-     *
-     * <p> This API will return false in scenarios like the profile on the
-     * Bluetooth device is not in connected state etc. When this API returns,
-     * true, it is guaranteed that the connection state change
-     * intent will be broadcasted with the state. Users can get the
-     * disconnection state of the profile from this intent.
-     *
-     * <p> If the disconnection is initiated by a remote device, the state
-     * will transition from {@link #STATE_CONNECTED} to
-     * {@link #STATE_DISCONNECTED}. If the disconnect is initiated by the
-     * host (local) device the state will transition from
-     * {@link #STATE_CONNECTED} to state {@link #STATE_DISCONNECTING} to
-     * state {@link #STATE_DISCONNECTED}. The transition to
-     * {@link #STATE_DISCONNECTING} can be used to distinguish between the
-     * two scenarios.
-     *
-     * @param device Remote Bluetooth Device
-     * @return false on immediate error, true otherwise
-     * @hide
-     */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean disconnect(BluetoothDevice device) {
-        if (DBG) log("disconnect(" + device + ")");
-        final IBluetoothA2dpSink service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.disconnect(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * {@inheritDoc}
-     *
-     * @hide
-     */
-    @Override
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public List<BluetoothDevice> getConnectedDevices() {
-        if (VDBG) log("getConnectedDevices()");
-        final IBluetoothA2dpSink service = getService();
-        final List<BluetoothDevice> defaultValue = new ArrayList<BluetoothDevice>();
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<List<BluetoothDevice>> recv =
-                        new SynchronousResultReceiver();
-                service.getConnectedDevices(mAttributionSource, recv);
-                return Attributable.setAttributionSource(
-                        recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
-                        mAttributionSource);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * {@inheritDoc}
-     *
-     * @hide
-     */
-    @Override
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
-        if (VDBG) log("getDevicesMatchingStates()");
-        final IBluetoothA2dpSink service = getService();
-        final List<BluetoothDevice> defaultValue = new ArrayList<BluetoothDevice>();
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<List<BluetoothDevice>> recv =
-                        new SynchronousResultReceiver();
-                service.getDevicesMatchingConnectionStates(states, mAttributionSource, recv);
-                return Attributable.setAttributionSource(
-                        recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
-                        mAttributionSource);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * {@inheritDoc}
-     *
-     * @hide
-     */
-    @Override
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public int getConnectionState(BluetoothDevice device) {
-        if (VDBG) log("getConnectionState(" + device + ")");
-        final IBluetoothA2dpSink service = getService();
-        final int defaultValue = BluetoothProfile.STATE_DISCONNECTED;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
-                service.getConnectionState(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Get the current audio configuration for the A2DP source device,
-     * or null if the device has no audio configuration
-     *
-     * @param device Remote bluetooth device.
-     * @return audio configuration for the device, or null
-     *
-     * {@see BluetoothAudioConfig}
-     *
-     * @hide
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public BluetoothAudioConfig getAudioConfig(BluetoothDevice device) {
-        if (VDBG) log("getAudioConfig(" + device + ")");
-        final IBluetoothA2dpSink service = getService();
-        final BluetoothAudioConfig defaultValue = null;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<BluetoothAudioConfig> recv =
-                        new SynchronousResultReceiver();
-                service.getAudioConfig(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Set priority of the profile
-     *
-     * <p> The device should already be paired.
-     * Priority can be one of {@link #PRIORITY_ON} or {@link #PRIORITY_OFF}
-     *
-     * @param device Paired bluetooth device
-     * @param priority
-     * @return true if priority is set, false on error
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public boolean setPriority(BluetoothDevice device, int priority) {
-        if (DBG) log("setPriority(" + device + ", " + priority + ")");
-        return setConnectionPolicy(device, BluetoothAdapter.priorityToConnectionPolicy(priority));
-    }
-
-    /**
-     * Set connection policy of the profile
-     *
-     * <p> The device should already be paired.
-     * Connection policy can be one of {@link #CONNECTION_POLICY_ALLOWED},
-     * {@link #CONNECTION_POLICY_FORBIDDEN}, {@link #CONNECTION_POLICY_UNKNOWN}
-     *
-     * @param device Paired bluetooth device
-     * @param connectionPolicy is the connection policy to set to for this profile
-     * @return true if connectionPolicy is set, false on error
-     * @hide
-     */
-    @SystemApi
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED
-    })
-    public boolean setConnectionPolicy(@NonNull BluetoothDevice device,
-            @ConnectionPolicy int connectionPolicy) {
-        if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
-        final IBluetoothA2dpSink service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)
-                && (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_FORBIDDEN
-                    || connectionPolicy == BluetoothProfile.CONNECTION_POLICY_ALLOWED)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.setConnectionPolicy(device, connectionPolicy, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Get the priority of the profile.
-     *
-     * <p> The priority can be any of:
-     * {@link #PRIORITY_OFF}, {@link #PRIORITY_ON}, {@link #PRIORITY_UNDEFINED}
-     *
-     * @param device Bluetooth device
-     * @return priority of the device
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public int getPriority(BluetoothDevice device) {
-        if (VDBG) log("getPriority(" + device + ")");
-        return BluetoothAdapter.connectionPolicyToPriority(getConnectionPolicy(device));
-    }
-
-    /**
-     * Get the connection policy of the profile.
-     *
-     * <p> The connection policy can be any of:
-     * {@link #CONNECTION_POLICY_ALLOWED}, {@link #CONNECTION_POLICY_FORBIDDEN},
-     * {@link #CONNECTION_POLICY_UNKNOWN}
-     *
-     * @param device Bluetooth device
-     * @return connection policy of the device
-     * @hide
-     */
-    @SystemApi
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public @ConnectionPolicy int getConnectionPolicy(@NonNull BluetoothDevice device) {
-        if (VDBG) log("getConnectionPolicy(" + device + ")");
-        final IBluetoothA2dpSink service = getService();
-        final int defaultValue = BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
-                service.getConnectionPolicy(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Check if audio is playing on the bluetooth device (A2DP profile is streaming music).
-     *
-     * @param device BluetoothDevice device
-     * @return true if audio is playing (A2dp is streaming music), false otherwise
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public boolean isAudioPlaying(@NonNull BluetoothDevice device) {
-        if (VDBG) log("isAudioPlaying(" + device + ")");
-        final IBluetoothA2dpSink service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.isA2dpPlaying(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Helper for converting a state to a string.
-     *
-     * For debug use only - strings are not internationalized.
-     *
-     * @hide
-     */
-    public static String stateToString(int state) {
-        switch (state) {
-            case STATE_DISCONNECTED:
-                return "disconnected";
-            case STATE_CONNECTING:
-                return "connecting";
-            case STATE_CONNECTED:
-                return "connected";
-            case STATE_DISCONNECTING:
-                return "disconnecting";
-            case BluetoothA2dp.STATE_PLAYING:
-                return "playing";
-            case BluetoothA2dp.STATE_NOT_PLAYING:
-                return "not playing";
-            default:
-                return "<unknown state " + state + ">";
-        }
-    }
-
-    private boolean isEnabled() {
-        return mAdapter.getState() == BluetoothAdapter.STATE_ON;
-    }
-
-    private static boolean isValidDevice(BluetoothDevice device) {
-        return device != null && BluetoothAdapter.checkBluetoothAddress(device.getAddress());
-    }
-
-    private static void log(String msg) {
-        Log.d(TAG, msg);
-    }
-}
diff --git a/core/java/android/bluetooth/BluetoothActivityEnergyInfo.java b/core/java/android/bluetooth/BluetoothActivityEnergyInfo.java
deleted file mode 100644
index c17a7b4..0000000
--- a/core/java/android/bluetooth/BluetoothActivityEnergyInfo.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-import android.annotation.ElapsedRealtimeLong;
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.SystemApi;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Record of energy and activity information from controller and
- * underlying bt stack state.Timestamp the record with system
- * time.
- *
- * @hide
- */
-@SystemApi(client = SystemApi.Client.PRIVILEGED_APPS)
-public final class BluetoothActivityEnergyInfo implements Parcelable {
-    private final long mTimestamp;
-    private int mBluetoothStackState;
-    private long mControllerTxTimeMs;
-    private long mControllerRxTimeMs;
-    private long mControllerIdleTimeMs;
-    private long mControllerEnergyUsed;
-    private List<UidTraffic> mUidTraffic;
-
-    /** @hide */
-    @IntDef(prefix = { "BT_STACK_STATE_" }, value = {
-            BT_STACK_STATE_INVALID,
-            BT_STACK_STATE_STATE_ACTIVE,
-            BT_STACK_STATE_STATE_SCANNING,
-            BT_STACK_STATE_STATE_IDLE
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface BluetoothStackState {}
-
-    public static final int BT_STACK_STATE_INVALID = 0;
-    public static final int BT_STACK_STATE_STATE_ACTIVE = 1;
-    public static final int BT_STACK_STATE_STATE_SCANNING = 2;
-    public static final int BT_STACK_STATE_STATE_IDLE = 3;
-
-    /** @hide */
-    public BluetoothActivityEnergyInfo(long timestamp, int stackState,
-            long txTime, long rxTime, long idleTime, long energyUsed) {
-        mTimestamp = timestamp;
-        mBluetoothStackState = stackState;
-        mControllerTxTimeMs = txTime;
-        mControllerRxTimeMs = rxTime;
-        mControllerIdleTimeMs = idleTime;
-        mControllerEnergyUsed = energyUsed;
-    }
-
-    /** @hide */
-    private BluetoothActivityEnergyInfo(Parcel in) {
-        mTimestamp = in.readLong();
-        mBluetoothStackState = in.readInt();
-        mControllerTxTimeMs = in.readLong();
-        mControllerRxTimeMs = in.readLong();
-        mControllerIdleTimeMs = in.readLong();
-        mControllerEnergyUsed = in.readLong();
-        mUidTraffic = in.createTypedArrayList(UidTraffic.CREATOR);
-    }
-
-    /** @hide */
-    @Override
-    public String toString() {
-        return "BluetoothActivityEnergyInfo{"
-                + " mTimestamp=" + mTimestamp
-                + " mBluetoothStackState=" + mBluetoothStackState
-                + " mControllerTxTimeMs=" + mControllerTxTimeMs
-                + " mControllerRxTimeMs=" + mControllerRxTimeMs
-                + " mControllerIdleTimeMs=" + mControllerIdleTimeMs
-                + " mControllerEnergyUsed=" + mControllerEnergyUsed
-                + " mUidTraffic=" + mUidTraffic
-                + " }";
-    }
-
-    public static final @NonNull Parcelable.Creator<BluetoothActivityEnergyInfo> CREATOR =
-            new Parcelable.Creator<BluetoothActivityEnergyInfo>() {
-                public BluetoothActivityEnergyInfo createFromParcel(Parcel in) {
-                    return new BluetoothActivityEnergyInfo(in);
-                }
-
-                public BluetoothActivityEnergyInfo[] newArray(int size) {
-                    return new BluetoothActivityEnergyInfo[size];
-                }
-            };
-
-    /** @hide */
-    @Override
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeLong(mTimestamp);
-        out.writeInt(mBluetoothStackState);
-        out.writeLong(mControllerTxTimeMs);
-        out.writeLong(mControllerRxTimeMs);
-        out.writeLong(mControllerIdleTimeMs);
-        out.writeLong(mControllerEnergyUsed);
-        out.writeTypedList(mUidTraffic);
-    }
-
-    /** @hide */
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    /**
-     * Get the Bluetooth stack state associated with the energy info.
-     *
-     * @return one of {@link #BluetoothStackState} states
-     */
-    @BluetoothStackState
-    public int getBluetoothStackState() {
-        return mBluetoothStackState;
-    }
-
-    /**
-     * @return tx time in ms
-     */
-    public long getControllerTxTimeMillis() {
-        return mControllerTxTimeMs;
-    }
-
-    /**
-     * @return rx time in ms
-     */
-    public long getControllerRxTimeMillis() {
-        return mControllerRxTimeMs;
-    }
-
-    /**
-     * @return idle time in ms
-     */
-    public long getControllerIdleTimeMillis() {
-        return mControllerIdleTimeMs;
-    }
-
-    /**
-     * Get the product of current (mA), voltage (V), and time (ms).
-     *
-     * @return energy used
-     */
-    public long getControllerEnergyUsed() {
-        return mControllerEnergyUsed;
-    }
-
-    /**
-     * @return timestamp (real time elapsed in milliseconds since boot) of record creation
-     */
-    public @ElapsedRealtimeLong long getTimestampMillis() {
-        return mTimestamp;
-    }
-
-    /**
-     * Get the {@link List} of each application {@link android.bluetooth.UidTraffic}.
-     *
-     * @return current {@link List} of {@link android.bluetooth.UidTraffic}
-     */
-    public @NonNull List<UidTraffic> getUidTraffic() {
-        if (mUidTraffic == null) {
-            return Collections.emptyList();
-        }
-        return mUidTraffic;
-    }
-
-    /** @hide */
-    public void setUidTraffic(List<UidTraffic> traffic) {
-        mUidTraffic = traffic;
-    }
-
-    /**
-     * @return true if the record Tx time, Rx time, and Idle time are more than 0.
-     */
-    public boolean isValid() {
-        return ((mControllerTxTimeMs >= 0) && (mControllerRxTimeMs >= 0)
-                && (mControllerIdleTimeMs >= 0));
-    }
-}
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
deleted file mode 100644
index c6c64b0..0000000
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ /dev/null
@@ -1,4396 +0,0 @@
-/*
- * Copyright 2009-2016 The Android Open Source Project
- * Copyright 2015 Samsung LSI
- *
- * 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.bluetooth;
-
-import static java.util.Objects.requireNonNull;
-
-import android.annotation.CallbackExecutor;
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.RequiresNoPermission;
-import android.annotation.RequiresPermission;
-import android.annotation.SdkConstant;
-import android.annotation.SdkConstant.SdkConstantType;
-import android.annotation.SuppressLint;
-import android.annotation.SystemApi;
-import android.app.PropertyInvalidatedCache;
-import android.bluetooth.BluetoothDevice.Transport;
-import android.bluetooth.BluetoothProfile.ConnectionPolicy;
-import android.bluetooth.annotations.RequiresBluetoothAdvertisePermission;
-import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
-import android.bluetooth.annotations.RequiresBluetoothLocationPermission;
-import android.bluetooth.annotations.RequiresBluetoothScanPermission;
-import android.bluetooth.annotations.RequiresLegacyBluetoothAdminPermission;
-import android.bluetooth.annotations.RequiresLegacyBluetoothPermission;
-import android.bluetooth.le.BluetoothLeAdvertiser;
-import android.bluetooth.le.BluetoothLeScanner;
-import android.bluetooth.le.PeriodicAdvertisingManager;
-import android.bluetooth.le.ScanCallback;
-import android.bluetooth.le.ScanFilter;
-import android.bluetooth.le.ScanRecord;
-import android.bluetooth.le.ScanResult;
-import android.bluetooth.le.ScanSettings;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.content.AttributionSource;
-import android.content.Context;
-import android.os.Binder;
-import android.os.Build;
-import android.os.IBinder;
-import android.os.ParcelUuid;
-import android.os.RemoteException;
-import android.os.ResultReceiver;
-import android.os.ServiceManager;
-import android.sysprop.BluetoothProperties;
-import android.util.Log;
-import android.util.Pair;
-
-import com.android.internal.annotations.GuardedBy;
-
-import java.io.IOException;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import java.util.UUID;
-import java.util.WeakHashMap;
-import java.util.concurrent.Executor;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-
-/**
- * Represents the local device Bluetooth adapter. The {@link BluetoothAdapter}
- * lets you perform fundamental Bluetooth tasks, such as initiate
- * device discovery, query a list of bonded (paired) devices,
- * instantiate a {@link BluetoothDevice} using a known MAC address, and create
- * a {@link BluetoothServerSocket} to listen for connection requests from other
- * devices, and start a scan for Bluetooth LE devices.
- *
- * <p>To get a {@link BluetoothAdapter} representing the local Bluetooth
- * adapter, call the {@link BluetoothManager#getAdapter} function on {@link BluetoothManager}.
- * On JELLY_BEAN_MR1 and below you will need to use the static {@link #getDefaultAdapter}
- * method instead.
- * </p><p>
- * Fundamentally, this is your starting point for all
- * Bluetooth actions. Once you have the local adapter, you can get a set of
- * {@link BluetoothDevice} objects representing all paired devices with
- * {@link #getBondedDevices()}; start device discovery with
- * {@link #startDiscovery()}; or create a {@link BluetoothServerSocket} to
- * listen for incoming RFComm connection requests with {@link
- * #listenUsingRfcommWithServiceRecord(String, UUID)}; listen for incoming L2CAP Connection-oriented
- * Channels (CoC) connection requests with {@link #listenUsingL2capChannel()}; or start a scan for
- * Bluetooth LE devices with {@link #startLeScan(LeScanCallback callback)}.
- * </p>
- * <p>This class is thread safe.</p>
- * <div class="special reference">
- * <h3>Developer Guides</h3>
- * <p>
- * For more information about using Bluetooth, read the <a href=
- * "{@docRoot}guide/topics/connectivity/bluetooth.html">Bluetooth</a> developer
- * guide.
- * </p>
- * </div>
- *
- * {@see BluetoothDevice}
- * {@see BluetoothServerSocket}
- */
-public final class BluetoothAdapter {
-    private static final String TAG = "BluetoothAdapter";
-    private static final String DESCRIPTOR = "android.bluetooth.BluetoothAdapter";
-    private static final boolean DBG = true;
-    private static final boolean VDBG = false;
-
-    /**
-     * Default MAC address reported to a client that does not have the
-     * android.permission.LOCAL_MAC_ADDRESS permission.
-     *
-     * @hide
-     */
-    public static final String DEFAULT_MAC_ADDRESS = "02:00:00:00:00:00";
-
-    /**
-     * Sentinel error value for this class. Guaranteed to not equal any other
-     * integer constant in this class. Provided as a convenience for functions
-     * that require a sentinel error value, for example:
-     * <p><code>Intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
-     * BluetoothAdapter.ERROR)</code>
-     */
-    public static final int ERROR = Integer.MIN_VALUE;
-
-    /**
-     * Broadcast Action: The state of the local Bluetooth adapter has been
-     * changed.
-     * <p>For example, Bluetooth has been turned on or off.
-     * <p>Always contains the extra fields {@link #EXTRA_STATE} and {@link
-     * #EXTRA_PREVIOUS_STATE} containing the new and old states
-     * respectively.
-     */
-    @RequiresLegacyBluetoothPermission
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String
-            ACTION_STATE_CHANGED = "android.bluetooth.adapter.action.STATE_CHANGED";
-
-    /**
-     * Used as an int extra field in {@link #ACTION_STATE_CHANGED}
-     * intents to request the current power state. Possible values are:
-     * {@link #STATE_OFF},
-     * {@link #STATE_TURNING_ON},
-     * {@link #STATE_ON},
-     * {@link #STATE_TURNING_OFF},
-     */
-    public static final String EXTRA_STATE = "android.bluetooth.adapter.extra.STATE";
-    /**
-     * Used as an int extra field in {@link #ACTION_STATE_CHANGED}
-     * intents to request the previous power state. Possible values are:
-     * {@link #STATE_OFF},
-     * {@link #STATE_TURNING_ON},
-     * {@link #STATE_ON},
-     * {@link #STATE_TURNING_OFF}
-     */
-    public static final String EXTRA_PREVIOUS_STATE =
-            "android.bluetooth.adapter.extra.PREVIOUS_STATE";
-
-    /** @hide */
-    @IntDef(prefix = { "STATE_" }, value = {
-            STATE_OFF,
-            STATE_TURNING_ON,
-            STATE_ON,
-            STATE_TURNING_OFF,
-            STATE_BLE_TURNING_ON,
-            STATE_BLE_ON,
-            STATE_BLE_TURNING_OFF
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface AdapterState {}
-
-    /**
-     * Indicates the local Bluetooth adapter is off.
-     */
-    public static final int STATE_OFF = 10;
-    /**
-     * Indicates the local Bluetooth adapter is turning on. However local
-     * clients should wait for {@link #STATE_ON} before attempting to
-     * use the adapter.
-     */
-    public static final int STATE_TURNING_ON = 11;
-    /**
-     * Indicates the local Bluetooth adapter is on, and ready for use.
-     */
-    public static final int STATE_ON = 12;
-    /**
-     * Indicates the local Bluetooth adapter is turning off. Local clients
-     * should immediately attempt graceful disconnection of any remote links.
-     */
-    public static final int STATE_TURNING_OFF = 13;
-
-    /**
-     * Indicates the local Bluetooth adapter is turning Bluetooth LE mode on.
-     *
-     * @hide
-     */
-    public static final int STATE_BLE_TURNING_ON = 14;
-
-    /**
-     * Indicates the local Bluetooth adapter is in LE only mode.
-     *
-     * @hide
-     */
-    public static final int STATE_BLE_ON = 15;
-
-    /**
-     * Indicates the local Bluetooth adapter is turning off LE only mode.
-     *
-     * @hide
-     */
-    public static final int STATE_BLE_TURNING_OFF = 16;
-
-    /**
-     * UUID of the GATT Read Characteristics for LE_PSM value.
-     *
-     * @hide
-     */
-    public static final UUID LE_PSM_CHARACTERISTIC_UUID =
-            UUID.fromString("2d410339-82b6-42aa-b34e-e2e01df8cc1a");
-
-    /**
-     * Human-readable string helper for AdapterState
-     *
-     * @hide
-     */
-    public static String nameForState(@AdapterState int state) {
-        switch (state) {
-            case STATE_OFF:
-                return "OFF";
-            case STATE_TURNING_ON:
-                return "TURNING_ON";
-            case STATE_ON:
-                return "ON";
-            case STATE_TURNING_OFF:
-                return "TURNING_OFF";
-            case STATE_BLE_TURNING_ON:
-                return "BLE_TURNING_ON";
-            case STATE_BLE_ON:
-                return "BLE_ON";
-            case STATE_BLE_TURNING_OFF:
-                return "BLE_TURNING_OFF";
-            default:
-                return "?!?!? (" + state + ")";
-        }
-    }
-
-    /**
-     * Activity Action: Show a system activity that requests discoverable mode.
-     * This activity will also request the user to turn on Bluetooth if it
-     * is not currently enabled.
-     * <p>Discoverable mode is equivalent to {@link
-     * #SCAN_MODE_CONNECTABLE_DISCOVERABLE}. It allows remote devices to see
-     * this Bluetooth adapter when they perform a discovery.
-     * <p>For privacy, Android is not discoverable by default.
-     * <p>The sender of this Intent can optionally use extra field {@link
-     * #EXTRA_DISCOVERABLE_DURATION} to request the duration of
-     * discoverability. Currently the default duration is 120 seconds, and
-     * maximum duration is capped at 300 seconds for each request.
-     * <p>Notification of the result of this activity is posted using the
-     * {@link android.app.Activity#onActivityResult} callback. The
-     * <code>resultCode</code>
-     * will be the duration (in seconds) of discoverability or
-     * {@link android.app.Activity#RESULT_CANCELED} if the user rejected
-     * discoverability or an error has occurred.
-     * <p>Applications can also listen for {@link #ACTION_SCAN_MODE_CHANGED}
-     * for global notification whenever the scan mode changes. For example, an
-     * application can be notified when the device has ended discoverability.
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothAdvertisePermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)
-    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) public static final String
-            ACTION_REQUEST_DISCOVERABLE = "android.bluetooth.adapter.action.REQUEST_DISCOVERABLE";
-
-    /**
-     * Used as an optional int extra field in {@link
-     * #ACTION_REQUEST_DISCOVERABLE} intents to request a specific duration
-     * for discoverability in seconds. The current default is 120 seconds, and
-     * requests over 300 seconds will be capped. These values could change.
-     */
-    public static final String EXTRA_DISCOVERABLE_DURATION =
-            "android.bluetooth.adapter.extra.DISCOVERABLE_DURATION";
-
-    /**
-     * Activity Action: Show a system activity that allows the user to turn on
-     * Bluetooth.
-     * <p>This system activity will return once Bluetooth has completed turning
-     * on, or the user has decided not to turn Bluetooth on.
-     * <p>Notification of the result of this activity is posted using the
-     * {@link android.app.Activity#onActivityResult} callback. The
-     * <code>resultCode</code>
-     * will be {@link android.app.Activity#RESULT_OK} if Bluetooth has been
-     * turned on or {@link android.app.Activity#RESULT_CANCELED} if the user
-     * has rejected the request or an error has occurred.
-     * <p>Applications can also listen for {@link #ACTION_STATE_CHANGED}
-     * for global notification whenever Bluetooth is turned on or off.
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) public static final String
-            ACTION_REQUEST_ENABLE = "android.bluetooth.adapter.action.REQUEST_ENABLE";
-
-    /**
-     * Activity Action: Show a system activity that allows the user to turn off
-     * Bluetooth. This is used only if permission review is enabled which is for
-     * apps targeting API less than 23 require a permission review before any of
-     * the app's components can run.
-     * <p>This system activity will return once Bluetooth has completed turning
-     * off, or the user has decided not to turn Bluetooth off.
-     * <p>Notification of the result of this activity is posted using the
-     * {@link android.app.Activity#onActivityResult} callback. The
-     * <code>resultCode</code>
-     * will be {@link android.app.Activity#RESULT_OK} if Bluetooth has been
-     * turned off or {@link android.app.Activity#RESULT_CANCELED} if the user
-     * has rejected the request or an error has occurred.
-     * <p>Applications can also listen for {@link #ACTION_STATE_CHANGED}
-     * for global notification whenever Bluetooth is turned on or off.
-     *
-     * @hide
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) public static final String
-            ACTION_REQUEST_DISABLE = "android.bluetooth.adapter.action.REQUEST_DISABLE";
-
-    /**
-     * Activity Action: Show a system activity that allows user to enable BLE scans even when
-     * Bluetooth is turned off.<p>
-     *
-     * Notification of result of this activity is posted using
-     * {@link android.app.Activity#onActivityResult}. The <code>resultCode</code> will be
-     * {@link android.app.Activity#RESULT_OK} if BLE scan always available setting is turned on or
-     * {@link android.app.Activity#RESULT_CANCELED} if the user has rejected the request or an
-     * error occurred.
-     *
-     * @hide
-     */
-    @SystemApi
-    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
-    public static final String ACTION_REQUEST_BLE_SCAN_ALWAYS_AVAILABLE =
-            "android.bluetooth.adapter.action.REQUEST_BLE_SCAN_ALWAYS_AVAILABLE";
-
-    /**
-     * Broadcast Action: Indicates the Bluetooth scan mode of the local Adapter
-     * has changed.
-     * <p>Always contains the extra fields {@link #EXTRA_SCAN_MODE} and {@link
-     * #EXTRA_PREVIOUS_SCAN_MODE} containing the new and old scan modes
-     * respectively.
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothScanPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String
-            ACTION_SCAN_MODE_CHANGED = "android.bluetooth.adapter.action.SCAN_MODE_CHANGED";
-
-    /**
-     * Used as an int extra field in {@link #ACTION_SCAN_MODE_CHANGED}
-     * intents to request the current scan mode. Possible values are:
-     * {@link #SCAN_MODE_NONE},
-     * {@link #SCAN_MODE_CONNECTABLE},
-     * {@link #SCAN_MODE_CONNECTABLE_DISCOVERABLE},
-     */
-    public static final String EXTRA_SCAN_MODE = "android.bluetooth.adapter.extra.SCAN_MODE";
-    /**
-     * Used as an int extra field in {@link #ACTION_SCAN_MODE_CHANGED}
-     * intents to request the previous scan mode. Possible values are:
-     * {@link #SCAN_MODE_NONE},
-     * {@link #SCAN_MODE_CONNECTABLE},
-     * {@link #SCAN_MODE_CONNECTABLE_DISCOVERABLE},
-     */
-    public static final String EXTRA_PREVIOUS_SCAN_MODE =
-            "android.bluetooth.adapter.extra.PREVIOUS_SCAN_MODE";
-
-    /** @hide */
-    @IntDef(prefix = { "SCAN_" }, value = {
-            SCAN_MODE_NONE,
-            SCAN_MODE_CONNECTABLE,
-            SCAN_MODE_CONNECTABLE_DISCOVERABLE
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface ScanMode {}
-
-    /**
-     * Indicates that both inquiry scan and page scan are disabled on the local
-     * Bluetooth adapter. Therefore this device is neither discoverable
-     * nor connectable from remote Bluetooth devices.
-     */
-    public static final int SCAN_MODE_NONE = 20;
-    /**
-     * Indicates that inquiry scan is disabled, but page scan is enabled on the
-     * local Bluetooth adapter. Therefore this device is not discoverable from
-     * remote Bluetooth devices, but is connectable from remote devices that
-     * have previously discovered this device.
-     */
-    public static final int SCAN_MODE_CONNECTABLE = 21;
-    /**
-     * Indicates that both inquiry scan and page scan are enabled on the local
-     * Bluetooth adapter. Therefore this device is both discoverable and
-     * connectable from remote Bluetooth devices.
-     */
-    public static final int SCAN_MODE_CONNECTABLE_DISCOVERABLE = 23;
-
-    /**
-     * Device only has a display.
-     *
-     * @hide
-     */
-    public static final int IO_CAPABILITY_OUT = 0;
-
-    /**
-     * Device has a display and the ability to input Yes/No.
-     *
-     * @hide
-     */
-    public static final int IO_CAPABILITY_IO = 1;
-
-    /**
-     * Device only has a keyboard for entry but no display.
-     *
-     * @hide
-     */
-    public static final int IO_CAPABILITY_IN = 2;
-
-    /**
-     * Device has no Input or Output capability.
-     *
-     * @hide
-     */
-    public static final int IO_CAPABILITY_NONE = 3;
-
-    /**
-     * Device has a display and a full keyboard.
-     *
-     * @hide
-     */
-    public static final int IO_CAPABILITY_KBDISP = 4;
-
-    /**
-     * Maximum range value for Input/Output capabilities.
-     *
-     * <p>This should be updated when adding a new Input/Output capability. Other code
-     * like validation depends on this being accurate.
-     *
-     * @hide
-     */
-    public static final int IO_CAPABILITY_MAX = 5;
-
-    /**
-     * The Input/Output capability of the device is unknown.
-     *
-     * @hide
-     */
-    public static final int IO_CAPABILITY_UNKNOWN = 255;
-
-    /** @hide */
-    @IntDef({IO_CAPABILITY_OUT, IO_CAPABILITY_IO, IO_CAPABILITY_IN, IO_CAPABILITY_NONE,
-            IO_CAPABILITY_KBDISP})
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface IoCapability {}
-
-    /** @hide */
-    @IntDef(prefix = "ACTIVE_DEVICE_", value = {ACTIVE_DEVICE_AUDIO,
-            ACTIVE_DEVICE_PHONE_CALL, ACTIVE_DEVICE_ALL})
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface ActiveDeviceUse {}
-
-    /**
-     * Use the specified device for audio (a2dp and hearing aid profile)
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int ACTIVE_DEVICE_AUDIO = 0;
-
-    /**
-     * Use the specified device for phone calls (headset profile and hearing
-     * aid profile)
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int ACTIVE_DEVICE_PHONE_CALL = 1;
-
-    /**
-     * Use the specified device for a2dp, hearing aid profile, and headset profile
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int ACTIVE_DEVICE_ALL = 2;
-
-    /** @hide */
-    @IntDef({BluetoothProfile.HEADSET, BluetoothProfile.A2DP,
-            BluetoothProfile.HEARING_AID})
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface ActiveDeviceProfile {}
-
-    /**
-     * Broadcast Action: The local Bluetooth adapter has started the remote
-     * device discovery process.
-     * <p>This usually involves an inquiry scan of about 12 seconds, followed
-     * by a page scan of each new device to retrieve its Bluetooth name.
-     * <p>Register for {@link BluetoothDevice#ACTION_FOUND} to be notified as
-     * remote Bluetooth devices are found.
-     * <p>Device discovery is a heavyweight procedure. New connections to
-     * remote Bluetooth devices should not be attempted while discovery is in
-     * progress, and existing connections will experience limited bandwidth
-     * and high latency. Use {@link #cancelDiscovery()} to cancel an ongoing
-     * discovery.
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothScanPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String
-            ACTION_DISCOVERY_STARTED = "android.bluetooth.adapter.action.DISCOVERY_STARTED";
-    /**
-     * Broadcast Action: The local Bluetooth adapter has finished the device
-     * discovery process.
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothScanPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String
-            ACTION_DISCOVERY_FINISHED = "android.bluetooth.adapter.action.DISCOVERY_FINISHED";
-
-    /**
-     * Broadcast Action: The local Bluetooth adapter has changed its friendly
-     * Bluetooth name.
-     * <p>This name is visible to remote Bluetooth devices.
-     * <p>Always contains the extra field {@link #EXTRA_LOCAL_NAME} containing
-     * the name.
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String
-            ACTION_LOCAL_NAME_CHANGED = "android.bluetooth.adapter.action.LOCAL_NAME_CHANGED";
-    /**
-     * Used as a String extra field in {@link #ACTION_LOCAL_NAME_CHANGED}
-     * intents to request the local Bluetooth name.
-     */
-    public static final String EXTRA_LOCAL_NAME = "android.bluetooth.adapter.extra.LOCAL_NAME";
-
-    /**
-     * Intent used to broadcast the change in connection state of the local
-     * Bluetooth adapter to a profile of the remote device. When the adapter is
-     * not connected to any profiles of any remote devices and it attempts a
-     * connection to a profile this intent will be sent. Once connected, this intent
-     * will not be sent for any more connection attempts to any profiles of any
-     * remote device. When the adapter disconnects from the last profile its
-     * connected to of any remote device, this intent will be sent.
-     *
-     * <p> This intent is useful for applications that are only concerned about
-     * whether the local adapter is connected to any profile of any device and
-     * are not really concerned about which profile. For example, an application
-     * which displays an icon to display whether Bluetooth is connected or not
-     * can use this intent.
-     *
-     * <p>This intent will have 3 extras:
-     * {@link #EXTRA_CONNECTION_STATE} - The current connection state.
-     * {@link #EXTRA_PREVIOUS_CONNECTION_STATE}- The previous connection state.
-     * {@link BluetoothDevice#EXTRA_DEVICE} - The remote device.
-     *
-     * {@link #EXTRA_CONNECTION_STATE} or {@link #EXTRA_PREVIOUS_CONNECTION_STATE}
-     * can be any of {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTING},
-     * {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTING}.
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String
-            ACTION_CONNECTION_STATE_CHANGED =
-            "android.bluetooth.adapter.action.CONNECTION_STATE_CHANGED";
-
-    /**
-     * Extra used by {@link #ACTION_CONNECTION_STATE_CHANGED}
-     *
-     * This extra represents the current connection state.
-     */
-    public static final String EXTRA_CONNECTION_STATE =
-            "android.bluetooth.adapter.extra.CONNECTION_STATE";
-
-    /**
-     * Extra used by {@link #ACTION_CONNECTION_STATE_CHANGED}
-     *
-     * This extra represents the previous connection state.
-     */
-    public static final String EXTRA_PREVIOUS_CONNECTION_STATE =
-            "android.bluetooth.adapter.extra.PREVIOUS_CONNECTION_STATE";
-
-    /**
-     * Broadcast Action: The Bluetooth adapter state has changed in LE only mode.
-     *
-     * @hide
-     */
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    @SystemApi public static final String ACTION_BLE_STATE_CHANGED =
-            "android.bluetooth.adapter.action.BLE_STATE_CHANGED";
-
-    /**
-     * Intent used to broadcast the change in the Bluetooth address
-     * of the local Bluetooth adapter.
-     * <p>Always contains the extra field {@link
-     * #EXTRA_BLUETOOTH_ADDRESS} containing the Bluetooth address.
-     *
-     * Note: only system level processes are allowed to send this
-     * defined broadcast.
-     *
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_BLUETOOTH_ADDRESS_CHANGED =
-            "android.bluetooth.adapter.action.BLUETOOTH_ADDRESS_CHANGED";
-
-    /**
-     * Used as a String extra field in {@link
-     * #ACTION_BLUETOOTH_ADDRESS_CHANGED} intent to store the local
-     * Bluetooth address.
-     *
-     * @hide
-     */
-    public static final String EXTRA_BLUETOOTH_ADDRESS =
-            "android.bluetooth.adapter.extra.BLUETOOTH_ADDRESS";
-
-    /**
-     * Broadcast Action: The notifys Bluetooth ACL connected event. This will be
-     * by BLE Always on enabled application to know the ACL_CONNECTED event
-     * when Bluetooth state in STATE_BLE_ON. This denotes GATT connection
-     * as Bluetooth LE is the only feature available in STATE_BLE_ON
-     *
-     * This is counterpart of {@link BluetoothDevice#ACTION_ACL_CONNECTED} which
-     * works in Bluetooth state STATE_ON
-     *
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_BLE_ACL_CONNECTED =
-            "android.bluetooth.adapter.action.BLE_ACL_CONNECTED";
-
-    /**
-     * Broadcast Action: The notifys Bluetooth ACL connected event. This will be
-     * by BLE Always on enabled application to know the ACL_DISCONNECTED event
-     * when Bluetooth state in STATE_BLE_ON. This denotes GATT disconnection as Bluetooth
-     * LE is the only feature available in STATE_BLE_ON
-     *
-     * This is counterpart of {@link BluetoothDevice#ACTION_ACL_DISCONNECTED} which
-     * works in Bluetooth state STATE_ON
-     *
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_BLE_ACL_DISCONNECTED =
-            "android.bluetooth.adapter.action.BLE_ACL_DISCONNECTED";
-
-    /** The profile is in disconnected state */
-    public static final int STATE_DISCONNECTED = BluetoothProtoEnums.CONNECTION_STATE_DISCONNECTED;
-    /** The profile is in connecting state */
-    public static final int STATE_CONNECTING = BluetoothProtoEnums.CONNECTION_STATE_CONNECTING;
-    /** The profile is in connected state */
-    public static final int STATE_CONNECTED = BluetoothProtoEnums.CONNECTION_STATE_CONNECTED;
-    /** The profile is in disconnecting state */
-    public static final int STATE_DISCONNECTING =
-            BluetoothProtoEnums.CONNECTION_STATE_DISCONNECTING;
-
-    /** @hide */
-    public static final String BLUETOOTH_MANAGER_SERVICE = "bluetooth_manager";
-    private final IBinder mToken;
-
-
-    /**
-     * When creating a ServerSocket using listenUsingRfcommOn() or
-     * listenUsingL2capOn() use SOCKET_CHANNEL_AUTO_STATIC to create
-     * a ServerSocket that auto assigns a channel number to the first
-     * bluetooth socket.
-     * The channel number assigned to this first Bluetooth Socket will
-     * be stored in the ServerSocket, and reused for subsequent Bluetooth
-     * sockets.
-     *
-     * @hide
-     */
-    public static final int SOCKET_CHANNEL_AUTO_STATIC_NO_SDP = -2;
-
-
-    private static final int ADDRESS_LENGTH = 17;
-
-    /**
-     * Lazily initialized singleton. Guaranteed final after first object
-     * constructed.
-     */
-    private static BluetoothAdapter sAdapter;
-
-    private BluetoothLeScanner mBluetoothLeScanner;
-    private BluetoothLeAdvertiser mBluetoothLeAdvertiser;
-    private PeriodicAdvertisingManager mPeriodicAdvertisingManager;
-
-    private final IBluetoothManager mManagerService;
-    private final AttributionSource mAttributionSource;
-
-    // Yeah, keeping both mService and sService isn't pretty, but it's too late
-    // in the current release for a major refactoring, so we leave them both
-    // intact until this can be cleaned up in a future release
-
-    @UnsupportedAppUsage
-    @GuardedBy("mServiceLock")
-    private IBluetooth mService;
-    private final ReentrantReadWriteLock mServiceLock = new ReentrantReadWriteLock();
-
-    @GuardedBy("sServiceLock")
-    private static boolean sServiceRegistered;
-    @GuardedBy("sServiceLock")
-    private static IBluetooth sService;
-    private static final Object sServiceLock = new Object();
-
-    private final Object mLock = new Object();
-    private final Map<LeScanCallback, ScanCallback> mLeScanClients;
-    private final Map<BluetoothDevice, List<Pair<OnMetadataChangedListener, Executor>>>
-                mMetadataListeners = new HashMap<>();
-    private final Map<BluetoothConnectionCallback, Executor>
-            mBluetoothConnectionCallbackExecutorMap = new HashMap<>();
-
-    /**
-     * Bluetooth metadata listener. Overrides the default BluetoothMetadataListener
-     * implementation.
-     */
-    @SuppressLint("AndroidFrameworkBluetoothPermission")
-    private final IBluetoothMetadataListener mBluetoothMetadataListener =
-            new IBluetoothMetadataListener.Stub() {
-        @Override
-        public void onMetadataChanged(BluetoothDevice device, int key, byte[] value) {
-            Attributable.setAttributionSource(device, mAttributionSource);
-            synchronized (mMetadataListeners) {
-                if (mMetadataListeners.containsKey(device)) {
-                    List<Pair<OnMetadataChangedListener, Executor>> list =
-                            mMetadataListeners.get(device);
-                    for (Pair<OnMetadataChangedListener, Executor> pair : list) {
-                        OnMetadataChangedListener listener = pair.first;
-                        Executor executor = pair.second;
-                        executor.execute(() -> {
-                            listener.onMetadataChanged(device, key, value);
-                        });
-                    }
-                }
-            }
-            return;
-        }
-    };
-
-    /**
-     * Get a handle to the default local Bluetooth adapter.
-     * <p>
-     * Currently Android only supports one Bluetooth adapter, but the API could
-     * be extended to support more. This will always return the default adapter.
-     * </p>
-     *
-     * @return the default local adapter, or null if Bluetooth is not supported
-     *         on this hardware platform
-     * @deprecated this method will continue to work, but developers are
-     *             strongly encouraged to migrate to using
-     *             {@link BluetoothManager#getAdapter()}, since that approach
-     *             enables support for {@link Context#createAttributionContext}.
-     */
-    @Deprecated
-    @RequiresNoPermission
-    public static synchronized BluetoothAdapter getDefaultAdapter() {
-        if (sAdapter == null) {
-            sAdapter = createAdapter(AttributionSource.myAttributionSource());
-        }
-        return sAdapter;
-    }
-
-    /** {@hide} */
-    public static BluetoothAdapter createAdapter(AttributionSource attributionSource) {
-        IBinder binder = ServiceManager.getService(BLUETOOTH_MANAGER_SERVICE);
-        if (binder != null) {
-            return new BluetoothAdapter(IBluetoothManager.Stub.asInterface(binder),
-                    attributionSource);
-        } else {
-            Log.e(TAG, "Bluetooth binder is null");
-            return null;
-        }
-    }
-
-    /**
-     * Use {@link #getDefaultAdapter} to get the BluetoothAdapter instance.
-     */
-    BluetoothAdapter(IBluetoothManager managerService, AttributionSource attributionSource) {
-        mManagerService = Objects.requireNonNull(managerService);
-        mAttributionSource = Objects.requireNonNull(attributionSource);
-        synchronized (mServiceLock.writeLock()) {
-            mService = getBluetoothService(mManagerCallback);
-        }
-        mLeScanClients = new HashMap<LeScanCallback, ScanCallback>();
-        mToken = new Binder(DESCRIPTOR);
-    }
-
-    /**
-     * Get a {@link BluetoothDevice} object for the given Bluetooth hardware
-     * address.
-     * <p>Valid Bluetooth hardware addresses must be upper case, in a format
-     * such as "00:11:22:33:AA:BB". The helper {@link #checkBluetoothAddress} is
-     * available to validate a Bluetooth address.
-     * <p>A {@link BluetoothDevice} will always be returned for a valid
-     * hardware address, even if this adapter has never seen that device.
-     *
-     * @param address valid Bluetooth MAC address
-     * @throws IllegalArgumentException if address is invalid
-     */
-    @RequiresNoPermission
-    public BluetoothDevice getRemoteDevice(String address) {
-        final BluetoothDevice res = new BluetoothDevice(address);
-        res.setAttributionSource(mAttributionSource);
-        return res;
-    }
-
-    /**
-     * Get a {@link BluetoothDevice} object for the given Bluetooth hardware
-     * address.
-     * <p>Valid Bluetooth hardware addresses must be 6 bytes. This method
-     * expects the address in network byte order (MSB first).
-     * <p>A {@link BluetoothDevice} will always be returned for a valid
-     * hardware address, even if this adapter has never seen that device.
-     *
-     * @param address Bluetooth MAC address (6 bytes)
-     * @throws IllegalArgumentException if address is invalid
-     */
-    @RequiresNoPermission
-    public BluetoothDevice getRemoteDevice(byte[] address) {
-        if (address == null || address.length != 6) {
-            throw new IllegalArgumentException("Bluetooth address must have 6 bytes");
-        }
-        final BluetoothDevice res = new BluetoothDevice(
-                String.format(Locale.US, "%02X:%02X:%02X:%02X:%02X:%02X", address[0], address[1],
-                        address[2], address[3], address[4], address[5]));
-        res.setAttributionSource(mAttributionSource);
-        return res;
-    }
-
-    /**
-     * Returns a {@link BluetoothLeAdvertiser} object for Bluetooth LE Advertising operations.
-     * Will return null if Bluetooth is turned off or if Bluetooth LE Advertising is not
-     * supported on this device.
-     * <p>
-     * Use {@link #isMultipleAdvertisementSupported()} to check whether LE Advertising is supported
-     * on this device before calling this method.
-     */
-    @RequiresNoPermission
-    public BluetoothLeAdvertiser getBluetoothLeAdvertiser() {
-        if (!getLeAccess()) {
-            return null;
-        }
-        synchronized (mLock) {
-            if (mBluetoothLeAdvertiser == null) {
-                mBluetoothLeAdvertiser = new BluetoothLeAdvertiser(this);
-            }
-            return mBluetoothLeAdvertiser;
-        }
-    }
-
-    /**
-     * Returns a {@link PeriodicAdvertisingManager} object for Bluetooth LE Periodic Advertising
-     * operations. Will return null if Bluetooth is turned off or if Bluetooth LE Periodic
-     * Advertising is not supported on this device.
-     * <p>
-     * Use {@link #isLePeriodicAdvertisingSupported()} to check whether LE Periodic Advertising is
-     * supported on this device before calling this method.
-     *
-     * @hide
-     */
-    @RequiresNoPermission
-    public PeriodicAdvertisingManager getPeriodicAdvertisingManager() {
-        if (!getLeAccess()) {
-            return null;
-        }
-
-        if (!isLePeriodicAdvertisingSupported()) {
-            return null;
-        }
-
-        synchronized (mLock) {
-            if (mPeriodicAdvertisingManager == null) {
-                mPeriodicAdvertisingManager = new PeriodicAdvertisingManager(this);
-            }
-            return mPeriodicAdvertisingManager;
-        }
-    }
-
-    /**
-     * Returns a {@link BluetoothLeScanner} object for Bluetooth LE scan operations.
-     */
-    @RequiresNoPermission
-    public BluetoothLeScanner getBluetoothLeScanner() {
-        if (!getLeAccess()) {
-            return null;
-        }
-        synchronized (mLock) {
-            if (mBluetoothLeScanner == null) {
-                mBluetoothLeScanner = new BluetoothLeScanner(this);
-            }
-            return mBluetoothLeScanner;
-        }
-    }
-
-    /**
-     * Return true if Bluetooth is currently enabled and ready for use.
-     * <p>Equivalent to:
-     * <code>getBluetoothState() == STATE_ON</code>
-     *
-     * @return true if the local adapter is turned on
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresNoPermission
-    public boolean isEnabled() {
-        return getState() == BluetoothAdapter.STATE_ON;
-    }
-
-    /**
-     * Return true if Bluetooth LE(Always BLE On feature) is currently
-     * enabled and ready for use
-     * <p>This returns true if current state is either STATE_ON or STATE_BLE_ON
-     *
-     * @return true if the local Bluetooth LE adapter is turned on
-     * @hide
-     */
-    @SystemApi
-    @RequiresNoPermission
-    public boolean isLeEnabled() {
-        final int state = getLeState();
-        if (DBG) {
-            Log.d(TAG, "isLeEnabled(): " + BluetoothAdapter.nameForState(state));
-        }
-        return (state == BluetoothAdapter.STATE_ON
-                || state == BluetoothAdapter.STATE_BLE_ON
-                || state == BluetoothAdapter.STATE_TURNING_ON
-                || state == BluetoothAdapter.STATE_TURNING_OFF);
-    }
-
-    /**
-     * Turns off Bluetooth LE which was earlier turned on by calling enableBLE().
-     *
-     * <p> If the internal Adapter state is STATE_BLE_ON, this would trigger the transition
-     * to STATE_OFF and completely shut-down Bluetooth
-     *
-     * <p> If the Adapter state is STATE_ON, This would unregister the existance of
-     * special Bluetooth LE application and hence the further turning off of Bluetooth
-     * from UI would ensure the complete turn-off of Bluetooth rather than staying back
-     * BLE only state
-     *
-     * <p>This is an asynchronous call: it will return immediately, and
-     * clients should listen for {@link #ACTION_BLE_STATE_CHANGED}
-     * to be notified of subsequent adapter state changes If this call returns
-     * true, then the adapter state will immediately transition from {@link
-     * #STATE_ON} to {@link #STATE_TURNING_OFF}, and some time
-     * later transition to either {@link #STATE_BLE_ON} or {@link
-     * #STATE_OFF} based on the existance of the further Always BLE ON enabled applications
-     * If this call returns false then there was an
-     * immediate problem that will prevent the QAdapter from being turned off -
-     * such as the QAadapter already being turned off.
-     *
-     * @return true to indicate success, or false on immediate error
-     * @hide
-     */
-    @SystemApi
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean disableBLE() {
-        if (!isBleScanAlwaysAvailable()) {
-            return false;
-        }
-        try {
-            return mManagerService.disableBle(mAttributionSource, mToken);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        }
-        return false;
-    }
-
-    /**
-     * Applications who want to only use Bluetooth Low Energy (BLE) can call enableBLE.
-     *
-     * enableBLE registers the existence of an app using only LE functions.
-     *
-     * enableBLE may enable Bluetooth to an LE only mode so that an app can use
-     * LE related features (BluetoothGatt or BluetoothGattServer classes)
-     *
-     * If the user disables Bluetooth while an app is registered to use LE only features,
-     * Bluetooth will remain on in LE only mode for the app.
-     *
-     * When Bluetooth is in LE only mode, it is not shown as ON to the UI.
-     *
-     * <p>This is an asynchronous call: it returns immediately, and
-     * clients should listen for {@link #ACTION_BLE_STATE_CHANGED}
-     * to be notified of adapter state changes.
-     *
-     * If this call returns * true, then the adapter state is either in a mode where
-     * LE is available, or will transition from {@link #STATE_OFF} to {@link #STATE_BLE_TURNING_ON},
-     * and some time later transition to either {@link #STATE_OFF} or {@link #STATE_BLE_ON}.
-     *
-     * If this call returns false then there was an immediate problem that prevents the
-     * adapter from being turned on - such as Airplane mode.
-     *
-     * {@link #ACTION_BLE_STATE_CHANGED} returns the Bluetooth Adapter's various
-     * states, It includes all the classic Bluetooth Adapter states along with
-     * internal BLE only states
-     *
-     * @return true to indicate Bluetooth LE will be available, or false on immediate error
-     * @hide
-     */
-    @SystemApi
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean enableBLE() {
-        if (!isBleScanAlwaysAvailable()) {
-            return false;
-        }
-        try {
-            return mManagerService.enableBle(mAttributionSource, mToken);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        }
-
-        return false;
-    }
-
-    private static final String BLUETOOTH_GET_STATE_CACHE_PROPERTY = "cache_key.bluetooth.get_state";
-
-    private final PropertyInvalidatedCache<Void, Integer> mBluetoothGetStateCache =
-            new PropertyInvalidatedCache<Void, Integer>(
-                8, BLUETOOTH_GET_STATE_CACHE_PROPERTY) {
-                @Override
-                @SuppressLint("AndroidFrameworkRequiresPermission")
-                protected Integer recompute(Void query) {
-                    try {
-                        return mService.getState();
-                    } catch (RemoteException e) {
-                        throw e.rethrowFromSystemServer();
-                    }
-                }
-            };
-
-    /** @hide */
-    @RequiresNoPermission
-    public void disableBluetoothGetStateCache() {
-        mBluetoothGetStateCache.disableLocal();
-    }
-
-    /** @hide */
-    public static void invalidateBluetoothGetStateCache() {
-        PropertyInvalidatedCache.invalidateCache(BLUETOOTH_GET_STATE_CACHE_PROPERTY);
-    }
-
-    /**
-     * Fetch the current bluetooth state.  If the service is down, return
-     * OFF.
-     */
-    @AdapterState
-    private int getStateInternal() {
-        int state = BluetoothAdapter.STATE_OFF;
-        try {
-            mServiceLock.readLock().lock();
-            if (mService != null) {
-                state = mBluetoothGetStateCache.query(null);
-            }
-        } catch (RuntimeException e) {
-            if (e.getCause() instanceof RemoteException) {
-                Log.e(TAG, "", e.getCause());
-            } else {
-                throw e;
-            }
-        } finally {
-            mServiceLock.readLock().unlock();
-        }
-        return state;
-    }
-
-    /**
-     * Get the current state of the local Bluetooth adapter.
-     * <p>Possible return values are
-     * {@link #STATE_OFF},
-     * {@link #STATE_TURNING_ON},
-     * {@link #STATE_ON},
-     * {@link #STATE_TURNING_OFF}.
-     *
-     * @return current state of Bluetooth adapter
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresNoPermission
-    @AdapterState
-    public int getState() {
-        int state = getStateInternal();
-
-        // Consider all internal states as OFF
-        if (state == BluetoothAdapter.STATE_BLE_ON || state == BluetoothAdapter.STATE_BLE_TURNING_ON
-                || state == BluetoothAdapter.STATE_BLE_TURNING_OFF) {
-            if (VDBG) {
-                Log.d(TAG, "Consider " + BluetoothAdapter.nameForState(state) + " state as OFF");
-            }
-            state = BluetoothAdapter.STATE_OFF;
-        }
-        if (VDBG) {
-            Log.d(TAG, "" + hashCode() + ": getState(). Returning " + BluetoothAdapter.nameForState(
-                    state));
-        }
-        return state;
-    }
-
-    /**
-     * Get the current state of the local Bluetooth adapter
-     * <p>This returns current internal state of Adapter including LE ON/OFF
-     *
-     * <p>Possible return values are
-     * {@link #STATE_OFF},
-     * {@link #STATE_BLE_TURNING_ON},
-     * {@link #STATE_BLE_ON},
-     * {@link #STATE_TURNING_ON},
-     * {@link #STATE_ON},
-     * {@link #STATE_TURNING_OFF},
-     * {@link #STATE_BLE_TURNING_OFF}.
-     *
-     * @return current state of Bluetooth adapter
-     * @hide
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresNoPermission
-    @AdapterState
-    @UnsupportedAppUsage(publicAlternatives = "Use {@link #getState()} instead to determine "
-            + "whether you can use BLE & BT classic.")
-    public int getLeState() {
-        int state = getStateInternal();
-
-        if (VDBG) {
-            Log.d(TAG, "getLeState() returning " + BluetoothAdapter.nameForState(state));
-        }
-        return state;
-    }
-
-    boolean getLeAccess() {
-        if (getLeState() == STATE_ON) {
-            return true;
-        } else if (getLeState() == STATE_BLE_ON) {
-            return true; // TODO: FILTER SYSTEM APPS HERE <--
-        }
-
-        return false;
-    }
-
-    /**
-     * Turn on the local Bluetooth adapter&mdash;do not use without explicit
-     * user action to turn on Bluetooth.
-     * <p>This powers on the underlying Bluetooth hardware, and starts all
-     * Bluetooth system services.
-     * <p class="caution"><strong>Bluetooth should never be enabled without
-     * direct user consent</strong>. If you want to turn on Bluetooth in order
-     * to create a wireless connection, you should use the {@link
-     * #ACTION_REQUEST_ENABLE} Intent, which will raise a dialog that requests
-     * user permission to turn on Bluetooth. The {@link #enable()} method is
-     * provided only for applications that include a user interface for changing
-     * system settings, such as a "power manager" app.</p>
-     * <p>This is an asynchronous call: it will return immediately, and
-     * clients should listen for {@link #ACTION_STATE_CHANGED}
-     * to be notified of subsequent adapter state changes. If this call returns
-     * true, then the adapter state will immediately transition from {@link
-     * #STATE_OFF} to {@link #STATE_TURNING_ON}, and some time
-     * later transition to either {@link #STATE_OFF} or {@link
-     * #STATE_ON}. If this call returns false then there was an
-     * immediate problem that will prevent the adapter from being turned on -
-     * such as Airplane mode, or the adapter is already turned on.
-     *
-     * @return true to indicate adapter startup has begun, or false on immediate error
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean enable() {
-        if (isEnabled()) {
-            if (DBG) {
-                Log.d(TAG, "enable(): BT already enabled!");
-            }
-            return true;
-        }
-        try {
-            return mManagerService.enable(mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        }
-        return false;
-    }
-
-    /**
-     * Turn off the local Bluetooth adapter&mdash;do not use without explicit
-     * user action to turn off Bluetooth.
-     * <p>This gracefully shuts down all Bluetooth connections, stops Bluetooth
-     * system services, and powers down the underlying Bluetooth hardware.
-     * <p class="caution"><strong>Bluetooth should never be disabled without
-     * direct user consent</strong>. The {@link #disable()} method is
-     * provided only for applications that include a user interface for changing
-     * system settings, such as a "power manager" app.</p>
-     * <p>This is an asynchronous call: it will return immediately, and
-     * clients should listen for {@link #ACTION_STATE_CHANGED}
-     * to be notified of subsequent adapter state changes. If this call returns
-     * true, then the adapter state will immediately transition from {@link
-     * #STATE_ON} to {@link #STATE_TURNING_OFF}, and some time
-     * later transition to either {@link #STATE_OFF} or {@link
-     * #STATE_ON}. If this call returns false then there was an
-     * immediate problem that will prevent the adapter from being turned off -
-     * such as the adapter already being turned off.
-     *
-     * @return true to indicate adapter shutdown has begun, or false on immediate error
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean disable() {
-        try {
-            return mManagerService.disable(mAttributionSource, true);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        }
-        return false;
-    }
-
-    /**
-     * Turn off the local Bluetooth adapter and don't persist the setting.
-     *
-     * @param persist Indicate whether the off state should be persisted following the next reboot
-     * @return true to indicate adapter shutdown has begun, or false on immediate error
-     * @hide
-     */
-    @SystemApi
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public boolean disable(boolean persist) {
-
-        try {
-            return mManagerService.disable(mAttributionSource, persist);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        }
-        return false;
-    }
-
-    /**
-     * Returns the hardware address of the local Bluetooth adapter.
-     * <p>For example, "00:11:22:AA:BB:CC".
-     *
-     * @return Bluetooth hardware address as string
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.LOCAL_MAC_ADDRESS,
-    })
-    public String getAddress() {
-        try {
-            return mManagerService.getAddress(mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        }
-        return null;
-    }
-
-    /**
-     * Get the friendly Bluetooth name of the local Bluetooth adapter.
-     * <p>This name is visible to remote Bluetooth devices.
-     *
-     * @return the Bluetooth name, or null on error
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public String getName() {
-        try {
-            return mManagerService.getName(mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        }
-        return null;
-    }
-
-    /** {@hide} */
-    @RequiresBluetoothAdvertisePermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)
-    public int getNameLengthForAdvertise() {
-        try {
-            return mService.getNameLengthForAdvertise(mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        }
-        return -1;
-    }
-
-    /**
-     * Factory reset bluetooth settings.
-     *
-     * @return true to indicate that the config file was successfully cleared
-     * @hide
-     */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public boolean factoryReset() {
-        try {
-            mServiceLock.readLock().lock();
-            if (mService != null && mService.factoryReset(mAttributionSource)
-                    && mManagerService != null
-                    && mManagerService.onFactoryReset(mAttributionSource)) {
-                return true;
-            }
-            Log.e(TAG, "factoryReset(): Setting persist.bluetooth.factoryreset to retry later");
-            BluetoothProperties.factory_reset(true);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        } finally {
-            mServiceLock.readLock().unlock();
-        }
-        return false;
-    }
-
-    /**
-     * Get the UUIDs supported by the local Bluetooth adapter.
-     *
-     * @return the UUIDs supported by the local Bluetooth Adapter.
-     * @hide
-     */
-    @UnsupportedAppUsage
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public @Nullable ParcelUuid[] getUuids() {
-        if (getState() != STATE_ON) {
-            return null;
-        }
-        try {
-            mServiceLock.readLock().lock();
-            if (mService != null) {
-                return mService.getUuids(mAttributionSource);
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        } finally {
-            mServiceLock.readLock().unlock();
-        }
-        return null;
-    }
-
-    /**
-     * Set the friendly Bluetooth name of the local Bluetooth adapter.
-     * <p>This name is visible to remote Bluetooth devices.
-     * <p>Valid Bluetooth names are a maximum of 248 bytes using UTF-8
-     * encoding, although many remote devices can only display the first
-     * 40 characters, and some may be limited to just 20.
-     * <p>If Bluetooth state is not {@link #STATE_ON}, this API
-     * will return false. After turning on Bluetooth,
-     * wait for {@link #ACTION_STATE_CHANGED} with {@link #STATE_ON}
-     * to get the updated value.
-     *
-     * @param name a valid Bluetooth name
-     * @return true if the name was set, false otherwise
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean setName(String name) {
-        if (getState() != STATE_ON) {
-            return false;
-        }
-        try {
-            mServiceLock.readLock().lock();
-            if (mService != null) {
-                return mService.setName(name, mAttributionSource);
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        } finally {
-            mServiceLock.readLock().unlock();
-        }
-        return false;
-    }
-
-    /**
-     * Returns the {@link BluetoothClass} Bluetooth Class of Device (CoD) of the local Bluetooth
-     * adapter.
-     *
-     * @return {@link BluetoothClass} Bluetooth CoD of local Bluetooth device.
-     *
-     * @hide
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public BluetoothClass getBluetoothClass() {
-        if (getState() != STATE_ON) {
-            return null;
-        }
-        try {
-            mServiceLock.readLock().lock();
-            if (mService != null) {
-                return mService.getBluetoothClass(mAttributionSource);
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        } finally {
-            mServiceLock.readLock().unlock();
-        }
-        return null;
-    }
-
-    /**
-     * Sets the {@link BluetoothClass} Bluetooth Class of Device (CoD) of the local Bluetooth
-     * adapter.
-     *
-     * <p>Note: This value persists across system reboot.
-     *
-     * @param bluetoothClass {@link BluetoothClass} to set the local Bluetooth adapter to.
-     * @return true if successful, false if unsuccessful.
-     *
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public boolean setBluetoothClass(BluetoothClass bluetoothClass) {
-        if (getState() != STATE_ON) {
-            return false;
-        }
-        try {
-            mServiceLock.readLock().lock();
-            if (mService != null) {
-                return mService.setBluetoothClass(bluetoothClass, mAttributionSource);
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        } finally {
-            mServiceLock.readLock().unlock();
-        }
-        return false;
-    }
-
-    /**
-     * Returns the Input/Output capability of the device for classic Bluetooth.
-     *
-     * @return Input/Output capability of the device. One of {@link #IO_CAPABILITY_OUT},
-     *         {@link #IO_CAPABILITY_IO}, {@link #IO_CAPABILITY_IN}, {@link #IO_CAPABILITY_NONE},
-     *         {@link #IO_CAPABILITY_KBDISP} or {@link #IO_CAPABILITY_UNKNOWN}.
-     *
-     * @hide
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @IoCapability
-    public int getIoCapability() {
-        if (getState() != STATE_ON) return BluetoothAdapter.IO_CAPABILITY_UNKNOWN;
-        try {
-            mServiceLock.readLock().lock();
-            if (mService != null) return mService.getIoCapability(mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, e.getMessage(), e);
-        } finally {
-            mServiceLock.readLock().unlock();
-        }
-        return BluetoothAdapter.IO_CAPABILITY_UNKNOWN;
-    }
-
-    /**
-     * Sets the Input/Output capability of the device for classic Bluetooth.
-     *
-     * <p>Changing the Input/Output capability of a device only takes effect on restarting the
-     * Bluetooth stack. You would need to restart the stack using {@link BluetoothAdapter#disable()}
-     * and {@link BluetoothAdapter#enable()} to see the changes.
-     *
-     * @param capability Input/Output capability of the device. One of {@link #IO_CAPABILITY_OUT},
-     *                   {@link #IO_CAPABILITY_IO}, {@link #IO_CAPABILITY_IN},
-     *                   {@link #IO_CAPABILITY_NONE} or {@link #IO_CAPABILITY_KBDISP}.
-     *
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public boolean setIoCapability(@IoCapability int capability) {
-        if (getState() != STATE_ON) return false;
-        try {
-            mServiceLock.readLock().lock();
-            if (mService != null) return mService.setIoCapability(capability, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, e.getMessage(), e);
-        } finally {
-            mServiceLock.readLock().unlock();
-        }
-        return false;
-    }
-
-    /**
-     * Returns the Input/Output capability of the device for BLE operations.
-     *
-     * @return Input/Output capability of the device. One of {@link #IO_CAPABILITY_OUT},
-     *         {@link #IO_CAPABILITY_IO}, {@link #IO_CAPABILITY_IN}, {@link #IO_CAPABILITY_NONE},
-     *         {@link #IO_CAPABILITY_KBDISP} or {@link #IO_CAPABILITY_UNKNOWN}.
-     *
-     * @hide
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @IoCapability
-    public int getLeIoCapability() {
-        if (getState() != STATE_ON) return BluetoothAdapter.IO_CAPABILITY_UNKNOWN;
-        try {
-            mServiceLock.readLock().lock();
-            if (mService != null) return mService.getLeIoCapability(mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, e.getMessage(), e);
-        } finally {
-            mServiceLock.readLock().unlock();
-        }
-        return BluetoothAdapter.IO_CAPABILITY_UNKNOWN;
-    }
-
-    /**
-     * Sets the Input/Output capability of the device for BLE operations.
-     *
-     * <p>Changing the Input/Output capability of a device only takes effect on restarting the
-     * Bluetooth stack. You would need to restart the stack using {@link BluetoothAdapter#disable()}
-     * and {@link BluetoothAdapter#enable()} to see the changes.
-     *
-     * @param capability Input/Output capability of the device. One of {@link #IO_CAPABILITY_OUT},
-     *                   {@link #IO_CAPABILITY_IO}, {@link #IO_CAPABILITY_IN},
-     *                   {@link #IO_CAPABILITY_NONE} or {@link #IO_CAPABILITY_KBDISP}.
-     *
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public boolean setLeIoCapability(@IoCapability int capability) {
-        if (getState() != STATE_ON) return false;
-        try {
-            mServiceLock.readLock().lock();
-            if (mService != null) return mService.setLeIoCapability(capability, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, e.getMessage(), e);
-        } finally {
-            mServiceLock.readLock().unlock();
-        }
-        return false;
-    }
-
-    /**
-     * Get the current Bluetooth scan mode of the local Bluetooth adapter.
-     * <p>The Bluetooth scan mode determines if the local adapter is
-     * connectable and/or discoverable from remote Bluetooth devices.
-     * <p>Possible values are:
-     * {@link #SCAN_MODE_NONE},
-     * {@link #SCAN_MODE_CONNECTABLE},
-     * {@link #SCAN_MODE_CONNECTABLE_DISCOVERABLE}.
-     * <p>If Bluetooth state is not {@link #STATE_ON}, this API
-     * will return {@link #SCAN_MODE_NONE}. After turning on Bluetooth,
-     * wait for {@link #ACTION_STATE_CHANGED} with {@link #STATE_ON}
-     * to get the updated value.
-     *
-     * @return scan mode
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothScanPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
-    @ScanMode
-    public int getScanMode() {
-        if (getState() != STATE_ON) {
-            return SCAN_MODE_NONE;
-        }
-        try {
-            mServiceLock.readLock().lock();
-            if (mService != null) {
-                return mService.getScanMode(mAttributionSource);
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        } finally {
-            mServiceLock.readLock().unlock();
-        }
-        return SCAN_MODE_NONE;
-    }
-
-    /**
-     * Set the Bluetooth scan mode of the local Bluetooth adapter.
-     * <p>The Bluetooth scan mode determines if the local adapter is
-     * connectable and/or discoverable from remote Bluetooth devices.
-     * <p>For privacy reasons, discoverable mode is automatically turned off
-     * after <code>durationMillis</code> milliseconds. For example, 120000 milliseconds should be
-     * enough for a remote device to initiate and complete its discovery process.
-     * <p>Valid scan mode values are:
-     * {@link #SCAN_MODE_NONE},
-     * {@link #SCAN_MODE_CONNECTABLE},
-     * {@link #SCAN_MODE_CONNECTABLE_DISCOVERABLE}.
-     * <p>If Bluetooth state is not {@link #STATE_ON}, this API
-     * will return false. After turning on Bluetooth,
-     * wait for {@link #ACTION_STATE_CHANGED} with {@link #STATE_ON}
-     * to get the updated value.
-     * <p>Applications cannot set the scan mode. They should use
-     * <code>startActivityForResult(
-     * BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE})
-     * </code>instead.
-     *
-     * @param mode valid scan mode
-     * @param durationMillis time in milliseconds to apply scan mode, only used for {@link
-     * #SCAN_MODE_CONNECTABLE_DISCOVERABLE}
-     * @return true if the scan mode was set, false otherwise
-     * @hide
-     */
-    @UnsupportedAppUsage(publicAlternatives = "Use {@link #ACTION_REQUEST_DISCOVERABLE}, which "
-            + "shows UI that confirms the user wants to go into discoverable mode.")
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothScanPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
-    public boolean setScanMode(@ScanMode int mode, long durationMillis) {
-        if (getState() != STATE_ON) {
-            return false;
-        }
-        try {
-            mServiceLock.readLock().lock();
-            if (mService != null) {
-                int durationSeconds = Math.toIntExact(durationMillis / 1000);
-                return mService.setScanMode(mode, durationSeconds, mAttributionSource);
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        } catch (ArithmeticException ex) {
-            Log.e(TAG, "setScanMode: Duration in seconds outside of the bounds of an int");
-            throw new IllegalArgumentException("Duration not in bounds. In seconds, the "
-                    + "durationMillis must be in the range of an int");
-        } finally {
-            mServiceLock.readLock().unlock();
-        }
-        return false;
-    }
-
-    /**
-     * Set the Bluetooth scan mode of the local Bluetooth adapter.
-     * <p>The Bluetooth scan mode determines if the local adapter is
-     * connectable and/or discoverable from remote Bluetooth devices.
-     * <p>For privacy reasons, discoverable mode is automatically turned off
-     * after <code>duration</code> seconds. For example, 120 seconds should be
-     * enough for a remote device to initiate and complete its discovery
-     * process.
-     * <p>Valid scan mode values are:
-     * {@link #SCAN_MODE_NONE},
-     * {@link #SCAN_MODE_CONNECTABLE},
-     * {@link #SCAN_MODE_CONNECTABLE_DISCOVERABLE}.
-     * <p>If Bluetooth state is not {@link #STATE_ON}, this API
-     * will return false. After turning on Bluetooth,
-     * wait for {@link #ACTION_STATE_CHANGED} with {@link #STATE_ON}
-     * to get the updated value.
-     * <p>Applications cannot set the scan mode. They should use
-     * <code>startActivityForResult(
-     * BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE})
-     * </code>instead.
-     *
-     * @param mode valid scan mode
-     * @return true if the scan mode was set, false otherwise
-     * @hide
-     */
-    @UnsupportedAppUsage
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothScanPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
-    public boolean setScanMode(@ScanMode int mode) {
-        if (getState() != STATE_ON) {
-            return false;
-        }
-        try {
-            mServiceLock.readLock().lock();
-            if (mService != null) {
-                return mService.setScanMode(mode, getDiscoverableTimeout(), mAttributionSource);
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        } finally {
-            mServiceLock.readLock().unlock();
-        }
-        return false;
-    }
-
-    /** @hide */
-    @UnsupportedAppUsage
-    @RequiresBluetoothScanPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
-    public int getDiscoverableTimeout() {
-        if (getState() != STATE_ON) {
-            return -1;
-        }
-        try {
-            mServiceLock.readLock().lock();
-            if (mService != null) {
-                return mService.getDiscoverableTimeout(mAttributionSource);
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        } finally {
-            mServiceLock.readLock().unlock();
-        }
-        return -1;
-    }
-
-    /** @hide */
-    @UnsupportedAppUsage
-    @RequiresBluetoothScanPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
-    public void setDiscoverableTimeout(int timeout) {
-        if (getState() != STATE_ON) {
-            return;
-        }
-        try {
-            mServiceLock.readLock().lock();
-            if (mService != null) {
-                mService.setDiscoverableTimeout(timeout, mAttributionSource);
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        } finally {
-            mServiceLock.readLock().unlock();
-        }
-    }
-
-    /**
-     * Get the end time of the latest remote device discovery process.
-     *
-     * @return the latest time that the bluetooth adapter was/will be in discovery mode, in
-     * milliseconds since the epoch. This time can be in the future if {@link #startDiscovery()} has
-     * been called recently.
-     * @hide
-     */
-    @SystemApi
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public long getDiscoveryEndMillis() {
-        try {
-            mServiceLock.readLock().lock();
-            if (mService != null) {
-                return mService.getDiscoveryEndMillis(mAttributionSource);
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        } finally {
-            mServiceLock.readLock().unlock();
-        }
-        return -1;
-    }
-
-    /**
-     * Start the remote device discovery process.
-     * <p>The discovery process usually involves an inquiry scan of about 12
-     * seconds, followed by a page scan of each new device to retrieve its
-     * Bluetooth name.
-     * <p>This is an asynchronous call, it will return immediately. Register
-     * for {@link #ACTION_DISCOVERY_STARTED} and {@link
-     * #ACTION_DISCOVERY_FINISHED} intents to determine exactly when the
-     * discovery starts and completes. Register for {@link
-     * BluetoothDevice#ACTION_FOUND} to be notified as remote Bluetooth devices
-     * are found.
-     * <p>Device discovery is a heavyweight procedure. New connections to
-     * remote Bluetooth devices should not be attempted while discovery is in
-     * progress, and existing connections will experience limited bandwidth
-     * and high latency. Use {@link #cancelDiscovery()} to cancel an ongoing
-     * discovery. Discovery is not managed by the Activity,
-     * but is run as a system service, so an application should always call
-     * {@link BluetoothAdapter#cancelDiscovery()} even if it
-     * did not directly request a discovery, just to be sure.
-     * <p>Device discovery will only find remote devices that are currently
-     * <i>discoverable</i> (inquiry scan enabled). Many Bluetooth devices are
-     * not discoverable by default, and need to be entered into a special mode.
-     * <p>If Bluetooth state is not {@link #STATE_ON}, this API
-     * will return false. After turning on Bluetooth, wait for {@link #ACTION_STATE_CHANGED}
-     * with {@link #STATE_ON} to get the updated value.
-     * <p>If a device is currently bonding, this request will be queued and executed once that
-     * device has finished bonding. If a request is already queued, this request will be ignored.
-     *
-     * @return true on success, false on error
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothScanPermission
-    @RequiresBluetoothLocationPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
-    public boolean startDiscovery() {
-        if (getState() != STATE_ON) {
-            return false;
-        }
-        try {
-            mServiceLock.readLock().lock();
-            if (mService != null) {
-                return mService.startDiscovery(mAttributionSource);
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        } finally {
-            mServiceLock.readLock().unlock();
-        }
-        return false;
-    }
-
-    /**
-     * Cancel the current device discovery process.
-     * <p>Because discovery is a heavyweight procedure for the Bluetooth
-     * adapter, this method should always be called before attempting to connect
-     * to a remote device with {@link
-     * android.bluetooth.BluetoothSocket#connect()}. Discovery is not managed by
-     * the  Activity, but is run as a system service, so an application should
-     * always call cancel discovery even if it did not directly request a
-     * discovery, just to be sure.
-     * <p>If Bluetooth state is not {@link #STATE_ON}, this API
-     * will return false. After turning on Bluetooth,
-     * wait for {@link #ACTION_STATE_CHANGED} with {@link #STATE_ON}
-     * to get the updated value.
-     *
-     * @return true on success, false on error
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothScanPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
-    public boolean cancelDiscovery() {
-        if (getState() != STATE_ON) {
-            return false;
-        }
-        try {
-            mServiceLock.readLock().lock();
-            if (mService != null) {
-                return mService.cancelDiscovery(mAttributionSource);
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        } finally {
-            mServiceLock.readLock().unlock();
-        }
-        return false;
-    }
-
-    /**
-     * Return true if the local Bluetooth adapter is currently in the device
-     * discovery process.
-     * <p>Device discovery is a heavyweight procedure. New connections to
-     * remote Bluetooth devices should not be attempted while discovery is in
-     * progress, and existing connections will experience limited bandwidth
-     * and high latency. Use {@link #cancelDiscovery()} to cancel an ongoing
-     * discovery.
-     * <p>Applications can also register for {@link #ACTION_DISCOVERY_STARTED}
-     * or {@link #ACTION_DISCOVERY_FINISHED} to be notified when discovery
-     * starts or completes.
-     * <p>If Bluetooth state is not {@link #STATE_ON}, this API
-     * will return false. After turning on Bluetooth,
-     * wait for {@link #ACTION_STATE_CHANGED} with {@link #STATE_ON}
-     * to get the updated value.
-     *
-     * @return true if discovering
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothScanPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
-    public boolean isDiscovering() {
-        if (getState() != STATE_ON) {
-            return false;
-        }
-        try {
-            mServiceLock.readLock().lock();
-            if (mService != null) {
-                return mService.isDiscovering(mAttributionSource);
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        } finally {
-            mServiceLock.readLock().unlock();
-        }
-        return false;
-    }
-
-    /**
-     * Removes the active device for the grouping of @ActiveDeviceUse specified
-     *
-     * @param profiles represents the purpose for which we are setting this as the active device.
-     *                 Possible values are:
-     *                 {@link BluetoothAdapter#ACTIVE_DEVICE_AUDIO},
-     *                 {@link BluetoothAdapter#ACTIVE_DEVICE_PHONE_CALL},
-     *                 {@link BluetoothAdapter#ACTIVE_DEVICE_ALL}
-     * @return false on immediate error, true otherwise
-     * @throws IllegalArgumentException if device is null or profiles is not one of
-     * {@link ActiveDeviceUse}
-     * @hide
-     */
-    @SystemApi
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-            android.Manifest.permission.MODIFY_PHONE_STATE,
-    })
-    public boolean removeActiveDevice(@ActiveDeviceUse int profiles) {
-        if (profiles != ACTIVE_DEVICE_AUDIO && profiles != ACTIVE_DEVICE_PHONE_CALL
-                && profiles != ACTIVE_DEVICE_ALL) {
-            Log.e(TAG, "Invalid profiles param value in removeActiveDevice");
-            throw new IllegalArgumentException("Profiles must be one of "
-                    + "BluetoothAdapter.ACTIVE_DEVICE_AUDIO, "
-                    + "BluetoothAdapter.ACTIVE_DEVICE_PHONE_CALL, or "
-                    + "BluetoothAdapter.ACTIVE_DEVICE_ALL");
-        }
-        try {
-            mServiceLock.readLock().lock();
-            if (mService != null) {
-                if (DBG) Log.d(TAG, "removeActiveDevice, profiles: " + profiles);
-                return mService.removeActiveDevice(profiles, mAttributionSource);
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        } finally {
-            mServiceLock.readLock().unlock();
-        }
-
-        return false;
-    }
-
-    /**
-     * Sets device as the active devices for the profiles passed into the function
-     *
-     * @param device is the remote bluetooth device
-     * @param profiles represents the purpose for which we are setting this as the active device.
-     *                 Possible values are:
-     *                 {@link BluetoothAdapter#ACTIVE_DEVICE_AUDIO},
-     *                 {@link BluetoothAdapter#ACTIVE_DEVICE_PHONE_CALL},
-     *                 {@link BluetoothAdapter#ACTIVE_DEVICE_ALL}
-     * @return false on immediate error, true otherwise
-     * @throws IllegalArgumentException if device is null or profiles is not one of
-     * {@link ActiveDeviceUse}
-     * @hide
-     */
-    @SystemApi
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-            android.Manifest.permission.MODIFY_PHONE_STATE,
-    })
-    public boolean setActiveDevice(@NonNull BluetoothDevice device,
-            @ActiveDeviceUse int profiles) {
-        if (device == null) {
-            Log.e(TAG, "setActiveDevice: Null device passed as parameter");
-            throw new IllegalArgumentException("device cannot be null");
-        }
-        if (profiles != ACTIVE_DEVICE_AUDIO && profiles != ACTIVE_DEVICE_PHONE_CALL
-                && profiles != ACTIVE_DEVICE_ALL) {
-            Log.e(TAG, "Invalid profiles param value in setActiveDevice");
-            throw new IllegalArgumentException("Profiles must be one of "
-                    + "BluetoothAdapter.ACTIVE_DEVICE_AUDIO, "
-                    + "BluetoothAdapter.ACTIVE_DEVICE_PHONE_CALL, or "
-                    + "BluetoothAdapter.ACTIVE_DEVICE_ALL");
-        }
-        try {
-            mServiceLock.readLock().lock();
-            if (mService != null) {
-                if (DBG) {
-                    Log.d(TAG, "setActiveDevice, device: " + device + ", profiles: " + profiles);
-                }
-                return mService.setActiveDevice(device, profiles, mAttributionSource);
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        } finally {
-            mServiceLock.readLock().unlock();
-        }
-
-        return false;
-    }
-
-    /**
-     * Get the active devices for the BluetoothProfile specified
-     *
-     * @param profile is the profile from which we want the active devices.
-     *                Possible values are:
-     *                {@link BluetoothProfile#HEADSET},
-     *                {@link BluetoothProfile#A2DP},
-     *                {@link BluetoothProfile#HEARING_AID}
-     *                {@link BluetoothProfile#LE_AUDIO}
-     * @return A list of active bluetooth devices
-     * @throws IllegalArgumentException If profile is not one of {@link ActiveDeviceProfile}
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public @NonNull List<BluetoothDevice> getActiveDevices(@ActiveDeviceProfile int profile) {
-        if (profile != BluetoothProfile.HEADSET
-                && profile != BluetoothProfile.A2DP
-                && profile != BluetoothProfile.HEARING_AID
-                && profile != BluetoothProfile.LE_AUDIO) {
-            Log.e(TAG, "Invalid profile param value in getActiveDevices");
-            throw new IllegalArgumentException("Profiles must be one of "
-                    + "BluetoothProfile.A2DP, "
-                    + "BluetoothProfile.HEARING_AID, or"
-                    + "BluetoothProfile.HEARING_AID"
-                    + "BluetoothProfile.LE_AUDIO");
-        }
-        try {
-            mServiceLock.readLock().lock();
-            if (mService != null) {
-                if (DBG) {
-                    Log.d(TAG, "getActiveDevices(profile= "
-                            + BluetoothProfile.getProfileName(profile) + ")");
-                }
-                return mService.getActiveDevices(profile, mAttributionSource);
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        } finally {
-            mServiceLock.readLock().unlock();
-        }
-
-        return new ArrayList<>();
-    }
-
-    /**
-     * Return true if the multi advertisement is supported by the chipset
-     *
-     * @return true if Multiple Advertisement feature is supported
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresNoPermission
-    public boolean isMultipleAdvertisementSupported() {
-        if (getState() != STATE_ON) {
-            return false;
-        }
-        try {
-            mServiceLock.readLock().lock();
-            if (mService != null) {
-                return mService.isMultiAdvertisementSupported();
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "failed to get isMultipleAdvertisementSupported, error: ", e);
-        } finally {
-            mServiceLock.readLock().unlock();
-        }
-        return false;
-    }
-
-    /**
-     * Returns {@code true} if BLE scan is always available, {@code false} otherwise. <p>
-     *
-     * If this returns {@code true}, application can issue {@link BluetoothLeScanner#startScan} and
-     * fetch scan results even when Bluetooth is turned off.<p>
-     *
-     * To change this setting, use {@link #ACTION_REQUEST_BLE_SCAN_ALWAYS_AVAILABLE}.
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresNoPermission
-    public boolean isBleScanAlwaysAvailable() {
-        try {
-            return mManagerService.isBleScanAlwaysAvailable();
-        } catch (RemoteException e) {
-            Log.e(TAG, "remote exception when calling isBleScanAlwaysAvailable", e);
-            return false;
-        }
-    }
-
-    private static final String BLUETOOTH_FILTERING_CACHE_PROPERTY =
-            "cache_key.bluetooth.is_offloaded_filtering_supported";
-    private final PropertyInvalidatedCache<Void, Boolean> mBluetoothFilteringCache =
-            new PropertyInvalidatedCache<Void, Boolean>(
-                8, BLUETOOTH_FILTERING_CACHE_PROPERTY) {
-                @Override
-                @SuppressLint("AndroidFrameworkRequiresPermission")
-                protected Boolean recompute(Void query) {
-                    try {
-                        mServiceLock.readLock().lock();
-                        if (mService != null) {
-                            return mService.isOffloadedFilteringSupported();
-                        }
-                    } catch (RemoteException e) {
-                        Log.e(TAG, "failed to get isOffloadedFilteringSupported, error: ", e);
-                    } finally {
-                        mServiceLock.readLock().unlock();
-                    }
-                    return false;
-
-                }
-            };
-
-    /** @hide */
-    @RequiresNoPermission
-    public void disableIsOffloadedFilteringSupportedCache() {
-        mBluetoothFilteringCache.disableLocal();
-    }
-
-    /** @hide */
-    public static void invalidateIsOffloadedFilteringSupportedCache() {
-        PropertyInvalidatedCache.invalidateCache(BLUETOOTH_FILTERING_CACHE_PROPERTY);
-    }
-
-    /**
-     * Return true if offloaded filters are supported
-     *
-     * @return true if chipset supports on-chip filtering
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresNoPermission
-    public boolean isOffloadedFilteringSupported() {
-        if (!getLeAccess()) {
-            return false;
-        }
-        return mBluetoothFilteringCache.query(null);
-    }
-
-    /**
-     * Return true if offloaded scan batching is supported
-     *
-     * @return true if chipset supports on-chip scan batching
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresNoPermission
-    public boolean isOffloadedScanBatchingSupported() {
-        if (!getLeAccess()) {
-            return false;
-        }
-        try {
-            mServiceLock.readLock().lock();
-            if (mService != null) {
-                return mService.isOffloadedScanBatchingSupported();
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "failed to get isOffloadedScanBatchingSupported, error: ", e);
-        } finally {
-            mServiceLock.readLock().unlock();
-        }
-        return false;
-    }
-
-    /**
-     * Return true if LE 2M PHY feature is supported.
-     *
-     * @return true if chipset supports LE 2M PHY feature
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresNoPermission
-    public boolean isLe2MPhySupported() {
-        if (!getLeAccess()) {
-            return false;
-        }
-        try {
-            mServiceLock.readLock().lock();
-            if (mService != null) {
-                return mService.isLe2MPhySupported();
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "failed to get isExtendedAdvertisingSupported, error: ", e);
-        } finally {
-            mServiceLock.readLock().unlock();
-        }
-        return false;
-    }
-
-    /**
-     * Return true if LE Coded PHY feature is supported.
-     *
-     * @return true if chipset supports LE Coded PHY feature
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresNoPermission
-    public boolean isLeCodedPhySupported() {
-        if (!getLeAccess()) {
-            return false;
-        }
-        try {
-            mServiceLock.readLock().lock();
-            if (mService != null) {
-                return mService.isLeCodedPhySupported();
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "failed to get isLeCodedPhySupported, error: ", e);
-        } finally {
-            mServiceLock.readLock().unlock();
-        }
-        return false;
-    }
-
-    /**
-     * Return true if LE Extended Advertising feature is supported.
-     *
-     * @return true if chipset supports LE Extended Advertising feature
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresNoPermission
-    public boolean isLeExtendedAdvertisingSupported() {
-        if (!getLeAccess()) {
-            return false;
-        }
-        try {
-            mServiceLock.readLock().lock();
-            if (mService != null) {
-                return mService.isLeExtendedAdvertisingSupported();
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "failed to get isLeExtendedAdvertisingSupported, error: ", e);
-        } finally {
-            mServiceLock.readLock().unlock();
-        }
-        return false;
-    }
-
-    /**
-     * Return true if LE Periodic Advertising feature is supported.
-     *
-     * @return true if chipset supports LE Periodic Advertising feature
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresNoPermission
-    public boolean isLePeriodicAdvertisingSupported() {
-        if (!getLeAccess()) {
-            return false;
-        }
-        try {
-            mServiceLock.readLock().lock();
-            if (mService != null) {
-                return mService.isLePeriodicAdvertisingSupported();
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "failed to get isLePeriodicAdvertisingSupported, error: ", e);
-        } finally {
-            mServiceLock.readLock().unlock();
-        }
-        return false;
-    }
-
-    /** @hide */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(value = {
-            BluetoothStatusCodes.SUCCESS,
-            BluetoothStatusCodes.ERROR_UNKNOWN,
-            BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED,
-            BluetoothStatusCodes.ERROR_FEATURE_NOT_SUPPORTED,
-    })
-    public @interface LeFeatureReturnValues {}
-
-    /**
-     * Returns {@link BluetoothStatusCodes#SUCCESS} if the LE audio feature is
-     * supported, returns {@link BluetoothStatusCodes#ERROR_FEATURE_NOT_SUPPORTED} if
-     * the feature is not supported or an error code.
-     *
-     * @return whether the LE audio is supported
-     */
-    @RequiresNoPermission
-    public @LeFeatureReturnValues int isLeAudioSupported() {
-        if (!getLeAccess()) {
-            return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED;
-        }
-        try {
-            mServiceLock.readLock().lock();
-            if (mService != null) {
-                return mService.isLeAudioSupported();
-            }
-        } catch (RemoteException e) {
-            e.rethrowFromSystemServer();
-        } finally {
-            mServiceLock.readLock().unlock();
-        }
-        return BluetoothStatusCodes.ERROR_UNKNOWN;
-    }
-
-    /**
-     * Returns {@link BluetoothStatusCodes#SUCCESS} if LE Periodic Advertising Sync Transfer Sender
-     * feature is supported, returns {@link BluetoothStatusCodes#ERROR_FEATURE_NOT_SUPPORTED} if the
-     * feature is not supported or an error code
-     *
-     * @return whether the chipset supports the LE Periodic Advertising Sync Transfer Sender feature
-     */
-    @RequiresNoPermission
-    public @LeFeatureReturnValues int isLePeriodicAdvertisingSyncTransferSenderSupported() {
-        if (!getLeAccess()) {
-            return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED;
-        }
-        try {
-            mServiceLock.readLock().lock();
-            if (mService != null) {
-                return mService.isLePeriodicAdvertisingSyncTransferSenderSupported();
-            }
-        } catch (RemoteException e) {
-            e.rethrowFromSystemServer();
-        } finally {
-            mServiceLock.readLock().unlock();
-        }
-        return BluetoothStatusCodes.ERROR_UNKNOWN;
-    }
-
-    /**
-     * Return the maximum LE advertising data length in bytes,
-     * if LE Extended Advertising feature is supported, 0 otherwise.
-     *
-     * @return the maximum LE advertising data length.
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresNoPermission
-    public int getLeMaximumAdvertisingDataLength() {
-        if (!getLeAccess()) {
-            return 0;
-        }
-        try {
-            mServiceLock.readLock().lock();
-            if (mService != null) {
-                return mService.getLeMaximumAdvertisingDataLength();
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "failed to get getLeMaximumAdvertisingDataLength, error: ", e);
-        } finally {
-            mServiceLock.readLock().unlock();
-        }
-        return 0;
-    }
-
-    /**
-     * Return true if Hearing Aid Profile is supported.
-     *
-     * @return true if phone supports Hearing Aid Profile
-     */
-    @RequiresNoPermission
-    private boolean isHearingAidProfileSupported() {
-        try {
-            return mManagerService.isHearingAidProfileSupported();
-        } catch (RemoteException e) {
-            Log.e(TAG, "remote exception when calling isHearingAidProfileSupported", e);
-            return false;
-        }
-    }
-
-    /**
-     * Get the maximum number of connected audio devices.
-     *
-     * @return the maximum number of connected audio devices
-     * @hide
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public int getMaxConnectedAudioDevices() {
-        try {
-            mServiceLock.readLock().lock();
-            if (mService != null) {
-                return mService.getMaxConnectedAudioDevices(mAttributionSource);
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "failed to get getMaxConnectedAudioDevices, error: ", e);
-        } finally {
-            mServiceLock.readLock().unlock();
-        }
-        return 1;
-    }
-
-    /**
-     * Return true if hardware has entries available for matching beacons
-     *
-     * @return true if there are hw entries available for matching beacons
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean isHardwareTrackingFiltersAvailable() {
-        if (!getLeAccess()) {
-            return false;
-        }
-        try {
-            IBluetoothGatt iGatt = mManagerService.getBluetoothGatt();
-            if (iGatt == null) {
-                // BLE is not supported
-                return false;
-            }
-            return (iGatt.numHwTrackFiltersAvailable(mAttributionSource) != 0);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        }
-        return false;
-    }
-
-    /**
-     * Request the record of {@link BluetoothActivityEnergyInfo} object that
-     * has the activity and energy info. This can be used to ascertain what
-     * the controller has been up to, since the last sample.
-     *
-     * A null value for the activity info object may be sent if the bluetooth service is
-     * unreachable or the device does not support reporting such information.
-     *
-     * @param result The callback to which to send the activity info.
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public void requestControllerActivityEnergyInfo(ResultReceiver result) {
-        try {
-            mServiceLock.readLock().lock();
-            if (mService != null) {
-                mService.requestActivityInfo(result, mAttributionSource);
-                result = null;
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "getControllerActivityEnergyInfoCallback: " + e);
-        } finally {
-            mServiceLock.readLock().unlock();
-            if (result != null) {
-                // Only send an immediate result if we failed.
-                result.send(0, null);
-            }
-        }
-    }
-
-    /**
-     * Fetches a list of the most recently connected bluetooth devices ordered by how recently they
-     * were connected with most recently first and least recently last
-     *
-     * @return {@link List} of bonded {@link BluetoothDevice} ordered by how recently they were
-     * connected
-     *
-     * @hide
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public @NonNull List<BluetoothDevice> getMostRecentlyConnectedDevices() {
-        if (getState() != STATE_ON) {
-            return new ArrayList<>();
-        }
-        try {
-            mServiceLock.readLock().lock();
-            if (mService != null) {
-                return Attributable.setAttributionSource(
-                        mService.getMostRecentlyConnectedDevices(mAttributionSource),
-                        mAttributionSource);
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        } finally {
-            mServiceLock.readLock().unlock();
-        }
-        return new ArrayList<>();
-    }
-
-    /**
-     * Return the set of {@link BluetoothDevice} objects that are bonded
-     * (paired) to the local adapter.
-     * <p>If Bluetooth state is not {@link #STATE_ON}, this API
-     * will return an empty set. After turning on Bluetooth,
-     * wait for {@link #ACTION_STATE_CHANGED} with {@link #STATE_ON}
-     * to get the updated value.
-     *
-     * @return unmodifiable set of {@link BluetoothDevice}, or null on error
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public Set<BluetoothDevice> getBondedDevices() {
-        if (getState() != STATE_ON) {
-            return toDeviceSet(Arrays.asList());
-        }
-        try {
-            mServiceLock.readLock().lock();
-            if (mService != null) {
-                return toDeviceSet(Attributable.setAttributionSource(
-                        Arrays.asList(mService.getBondedDevices(mAttributionSource)),
-                        mAttributionSource));
-            }
-            return toDeviceSet(Arrays.asList());
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        } finally {
-            mServiceLock.readLock().unlock();
-        }
-        return null;
-    }
-
-    /**
-     * Gets the currently supported profiles by the adapter.
-     *
-     * <p> This can be used to check whether a profile is supported before attempting
-     * to connect to its respective proxy.
-     *
-     * @return a list of integers indicating the ids of supported profiles as defined in {@link
-     * BluetoothProfile}.
-     * @hide
-     */
-    @RequiresNoPermission
-    public @NonNull List<Integer> getSupportedProfiles() {
-        final ArrayList<Integer> supportedProfiles = new ArrayList<Integer>();
-
-        try {
-            synchronized (mManagerCallback) {
-                if (mService != null) {
-                    final long supportedProfilesBitMask = mService.getSupportedProfiles();
-
-                    for (int i = 0; i <= BluetoothProfile.MAX_PROFILE_ID; i++) {
-                        if ((supportedProfilesBitMask & (1 << i)) != 0) {
-                            supportedProfiles.add(i);
-                        }
-                    }
-                } else {
-                    // Bluetooth is disabled. Just fill in known supported Profiles
-                    if (isHearingAidProfileSupported()) {
-                        supportedProfiles.add(BluetoothProfile.HEARING_AID);
-                    }
-                }
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "getSupportedProfiles:", e);
-        }
-        return supportedProfiles;
-    }
-
-    private static final String BLUETOOTH_GET_ADAPTER_CONNECTION_STATE_CACHE_PROPERTY =
-            "cache_key.bluetooth.get_adapter_connection_state";
-    private final PropertyInvalidatedCache<Void, Integer>
-            mBluetoothGetAdapterConnectionStateCache =
-            new PropertyInvalidatedCache<Void, Integer> (
-                8, BLUETOOTH_GET_ADAPTER_CONNECTION_STATE_CACHE_PROPERTY) {
-                /**
-                 * This method must not be called when mService is null.
-                 */
-                @Override
-                @SuppressLint("AndroidFrameworkRequiresPermission")
-                protected Integer recompute(Void query) {
-                    try {
-                        return mService.getAdapterConnectionState();
-                    } catch (RemoteException e) {
-                        throw e.rethrowAsRuntimeException();
-                    }
-                }
-            };
-
-    /** @hide */
-    @RequiresNoPermission
-    public void disableGetAdapterConnectionStateCache() {
-        mBluetoothGetAdapterConnectionStateCache.disableLocal();
-    }
-
-    /** @hide */
-    public static void invalidateGetAdapterConnectionStateCache() {
-        PropertyInvalidatedCache.invalidateCache(
-            BLUETOOTH_GET_ADAPTER_CONNECTION_STATE_CACHE_PROPERTY);
-    }
-
-    /**
-     * Get the current connection state of the local Bluetooth adapter.
-     * This can be used to check whether the local Bluetooth adapter is connected
-     * to any profile of any other remote Bluetooth Device.
-     *
-     * <p> Use this function along with {@link #ACTION_CONNECTION_STATE_CHANGED}
-     * intent to get the connection state of the adapter.
-     *
-     * @return One of {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTED}, {@link
-     * #STATE_CONNECTING} or {@link #STATE_DISCONNECTED}
-     * @hide
-     */
-    @UnsupportedAppUsage
-    @RequiresLegacyBluetoothPermission
-    @RequiresNoPermission
-    public int getConnectionState() {
-        if (getState() != STATE_ON) {
-            return BluetoothAdapter.STATE_DISCONNECTED;
-        }
-        try {
-            mServiceLock.readLock().lock();
-            if (mService != null) {
-                return mBluetoothGetAdapterConnectionStateCache.query(null);
-            }
-        } catch (RuntimeException e) {
-            if (e.getCause() instanceof RemoteException) {
-                Log.e(TAG, "getConnectionState:", e.getCause());
-            } else {
-                throw e;
-            }
-        } finally {
-            mServiceLock.readLock().unlock();
-        }
-        return BluetoothAdapter.STATE_DISCONNECTED;
-    }
-
-    private static final String BLUETOOTH_PROFILE_CACHE_PROPERTY =
-            "cache_key.bluetooth.get_profile_connection_state";
-    private final PropertyInvalidatedCache<Integer, Integer>
-            mGetProfileConnectionStateCache =
-            new PropertyInvalidatedCache<Integer, Integer>(
-                8, BLUETOOTH_PROFILE_CACHE_PROPERTY) {
-                @Override
-                @SuppressLint("AndroidFrameworkRequiresPermission")
-                protected Integer recompute(Integer query) {
-                    try {
-                        mServiceLock.readLock().lock();
-                        if (mService != null) {
-                            return mService.getProfileConnectionState(query);
-                        }
-                    } catch (RemoteException e) {
-                        Log.e(TAG, "getProfileConnectionState:", e);
-                    } finally {
-                        mServiceLock.readLock().unlock();
-                    }
-                    return BluetoothProfile.STATE_DISCONNECTED;
-                }
-                @Override
-                public String queryToString(Integer query) {
-                    return String.format("getProfileConnectionState(profile=\"%d\")",
-                                         query);
-                }
-            };
-
-    /** @hide */
-    @RequiresNoPermission
-    public void disableGetProfileConnectionStateCache() {
-        mGetProfileConnectionStateCache.disableLocal();
-    }
-
-    /** @hide */
-    public static void invalidateGetProfileConnectionStateCache() {
-        PropertyInvalidatedCache.invalidateCache(BLUETOOTH_PROFILE_CACHE_PROPERTY);
-    }
-
-    /**
-     * Get the current connection state of a profile.
-     * This function can be used to check whether the local Bluetooth adapter
-     * is connected to any remote device for a specific profile.
-     * Profile can be one of {@link BluetoothProfile#HEADSET}, {@link BluetoothProfile#A2DP}.
-     *
-     * <p> Return value can be one of
-     * {@link BluetoothProfile#STATE_DISCONNECTED},
-     * {@link BluetoothProfile#STATE_CONNECTING},
-     * {@link BluetoothProfile#STATE_CONNECTED},
-     * {@link BluetoothProfile#STATE_DISCONNECTING}
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SuppressLint("AndroidFrameworkRequiresPermission")
-    public int getProfileConnectionState(int profile) {
-        if (getState() != STATE_ON) {
-            return BluetoothProfile.STATE_DISCONNECTED;
-        }
-        return mGetProfileConnectionStateCache.query(new Integer(profile));
-    }
-
-    /**
-     * Create a listening, secure RFCOMM Bluetooth socket.
-     * <p>A remote device connecting to this socket will be authenticated and
-     * communication on this socket will be encrypted.
-     * <p>Use {@link BluetoothServerSocket#accept} to retrieve incoming
-     * connections from a listening {@link BluetoothServerSocket}.
-     * <p>Valid RFCOMM channels are in range 1 to 30.
-     *
-     * @param channel RFCOMM channel to listen on
-     * @return a listening RFCOMM BluetoothServerSocket
-     * @throws IOException on error, for example Bluetooth not available, or insufficient
-     * permissions, or channel in use.
-     * @hide
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public BluetoothServerSocket listenUsingRfcommOn(int channel) throws IOException {
-        return listenUsingRfcommOn(channel, false, false);
-    }
-
-    /**
-     * Create a listening, secure RFCOMM Bluetooth socket.
-     * <p>A remote device connecting to this socket will be authenticated and
-     * communication on this socket will be encrypted.
-     * <p>Use {@link BluetoothServerSocket#accept} to retrieve incoming
-     * connections from a listening {@link BluetoothServerSocket}.
-     * <p>Valid RFCOMM channels are in range 1 to 30.
-     * <p>To auto assign a channel without creating a SDP record use
-     * {@link #SOCKET_CHANNEL_AUTO_STATIC_NO_SDP} as channel number.
-     *
-     * @param channel RFCOMM channel to listen on
-     * @param mitm enforce person-in-the-middle protection for authentication.
-     * @param min16DigitPin enforce a pin key length og minimum 16 digit for sec mode 2
-     * connections.
-     * @return a listening RFCOMM BluetoothServerSocket
-     * @throws IOException on error, for example Bluetooth not available, or insufficient
-     * permissions, or channel in use.
-     * @hide
-     */
-    @UnsupportedAppUsage
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public BluetoothServerSocket listenUsingRfcommOn(int channel, boolean mitm,
-            boolean min16DigitPin) throws IOException {
-        BluetoothServerSocket socket =
-                new BluetoothServerSocket(BluetoothSocket.TYPE_RFCOMM, true, true, channel, mitm,
-                        min16DigitPin);
-        int errno = socket.mSocket.bindListen();
-        if (channel == SOCKET_CHANNEL_AUTO_STATIC_NO_SDP) {
-            socket.setChannel(socket.mSocket.getPort());
-        }
-        if (errno != 0) {
-            //TODO(BT): Throw the same exception error code
-            // that the previous code was using.
-            //socket.mSocket.throwErrnoNative(errno);
-            throw new IOException("Error: " + errno);
-        }
-        return socket;
-    }
-
-    /**
-     * Create a listening, secure RFCOMM Bluetooth socket with Service Record.
-     * <p>A remote device connecting to this socket will be authenticated and
-     * communication on this socket will be encrypted.
-     * <p>Use {@link BluetoothServerSocket#accept} to retrieve incoming
-     * connections from a listening {@link BluetoothServerSocket}.
-     * <p>The system will assign an unused RFCOMM channel to listen on.
-     * <p>The system will also register a Service Discovery
-     * Protocol (SDP) record with the local SDP server containing the specified
-     * UUID, service name, and auto-assigned channel. Remote Bluetooth devices
-     * can use the same UUID to query our SDP server and discover which channel
-     * to connect to. This SDP record will be removed when this socket is
-     * closed, or if this application closes unexpectedly.
-     * <p>Use {@link BluetoothDevice#createRfcommSocketToServiceRecord} to
-     * connect to this socket from another device using the same {@link UUID}.
-     *
-     * @param name service name for SDP record
-     * @param uuid uuid for SDP record
-     * @return a listening RFCOMM BluetoothServerSocket
-     * @throws IOException on error, for example Bluetooth not available, or insufficient
-     * permissions, or channel in use.
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public BluetoothServerSocket listenUsingRfcommWithServiceRecord(String name, UUID uuid)
-            throws IOException {
-        return createNewRfcommSocketAndRecord(name, uuid, true, true);
-    }
-
-    /**
-     * Create a listening, insecure RFCOMM Bluetooth socket with Service Record.
-     * <p>The link key is not required to be authenticated, i.e the communication may be
-     * vulnerable to Person In the Middle attacks. For Bluetooth 2.1 devices,
-     * the link will be encrypted, as encryption is mandatory.
-     * For legacy devices (pre Bluetooth 2.1 devices) the link will not
-     * be encrypted. Use {@link #listenUsingRfcommWithServiceRecord}, if an
-     * encrypted and authenticated communication channel is desired.
-     * <p>Use {@link BluetoothServerSocket#accept} to retrieve incoming
-     * connections from a listening {@link BluetoothServerSocket}.
-     * <p>The system will assign an unused RFCOMM channel to listen on.
-     * <p>The system will also register a Service Discovery
-     * Protocol (SDP) record with the local SDP server containing the specified
-     * UUID, service name, and auto-assigned channel. Remote Bluetooth devices
-     * can use the same UUID to query our SDP server and discover which channel
-     * to connect to. This SDP record will be removed when this socket is
-     * closed, or if this application closes unexpectedly.
-     * <p>Use {@link BluetoothDevice#createRfcommSocketToServiceRecord} to
-     * connect to this socket from another device using the same {@link UUID}.
-     *
-     * @param name service name for SDP record
-     * @param uuid uuid for SDP record
-     * @return a listening RFCOMM BluetoothServerSocket
-     * @throws IOException on error, for example Bluetooth not available, or insufficient
-     * permissions, or channel in use.
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public BluetoothServerSocket listenUsingInsecureRfcommWithServiceRecord(String name, UUID uuid)
-            throws IOException {
-        return createNewRfcommSocketAndRecord(name, uuid, false, false);
-    }
-
-    /**
-     * Create a listening, encrypted,
-     * RFCOMM Bluetooth socket with Service Record.
-     * <p>The link will be encrypted, but the link key is not required to be authenticated
-     * i.e the communication is vulnerable to Person In the Middle attacks. Use
-     * {@link #listenUsingRfcommWithServiceRecord}, to ensure an authenticated link key.
-     * <p> Use this socket if authentication of link key is not possible.
-     * For example, for Bluetooth 2.1 devices, if any of the devices does not have
-     * an input and output capability or just has the ability to display a numeric key,
-     * a secure socket connection is not possible and this socket can be used.
-     * Use {@link #listenUsingInsecureRfcommWithServiceRecord}, if encryption is not required.
-     * For Bluetooth 2.1 devices, the link will be encrypted, as encryption is mandatory.
-     * For more details, refer to the Security Model section 5.2 (vol 3) of
-     * Bluetooth Core Specification version 2.1 + EDR.
-     * <p>Use {@link BluetoothServerSocket#accept} to retrieve incoming
-     * connections from a listening {@link BluetoothServerSocket}.
-     * <p>The system will assign an unused RFCOMM channel to listen on.
-     * <p>The system will also register a Service Discovery
-     * Protocol (SDP) record with the local SDP server containing the specified
-     * UUID, service name, and auto-assigned channel. Remote Bluetooth devices
-     * can use the same UUID to query our SDP server and discover which channel
-     * to connect to. This SDP record will be removed when this socket is
-     * closed, or if this application closes unexpectedly.
-     * <p>Use {@link BluetoothDevice#createRfcommSocketToServiceRecord} to
-     * connect to this socket from another device using the same {@link UUID}.
-     *
-     * @param name service name for SDP record
-     * @param uuid uuid for SDP record
-     * @return a listening RFCOMM BluetoothServerSocket
-     * @throws IOException on error, for example Bluetooth not available, or insufficient
-     * permissions, or channel in use.
-     * @hide
-     */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public BluetoothServerSocket listenUsingEncryptedRfcommWithServiceRecord(String name, UUID uuid)
-            throws IOException {
-        return createNewRfcommSocketAndRecord(name, uuid, false, true);
-    }
-
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    private BluetoothServerSocket createNewRfcommSocketAndRecord(String name, UUID uuid,
-            boolean auth, boolean encrypt) throws IOException {
-        BluetoothServerSocket socket;
-        socket = new BluetoothServerSocket(BluetoothSocket.TYPE_RFCOMM, auth, encrypt,
-                new ParcelUuid(uuid));
-        socket.setServiceName(name);
-        int errno = socket.mSocket.bindListen();
-        if (errno != 0) {
-            //TODO(BT): Throw the same exception error code
-            // that the previous code was using.
-            //socket.mSocket.throwErrnoNative(errno);
-            throw new IOException("Error: " + errno);
-        }
-        return socket;
-    }
-
-    /**
-     * Construct an unencrypted, unauthenticated, RFCOMM server socket.
-     * Call #accept to retrieve connections to this socket.
-     *
-     * @return An RFCOMM BluetoothServerSocket
-     * @throws IOException On error, for example Bluetooth not available, or insufficient
-     * permissions.
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public BluetoothServerSocket listenUsingInsecureRfcommOn(int port) throws IOException {
-        BluetoothServerSocket socket =
-                new BluetoothServerSocket(BluetoothSocket.TYPE_RFCOMM, false, false, port);
-        int errno = socket.mSocket.bindListen();
-        if (port == SOCKET_CHANNEL_AUTO_STATIC_NO_SDP) {
-            socket.setChannel(socket.mSocket.getPort());
-        }
-        if (errno != 0) {
-            //TODO(BT): Throw the same exception error code
-            // that the previous code was using.
-            //socket.mSocket.throwErrnoNative(errno);
-            throw new IOException("Error: " + errno);
-        }
-        return socket;
-    }
-
-    /**
-     * Construct an encrypted, authenticated, L2CAP server socket.
-     * Call #accept to retrieve connections to this socket.
-     * <p>To auto assign a port without creating a SDP record use
-     * {@link #SOCKET_CHANNEL_AUTO_STATIC_NO_SDP} as port number.
-     *
-     * @param port the PSM to listen on
-     * @param mitm enforce person-in-the-middle protection for authentication.
-     * @param min16DigitPin enforce a pin key length og minimum 16 digit for sec mode 2
-     * connections.
-     * @return An L2CAP BluetoothServerSocket
-     * @throws IOException On error, for example Bluetooth not available, or insufficient
-     * permissions.
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public BluetoothServerSocket listenUsingL2capOn(int port, boolean mitm, boolean min16DigitPin)
-            throws IOException {
-        BluetoothServerSocket socket =
-                new BluetoothServerSocket(BluetoothSocket.TYPE_L2CAP, true, true, port, mitm,
-                        min16DigitPin);
-        int errno = socket.mSocket.bindListen();
-        if (port == SOCKET_CHANNEL_AUTO_STATIC_NO_SDP) {
-            int assignedChannel = socket.mSocket.getPort();
-            if (DBG) Log.d(TAG, "listenUsingL2capOn: set assigned channel to " + assignedChannel);
-            socket.setChannel(assignedChannel);
-        }
-        if (errno != 0) {
-            //TODO(BT): Throw the same exception error code
-            // that the previous code was using.
-            //socket.mSocket.throwErrnoNative(errno);
-            throw new IOException("Error: " + errno);
-        }
-        return socket;
-    }
-
-    /**
-     * Construct an encrypted, authenticated, L2CAP server socket.
-     * Call #accept to retrieve connections to this socket.
-     * <p>To auto assign a port without creating a SDP record use
-     * {@link #SOCKET_CHANNEL_AUTO_STATIC_NO_SDP} as port number.
-     *
-     * @param port the PSM to listen on
-     * @return An L2CAP BluetoothServerSocket
-     * @throws IOException On error, for example Bluetooth not available, or insufficient
-     * permissions.
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public BluetoothServerSocket listenUsingL2capOn(int port) throws IOException {
-        return listenUsingL2capOn(port, false, false);
-    }
-
-    /**
-     * Construct an insecure L2CAP server socket.
-     * Call #accept to retrieve connections to this socket.
-     * <p>To auto assign a port without creating a SDP record use
-     * {@link #SOCKET_CHANNEL_AUTO_STATIC_NO_SDP} as port number.
-     *
-     * @param port the PSM to listen on
-     * @return An L2CAP BluetoothServerSocket
-     * @throws IOException On error, for example Bluetooth not available, or insufficient
-     * permissions.
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public BluetoothServerSocket listenUsingInsecureL2capOn(int port) throws IOException {
-        Log.d(TAG, "listenUsingInsecureL2capOn: port=" + port);
-        BluetoothServerSocket socket =
-                new BluetoothServerSocket(BluetoothSocket.TYPE_L2CAP, false, false, port, false,
-                                          false);
-        int errno = socket.mSocket.bindListen();
-        if (port == SOCKET_CHANNEL_AUTO_STATIC_NO_SDP) {
-            int assignedChannel = socket.mSocket.getPort();
-            if (DBG) {
-                Log.d(TAG, "listenUsingInsecureL2capOn: set assigned channel to "
-                        + assignedChannel);
-            }
-            socket.setChannel(assignedChannel);
-        }
-        if (errno != 0) {
-            //TODO(BT): Throw the same exception error code
-            // that the previous code was using.
-            //socket.mSocket.throwErrnoNative(errno);
-            throw new IOException("Error: " + errno);
-        }
-        return socket;
-
-    }
-
-    /**
-     * Read the local Out of Band Pairing Data
-     *
-     * @return Pair<byte[], byte[]> of Hash and Randomizer
-     * @hide
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SuppressLint("AndroidFrameworkRequiresPermission")
-    public Pair<byte[], byte[]> readOutOfBandData() {
-        return null;
-    }
-
-    /**
-     * Get the profile proxy object associated with the profile.
-     *
-     * <p>Profile can be one of {@link BluetoothProfile#HEADSET}, {@link BluetoothProfile#A2DP},
-     * {@link BluetoothProfile#GATT}, {@link BluetoothProfile#HEARING_AID}, or {@link
-     * BluetoothProfile#GATT_SERVER}. Clients must implement {@link
-     * BluetoothProfile.ServiceListener} to get notified of the connection status and to get the
-     * proxy object.
-     *
-     * @param context Context of the application
-     * @param listener The service Listener for connection callbacks.
-     * @param profile The Bluetooth profile; either {@link BluetoothProfile#HEADSET},
-     * {@link BluetoothProfile#A2DP}, {@link BluetoothProfile#GATT}, {@link
-     * BluetoothProfile#HEARING_AID} or {@link BluetoothProfile#GATT_SERVER}.
-     * @return true on success, false on error
-     */
-    @SuppressLint({
-        "AndroidFrameworkRequiresPermission",
-        "AndroidFrameworkBluetoothPermission"
-    })
-    public boolean getProfileProxy(Context context, BluetoothProfile.ServiceListener listener,
-            int profile) {
-        if (context == null || listener == null) {
-            return false;
-        }
-
-        if (profile == BluetoothProfile.HEADSET) {
-            BluetoothHeadset headset = new BluetoothHeadset(context, listener, this);
-            return true;
-        } else if (profile == BluetoothProfile.A2DP) {
-            BluetoothA2dp a2dp = new BluetoothA2dp(context, listener, this);
-            return true;
-        } else if (profile == BluetoothProfile.A2DP_SINK) {
-            BluetoothA2dpSink a2dpSink = new BluetoothA2dpSink(context, listener, this);
-            return true;
-        } else if (profile == BluetoothProfile.AVRCP_CONTROLLER) {
-            BluetoothAvrcpController avrcp = new BluetoothAvrcpController(context, listener, this);
-            return true;
-        } else if (profile == BluetoothProfile.HID_HOST) {
-            BluetoothHidHost iDev = new BluetoothHidHost(context, listener, this);
-            return true;
-        } else if (profile == BluetoothProfile.PAN) {
-            BluetoothPan pan = new BluetoothPan(context, listener, this);
-            return true;
-        } else if (profile == BluetoothProfile.PBAP) {
-            BluetoothPbap pbap = new BluetoothPbap(context, listener, this);
-            return true;
-        } else if (profile == BluetoothProfile.HEALTH) {
-            Log.e(TAG, "getProfileProxy(): BluetoothHealth is deprecated");
-            return false;
-        } else if (profile == BluetoothProfile.MAP) {
-            BluetoothMap map = new BluetoothMap(context, listener, this);
-            return true;
-        } else if (profile == BluetoothProfile.HEADSET_CLIENT) {
-            BluetoothHeadsetClient headsetClient =
-                    new BluetoothHeadsetClient(context, listener, this);
-            return true;
-        } else if (profile == BluetoothProfile.SAP) {
-            BluetoothSap sap = new BluetoothSap(context, listener, this);
-            return true;
-        } else if (profile == BluetoothProfile.PBAP_CLIENT) {
-            BluetoothPbapClient pbapClient = new BluetoothPbapClient(context, listener, this);
-            return true;
-        } else if (profile == BluetoothProfile.MAP_CLIENT) {
-            BluetoothMapClient mapClient = new BluetoothMapClient(context, listener, this);
-            return true;
-        } else if (profile == BluetoothProfile.HID_DEVICE) {
-            BluetoothHidDevice hidDevice = new BluetoothHidDevice(context, listener, this);
-            return true;
-        } else if (profile == BluetoothProfile.HEARING_AID) {
-            if (isHearingAidProfileSupported()) {
-                BluetoothHearingAid hearingAid = new BluetoothHearingAid(context, listener, this);
-                return true;
-            }
-            return false;
-        } else if (profile == BluetoothProfile.LE_AUDIO) {
-            BluetoothLeAudio leAudio = new BluetoothLeAudio(context, listener, this);
-            return true;
-        } else if (profile == BluetoothProfile.VOLUME_CONTROL) {
-            BluetoothVolumeControl vcs = new BluetoothVolumeControl(context, listener, this);
-            return true;
-        } else if (profile == BluetoothProfile.CSIP_SET_COORDINATOR) {
-            BluetoothCsipSetCoordinator csipSetCoordinator =
-                    new BluetoothCsipSetCoordinator(context, listener, this);
-            return true;
-        } else if (profile == BluetoothProfile.LE_CALL_CONTROL) {
-            BluetoothLeCallControl tbs = new BluetoothLeCallControl(context, listener);
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    /**
-     * Close the connection of the profile proxy to the Service.
-     *
-     * <p> Clients should call this when they are no longer using
-     * the proxy obtained from {@link #getProfileProxy}.
-     * Profile can be one of  {@link BluetoothProfile#HEADSET} or {@link BluetoothProfile#A2DP}
-     *
-     * @param profile
-     * @param proxy Profile proxy object
-     */
-    @SuppressLint({
-            "AndroidFrameworkRequiresPermission",
-            "AndroidFrameworkBluetoothPermission"
-    })
-    public void closeProfileProxy(int profile, BluetoothProfile proxy) {
-        if (proxy == null) {
-            return;
-        }
-
-        switch (profile) {
-            case BluetoothProfile.HEADSET:
-                BluetoothHeadset headset = (BluetoothHeadset) proxy;
-                headset.close();
-                break;
-            case BluetoothProfile.A2DP:
-                BluetoothA2dp a2dp = (BluetoothA2dp) proxy;
-                a2dp.close();
-                break;
-            case BluetoothProfile.A2DP_SINK:
-                BluetoothA2dpSink a2dpSink = (BluetoothA2dpSink) proxy;
-                a2dpSink.close();
-                break;
-            case BluetoothProfile.AVRCP_CONTROLLER:
-                BluetoothAvrcpController avrcp = (BluetoothAvrcpController) proxy;
-                avrcp.close();
-                break;
-            case BluetoothProfile.HID_HOST:
-                BluetoothHidHost iDev = (BluetoothHidHost) proxy;
-                iDev.close();
-                break;
-            case BluetoothProfile.PAN:
-                BluetoothPan pan = (BluetoothPan) proxy;
-                pan.close();
-                break;
-            case BluetoothProfile.PBAP:
-                BluetoothPbap pbap = (BluetoothPbap) proxy;
-                pbap.close();
-                break;
-            case BluetoothProfile.GATT:
-                BluetoothGatt gatt = (BluetoothGatt) proxy;
-                gatt.close();
-                break;
-            case BluetoothProfile.GATT_SERVER:
-                BluetoothGattServer gattServer = (BluetoothGattServer) proxy;
-                gattServer.close();
-                break;
-            case BluetoothProfile.MAP:
-                BluetoothMap map = (BluetoothMap) proxy;
-                map.close();
-                break;
-            case BluetoothProfile.HEADSET_CLIENT:
-                BluetoothHeadsetClient headsetClient = (BluetoothHeadsetClient) proxy;
-                headsetClient.close();
-                break;
-            case BluetoothProfile.SAP:
-                BluetoothSap sap = (BluetoothSap) proxy;
-                sap.close();
-                break;
-            case BluetoothProfile.PBAP_CLIENT:
-                BluetoothPbapClient pbapClient = (BluetoothPbapClient) proxy;
-                pbapClient.close();
-                break;
-            case BluetoothProfile.MAP_CLIENT:
-                BluetoothMapClient mapClient = (BluetoothMapClient) proxy;
-                mapClient.close();
-                break;
-            case BluetoothProfile.HID_DEVICE:
-                BluetoothHidDevice hidDevice = (BluetoothHidDevice) proxy;
-                hidDevice.close();
-                break;
-            case BluetoothProfile.HEARING_AID:
-                BluetoothHearingAid hearingAid = (BluetoothHearingAid) proxy;
-                hearingAid.close();
-                break;
-            case BluetoothProfile.LE_AUDIO:
-                BluetoothLeAudio leAudio = (BluetoothLeAudio) proxy;
-                leAudio.close();
-                break;
-            case BluetoothProfile.VOLUME_CONTROL:
-                BluetoothVolumeControl vcs = (BluetoothVolumeControl) proxy;
-                vcs.close();
-                break;
-            case BluetoothProfile.CSIP_SET_COORDINATOR:
-                BluetoothCsipSetCoordinator csipSetCoordinator =
-                        (BluetoothCsipSetCoordinator) proxy;
-                csipSetCoordinator.close();
-                break;
-            case BluetoothProfile.LE_CALL_CONTROL:
-                BluetoothLeCallControl tbs = (BluetoothLeCallControl) proxy;
-                tbs.close();
-                break;
-        }
-    }
-
-    private static final IBluetoothManagerCallback sManagerCallback =
-            new IBluetoothManagerCallback.Stub() {
-                public void onBluetoothServiceUp(IBluetooth bluetoothService) {
-                    if (DBG) {
-                        Log.d(TAG, "onBluetoothServiceUp: " + bluetoothService);
-                    }
-
-                    synchronized (sServiceLock) {
-                        sService = bluetoothService;
-                        for (IBluetoothManagerCallback cb : sProxyServiceStateCallbacks.keySet()) {
-                            try {
-                                if (cb != null) {
-                                    cb.onBluetoothServiceUp(bluetoothService);
-                                } else {
-                                    Log.d(TAG, "onBluetoothServiceUp: cb is null!");
-                                }
-                            } catch (Exception e) {
-                                Log.e(TAG, "", e);
-                            }
-                        }
-                    }
-                }
-
-                public void onBluetoothServiceDown() {
-                    if (DBG) {
-                        Log.d(TAG, "onBluetoothServiceDown");
-                    }
-
-                    synchronized (sServiceLock) {
-                        sService = null;
-                        for (IBluetoothManagerCallback cb : sProxyServiceStateCallbacks.keySet()) {
-                            try {
-                                if (cb != null) {
-                                    cb.onBluetoothServiceDown();
-                                } else {
-                                    Log.d(TAG, "onBluetoothServiceDown: cb is null!");
-                                }
-                            } catch (Exception e) {
-                                Log.e(TAG, "", e);
-                            }
-                        }
-                    }
-                }
-
-                public void onBrEdrDown() {
-                    if (VDBG) {
-                        Log.i(TAG, "onBrEdrDown");
-                    }
-
-                    synchronized (sServiceLock) {
-                        for (IBluetoothManagerCallback cb : sProxyServiceStateCallbacks.keySet()) {
-                            try {
-                                if (cb != null) {
-                                    cb.onBrEdrDown();
-                                } else {
-                                    Log.d(TAG, "onBrEdrDown: cb is null!");
-                                }
-                            } catch (Exception e) {
-                                Log.e(TAG, "", e);
-                            }
-                        }
-                    }
-                }
-            };
-
-    private final IBluetoothManagerCallback mManagerCallback =
-            new IBluetoothManagerCallback.Stub() {
-                public void onBluetoothServiceUp(IBluetooth bluetoothService) {
-                    synchronized (mServiceLock.writeLock()) {
-                        mService = bluetoothService;
-                    }
-                    synchronized (mMetadataListeners) {
-                        mMetadataListeners.forEach((device, pair) -> {
-                            try {
-                                mService.registerMetadataListener(mBluetoothMetadataListener,
-                                        device, mAttributionSource);
-                            } catch (RemoteException e) {
-                                Log.e(TAG, "Failed to register metadata listener", e);
-                            }
-                        });
-                    }
-                    synchronized (mBluetoothConnectionCallbackExecutorMap) {
-                        if (!mBluetoothConnectionCallbackExecutorMap.isEmpty()) {
-                            try {
-                                mService.registerBluetoothConnectionCallback(mConnectionCallback,
-                                        mAttributionSource);
-                            } catch (RemoteException e) {
-                                Log.e(TAG, "onBluetoothServiceUp: Failed to register bluetooth"
-                                        + "connection callback", e);
-                            }
-                        }
-                    }
-                }
-
-                public void onBluetoothServiceDown() {
-                    synchronized (mServiceLock.writeLock()) {
-                        mService = null;
-                        if (mLeScanClients != null) {
-                            mLeScanClients.clear();
-                        }
-                        if (mBluetoothLeAdvertiser != null) {
-                            mBluetoothLeAdvertiser.cleanup();
-                        }
-                        if (mBluetoothLeScanner != null) {
-                            mBluetoothLeScanner.cleanup();
-                        }
-                    }
-                }
-
-                public void onBrEdrDown() {
-                }
-            };
-
-    /**
-     * Enable the Bluetooth Adapter, but don't auto-connect devices
-     * and don't persist state. Only for use by system applications.
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean enableNoAutoConnect() {
-        if (isEnabled()) {
-            if (DBG) {
-                Log.d(TAG, "enableNoAutoConnect(): BT already enabled!");
-            }
-            return true;
-        }
-        try {
-            return mManagerService.enableNoAutoConnect(mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        }
-        return false;
-    }
-
-    /** @hide */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(value = {
-            BluetoothStatusCodes.ERROR_UNKNOWN,
-            BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED,
-            BluetoothStatusCodes.ERROR_ANOTHER_ACTIVE_OOB_REQUEST,
-    })
-    public @interface OobError {}
-
-    /**
-     * Provides callback methods for receiving {@link OobData} from the host stack, as well as an
-     * error interface in order to allow the caller to determine next steps based on the {@code
-     * ErrorCode}.
-     *
-     * @hide
-     */
-    @SystemApi
-    public interface OobDataCallback {
-        /**
-         * Handles the {@link OobData} received from the host stack.
-         *
-         * @param transport - whether the {@link OobData} is generated for LE or Classic.
-         * @param oobData - data generated in the host stack(LE) or controller (Classic)
-         */
-        void onOobData(@Transport int transport, @NonNull OobData oobData);
-
-        /**
-         * Provides feedback when things don't go as expected.
-         *
-         * @param errorCode - the code describing the type of error that occurred.
-         */
-        void onError(@OobError int errorCode);
-    }
-
-    /**
-     * Wraps an AIDL interface around an {@link OobDataCallback} interface.
-     *
-     * @see {@link IBluetoothOobDataCallback} for interface definition.
-     *
-     * @hide
-     */
-    public class WrappedOobDataCallback extends IBluetoothOobDataCallback.Stub {
-        private final OobDataCallback mCallback;
-        private final Executor mExecutor;
-
-        /**
-         * @param callback - object to receive {@link OobData} must be a non null argument
-         *
-         * @throws NullPointerException if the callback is null.
-         */
-        WrappedOobDataCallback(@NonNull OobDataCallback callback,
-                @NonNull @CallbackExecutor Executor executor) {
-            requireNonNull(callback);
-            requireNonNull(executor);
-            mCallback = callback;
-            mExecutor = executor;
-        }
-        /**
-         * Wrapper function to relay to the {@link OobDataCallback#onOobData}
-         *
-         * @param transport - whether the {@link OobData} is generated for LE or Classic.
-         * @param oobData - data generated in the host stack(LE) or controller (Classic)
-         *
-         * @hide
-         */
-        public void onOobData(@Transport int transport, @NonNull OobData oobData) {
-            mExecutor.execute(new Runnable() {
-                public void run() {
-                    mCallback.onOobData(transport, oobData);
-                }
-            });
-        }
-        /**
-         * Wrapper function to relay to the {@link OobDataCallback#onError}
-         *
-         * @param errorCode - the code descibing the type of error that occurred.
-         *
-         * @hide
-         */
-        public void onError(@OobError int errorCode) {
-            mExecutor.execute(new Runnable() {
-                public void run() {
-                    mCallback.onError(errorCode);
-                }
-            });
-        }
-    }
-
-    /**
-     * Fetches a secret data value that can be used for a secure and simple pairing experience.
-     *
-     * <p>This is the Local Out of Band data the comes from the
-     *
-     * <p>This secret is the local Out of Band data.  This data is used to securely and quickly
-     * pair two devices with minimal user interaction.
-     *
-     * <p>For example, this secret can be transferred to a remote device out of band (meaning any
-     * other way besides using bluetooth).  Once the remote device finds this device using the
-     * information given in the data, such as the PUBLIC ADDRESS, the remote device could then
-     * connect to this device using this secret when the pairing sequenece asks for the secret.
-     * This device will respond by automatically accepting the pairing due to the secret being so
-     * trustworthy.
-     *
-     * @param transport - provide type of transport (e.g. LE or Classic).
-     * @param callback - target object to receive the {@link OobData} value.
-     *
-     * @throws NullPointerException if callback is null.
-     * @throws IllegalArgumentException if the transport is not valid.
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public void generateLocalOobData(@Transport int transport,
-            @NonNull @CallbackExecutor Executor executor, @NonNull OobDataCallback callback) {
-        if (transport != BluetoothDevice.TRANSPORT_BREDR && transport
-                != BluetoothDevice.TRANSPORT_LE) {
-            throw new IllegalArgumentException("Invalid transport '" + transport + "'!");
-        }
-        requireNonNull(callback);
-        if (!isEnabled()) {
-            Log.w(TAG, "generateLocalOobData(): Adapter isn't enabled!");
-            callback.onError(BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED);
-        } else {
-            try {
-                mService.generateLocalOobData(transport, new WrappedOobDataCallback(callback,
-                        executor), mAttributionSource);
-            } catch (RemoteException e) {
-                Log.e(TAG, "", e);
-            }
-        }
-    }
-
-    /**
-     * Enable control of the Bluetooth Adapter for a single application.
-     *
-     * <p>Some applications need to use Bluetooth for short periods of time to
-     * transfer data but don't want all the associated implications like
-     * automatic connection to headsets etc.
-     *
-     * <p> Multiple applications can call this. This is reference counted and
-     * Bluetooth disabled only when no one else is using it. There will be no UI
-     * shown to the user while bluetooth is being enabled. Any user action will
-     * override this call. For example, if user wants Bluetooth on and the last
-     * user of this API wanted to disable Bluetooth, Bluetooth will not be
-     * turned off.
-     *
-     * <p> This API is only meant to be used by internal applications. Third
-     * party applications but use {@link #enable} and {@link #disable} APIs.
-     *
-     * <p> If this API returns true, it means the callback will be called.
-     * The callback will be called with the current state of Bluetooth.
-     * If the state is not what was requested, an internal error would be the
-     * reason. If Bluetooth is already on and if this function is called to turn
-     * it on, the api will return true and a callback will be called.
-     *
-     * @param on True for on, false for off.
-     * @param callback The callback to notify changes to the state.
-     * @hide
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SuppressLint("AndroidFrameworkRequiresPermission")
-    public boolean changeApplicationBluetoothState(boolean on,
-            BluetoothStateChangeCallback callback) {
-        return false;
-    }
-
-    /**
-     * @hide
-     */
-    public interface BluetoothStateChangeCallback {
-        /**
-         * @hide
-         */
-        void onBluetoothStateChange(boolean on);
-    }
-
-    /**
-     * @hide
-     */
-    public class StateChangeCallbackWrapper extends IBluetoothStateChangeCallback.Stub {
-        private BluetoothStateChangeCallback mCallback;
-
-        StateChangeCallbackWrapper(BluetoothStateChangeCallback callback) {
-            mCallback = callback;
-        }
-
-        @Override
-        public void onBluetoothStateChange(boolean on) {
-            mCallback.onBluetoothStateChange(on);
-        }
-    }
-
-    private Set<BluetoothDevice> toDeviceSet(List<BluetoothDevice> devices) {
-        Set<BluetoothDevice> deviceSet = new HashSet<BluetoothDevice>(devices);
-        return Collections.unmodifiableSet(deviceSet);
-    }
-
-    protected void finalize() throws Throwable {
-        try {
-            removeServiceStateCallback(mManagerCallback);
-        } finally {
-            super.finalize();
-        }
-    }
-
-    /**
-     * Validate a String Bluetooth address, such as "00:43:A8:23:10:F0"
-     * <p>Alphabetic characters must be uppercase to be valid.
-     *
-     * @param address Bluetooth address as string
-     * @return true if the address is valid, false otherwise
-     */
-    public static boolean checkBluetoothAddress(String address) {
-        if (address == null || address.length() != ADDRESS_LENGTH) {
-            return false;
-        }
-        for (int i = 0; i < ADDRESS_LENGTH; i++) {
-            char c = address.charAt(i);
-            switch (i % 3) {
-                case 0:
-                case 1:
-                    if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F')) {
-                        // hex character, OK
-                        break;
-                    }
-                    return false;
-                case 2:
-                    if (c == ':') {
-                        break;  // OK
-                    }
-                    return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Determines whether a String Bluetooth address, such as "F0:43:A8:23:10:00"
-     * is a RANDOM STATIC address.
-     *
-     * RANDOM STATIC: (addr & 0xC0) == 0xC0
-     * RANDOM RESOLVABLE: (addr &  0xC0) == 0x40
-     * RANDOM non-RESOLVABLE: (addr &  0xC0) == 0x00
-     *
-     * @param address Bluetooth address as string
-     * @return true if the 2 Most Significant Bits of the address equals 0xC0.
-     *
-     * @hide
-     */
-    public static boolean isAddressRandomStatic(@NonNull String address) {
-        requireNonNull(address);
-        return checkBluetoothAddress(address)
-                && (Integer.parseInt(address.split(":")[0], 16) & 0xC0) == 0xC0;
-    }
-
-    /** {@hide} */
-    @UnsupportedAppUsage
-    @RequiresNoPermission
-    public IBluetoothManager getBluetoothManager() {
-        return mManagerService;
-    }
-
-    /** {@hide} */
-    @RequiresNoPermission
-    public AttributionSource getAttributionSource() {
-        return mAttributionSource;
-    }
-
-    @GuardedBy("sServiceLock")
-    private static final WeakHashMap<IBluetoothManagerCallback, Void> sProxyServiceStateCallbacks =
-            new WeakHashMap<>();
-
-    /*package*/ IBluetooth getBluetoothService() {
-        synchronized (sServiceLock) {
-            if (sProxyServiceStateCallbacks.isEmpty()) {
-                throw new IllegalStateException(
-                        "Anonymous service access requires at least one lifecycle in process");
-            }
-            return sService;
-        }
-    }
-
-    @UnsupportedAppUsage
-    /*package*/ IBluetooth getBluetoothService(IBluetoothManagerCallback cb) {
-        Objects.requireNonNull(cb);
-        synchronized (sServiceLock) {
-            sProxyServiceStateCallbacks.put(cb, null);
-            registerOrUnregisterAdapterLocked();
-            return sService;
-        }
-    }
-
-    /*package*/ void removeServiceStateCallback(IBluetoothManagerCallback cb) {
-        Objects.requireNonNull(cb);
-        synchronized (sServiceLock) {
-            sProxyServiceStateCallbacks.remove(cb);
-            registerOrUnregisterAdapterLocked();
-        }
-    }
-
-    /**
-     * Handle registering (or unregistering) a single process-wide
-     * {@link IBluetoothManagerCallback} based on the presence of local
-     * {@link #sProxyServiceStateCallbacks} clients.
-     */
-    @GuardedBy("sServiceLock")
-    private void registerOrUnregisterAdapterLocked() {
-        final boolean isRegistered = sServiceRegistered;
-        final boolean wantRegistered = !sProxyServiceStateCallbacks.isEmpty();
-
-        if (isRegistered != wantRegistered) {
-            if (wantRegistered) {
-                try {
-                    sService = mManagerService.registerAdapter(sManagerCallback);
-                } catch (RemoteException e) {
-                    throw e.rethrowFromSystemServer();
-                }
-            } else {
-                try {
-                    mManagerService.unregisterAdapter(sManagerCallback);
-                    sService = null;
-                } catch (RemoteException e) {
-                    throw e.rethrowFromSystemServer();
-                }
-            }
-            sServiceRegistered = wantRegistered;
-        }
-    }
-
-    /**
-     * Callback interface used to deliver LE scan results.
-     *
-     * @see #startLeScan(LeScanCallback)
-     * @see #startLeScan(UUID[], LeScanCallback)
-     */
-    public interface LeScanCallback {
-        /**
-         * Callback reporting an LE device found during a device scan initiated
-         * by the {@link BluetoothAdapter#startLeScan} function.
-         *
-         * @param device Identifies the remote device
-         * @param rssi The RSSI value for the remote device as reported by the Bluetooth hardware. 0
-         * if no RSSI value is available.
-         * @param scanRecord The content of the advertisement record offered by the remote device.
-         */
-        void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord);
-    }
-
-    /**
-     * Register a callback to receive events whenever the bluetooth stack goes down and back up,
-     * e.g. in the event the bluetooth is turned off/on via settings.
-     *
-     * If the bluetooth stack is currently up, there will not be an initial callback call.
-     * You can use the return value as an indication of this being the case.
-     *
-     * Callbacks will be delivered on a binder thread.
-     *
-     * @return whether bluetooth is already up currently
-     *
-     * @hide
-     */
-    public boolean registerServiceLifecycleCallback(ServiceLifecycleCallback callback) {
-        return getBluetoothService(callback.mRemote) != null;
-    }
-
-    /**
-     * Unregister a callback registered via {@link #registerServiceLifecycleCallback}
-     *
-     * @hide
-     */
-    public void unregisterServiceLifecycleCallback(ServiceLifecycleCallback callback) {
-        removeServiceStateCallback(callback.mRemote);
-    }
-
-    /**
-     * A callback for {@link #registerServiceLifecycleCallback}
-     *
-     * @hide
-     */
-    public abstract static class ServiceLifecycleCallback {
-
-        /** Called when the bluetooth stack is up */
-        public abstract void onBluetoothServiceUp();
-
-        /** Called when the bluetooth stack is down */
-        public abstract void onBluetoothServiceDown();
-
-        IBluetoothManagerCallback mRemote = new IBluetoothManagerCallback.Stub() {
-            @Override
-            public void onBluetoothServiceUp(IBluetooth bluetoothService) {
-                ServiceLifecycleCallback.this.onBluetoothServiceUp();
-            }
-
-            @Override
-            public void onBluetoothServiceDown() {
-                ServiceLifecycleCallback.this.onBluetoothServiceDown();
-            }
-
-            @Override
-            public void onBrEdrDown() {}
-        };
-    }
-
-    /**
-     * Starts a scan for Bluetooth LE devices.
-     *
-     * <p>Results of the scan are reported using the
-     * {@link LeScanCallback#onLeScan} callback.
-     *
-     * @param callback the callback LE scan results are delivered
-     * @return true, if the scan was started successfully
-     * @deprecated use {@link BluetoothLeScanner#startScan(List, ScanSettings, ScanCallback)}
-     * instead.
-     */
-    @Deprecated
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothScanPermission
-    @RequiresBluetoothLocationPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
-    public boolean startLeScan(LeScanCallback callback) {
-        return startLeScan(null, callback);
-    }
-
-    /**
-     * Starts a scan for Bluetooth LE devices, looking for devices that
-     * advertise given services.
-     *
-     * <p>Devices which advertise all specified services are reported using the
-     * {@link LeScanCallback#onLeScan} callback.
-     *
-     * @param serviceUuids Array of services to look for
-     * @param callback the callback LE scan results are delivered
-     * @return true, if the scan was started successfully
-     * @deprecated use {@link BluetoothLeScanner#startScan(List, ScanSettings, ScanCallback)}
-     * instead.
-     */
-    @Deprecated
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothScanPermission
-    @RequiresBluetoothLocationPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
-    public boolean startLeScan(final UUID[] serviceUuids, final LeScanCallback callback) {
-        if (DBG) {
-            Log.d(TAG, "startLeScan(): " + Arrays.toString(serviceUuids));
-        }
-        if (callback == null) {
-            if (DBG) {
-                Log.e(TAG, "startLeScan: null callback");
-            }
-            return false;
-        }
-        BluetoothLeScanner scanner = getBluetoothLeScanner();
-        if (scanner == null) {
-            if (DBG) {
-                Log.e(TAG, "startLeScan: cannot get BluetoothLeScanner");
-            }
-            return false;
-        }
-
-        synchronized (mLeScanClients) {
-            if (mLeScanClients.containsKey(callback)) {
-                if (DBG) {
-                    Log.e(TAG, "LE Scan has already started");
-                }
-                return false;
-            }
-
-            try {
-                IBluetoothGatt iGatt = mManagerService.getBluetoothGatt();
-                if (iGatt == null) {
-                    // BLE is not supported
-                    return false;
-                }
-
-                @SuppressLint("AndroidFrameworkBluetoothPermission")
-                ScanCallback scanCallback = new ScanCallback() {
-                    @Override
-                    public void onScanResult(int callbackType, ScanResult result) {
-                        if (callbackType != ScanSettings.CALLBACK_TYPE_ALL_MATCHES) {
-                            // Should not happen.
-                            Log.e(TAG, "LE Scan has already started");
-                            return;
-                        }
-                        ScanRecord scanRecord = result.getScanRecord();
-                        if (scanRecord == null) {
-                            return;
-                        }
-                        if (serviceUuids != null) {
-                            List<ParcelUuid> uuids = new ArrayList<ParcelUuid>();
-                            for (UUID uuid : serviceUuids) {
-                                uuids.add(new ParcelUuid(uuid));
-                            }
-                            List<ParcelUuid> scanServiceUuids = scanRecord.getServiceUuids();
-                            if (scanServiceUuids == null || !scanServiceUuids.containsAll(uuids)) {
-                                if (DBG) {
-                                    Log.d(TAG, "uuids does not match");
-                                }
-                                return;
-                            }
-                        }
-                        callback.onLeScan(result.getDevice(), result.getRssi(),
-                                scanRecord.getBytes());
-                    }
-                };
-                ScanSettings settings = new ScanSettings.Builder().setCallbackType(
-                        ScanSettings.CALLBACK_TYPE_ALL_MATCHES)
-                        .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
-                        .build();
-
-                List<ScanFilter> filters = new ArrayList<ScanFilter>();
-                if (serviceUuids != null && serviceUuids.length > 0) {
-                    // Note scan filter does not support matching an UUID array so we put one
-                    // UUID to hardware and match the whole array in callback.
-                    ScanFilter filter =
-                            new ScanFilter.Builder().setServiceUuid(new ParcelUuid(serviceUuids[0]))
-                                    .build();
-                    filters.add(filter);
-                }
-                scanner.startScan(filters, settings, scanCallback);
-
-                mLeScanClients.put(callback, scanCallback);
-                return true;
-
-            } catch (RemoteException e) {
-                Log.e(TAG, "", e);
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Stops an ongoing Bluetooth LE device scan.
-     *
-     * @param callback used to identify which scan to stop must be the same handle used to start the
-     * scan
-     * @deprecated Use {@link BluetoothLeScanner#stopScan(ScanCallback)} instead.
-     */
-    @Deprecated
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothScanPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
-    public void stopLeScan(LeScanCallback callback) {
-        if (DBG) {
-            Log.d(TAG, "stopLeScan()");
-        }
-        BluetoothLeScanner scanner = getBluetoothLeScanner();
-        if (scanner == null) {
-            return;
-        }
-        synchronized (mLeScanClients) {
-            ScanCallback scanCallback = mLeScanClients.remove(callback);
-            if (scanCallback == null) {
-                if (DBG) {
-                    Log.d(TAG, "scan not started yet");
-                }
-                return;
-            }
-            scanner.stopScan(scanCallback);
-        }
-    }
-
-    /**
-     * Create a secure L2CAP Connection-oriented Channel (CoC) {@link BluetoothServerSocket} and
-     * assign a dynamic protocol/service multiplexer (PSM) value. This socket can be used to listen
-     * for incoming connections. The supported Bluetooth transport is LE only.
-     * <p>A remote device connecting to this socket will be authenticated and communication on this
-     * socket will be encrypted.
-     * <p>Use {@link BluetoothServerSocket#accept} to retrieve incoming connections from a listening
-     * {@link BluetoothServerSocket}.
-     * <p>The system will assign a dynamic PSM value. This PSM value can be read from the {@link
-     * BluetoothServerSocket#getPsm()} and this value will be released when this server socket is
-     * closed, Bluetooth is turned off, or the application exits unexpectedly.
-     * <p>The mechanism of disclosing the assigned dynamic PSM value to the initiating peer is
-     * defined and performed by the application.
-     * <p>Use {@link BluetoothDevice#createL2capChannel(int)} to connect to this server
-     * socket from another Android device that is given the PSM value.
-     *
-     * @return an L2CAP CoC BluetoothServerSocket
-     * @throws IOException on error, for example Bluetooth not available, or insufficient
-     * permissions, or unable to start this CoC
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public @NonNull BluetoothServerSocket listenUsingL2capChannel()
-            throws IOException {
-        BluetoothServerSocket socket =
-                            new BluetoothServerSocket(BluetoothSocket.TYPE_L2CAP_LE, true, true,
-                                      SOCKET_CHANNEL_AUTO_STATIC_NO_SDP, false, false);
-        int errno = socket.mSocket.bindListen();
-        if (errno != 0) {
-            throw new IOException("Error: " + errno);
-        }
-
-        int assignedPsm = socket.mSocket.getPort();
-        if (assignedPsm == 0) {
-            throw new IOException("Error: Unable to assign PSM value");
-        }
-        if (DBG) {
-            Log.d(TAG, "listenUsingL2capChannel: set assigned PSM to "
-                    + assignedPsm);
-        }
-        socket.setChannel(assignedPsm);
-
-        return socket;
-    }
-
-    /**
-     * Create an insecure L2CAP Connection-oriented Channel (CoC) {@link BluetoothServerSocket} and
-     * assign a dynamic PSM value. This socket can be used to listen for incoming connections. The
-     * supported Bluetooth transport is LE only.
-     * <p>The link key is not required to be authenticated, i.e the communication may be vulnerable
-     * to person-in-the-middle attacks. Use {@link #listenUsingL2capChannel}, if an encrypted and
-     * authenticated communication channel is desired.
-     * <p>Use {@link BluetoothServerSocket#accept} to retrieve incoming connections from a listening
-     * {@link BluetoothServerSocket}.
-     * <p>The system will assign a dynamic protocol/service multiplexer (PSM) value. This PSM value
-     * can be read from the {@link BluetoothServerSocket#getPsm()} and this value will be released
-     * when this server socket is closed, Bluetooth is turned off, or the application exits
-     * unexpectedly.
-     * <p>The mechanism of disclosing the assigned dynamic PSM value to the initiating peer is
-     * defined and performed by the application.
-     * <p>Use {@link BluetoothDevice#createInsecureL2capChannel(int)} to connect to this server
-     * socket from another Android device that is given the PSM value.
-     *
-     * @return an L2CAP CoC BluetoothServerSocket
-     * @throws IOException on error, for example Bluetooth not available, or insufficient
-     * permissions, or unable to start this CoC
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public @NonNull BluetoothServerSocket listenUsingInsecureL2capChannel()
-            throws IOException {
-        BluetoothServerSocket socket =
-                            new BluetoothServerSocket(BluetoothSocket.TYPE_L2CAP_LE, false, false,
-                                      SOCKET_CHANNEL_AUTO_STATIC_NO_SDP, false, false);
-        int errno = socket.mSocket.bindListen();
-        if (errno != 0) {
-            throw new IOException("Error: " + errno);
-        }
-
-        int assignedPsm = socket.mSocket.getPort();
-        if (assignedPsm == 0) {
-            throw new IOException("Error: Unable to assign PSM value");
-        }
-        if (DBG) {
-            Log.d(TAG, "listenUsingInsecureL2capChannel: set assigned PSM to "
-                    + assignedPsm);
-        }
-        socket.setChannel(assignedPsm);
-
-        return socket;
-    }
-
-    /**
-     * Register a {@link #OnMetadataChangedListener} to receive update about metadata
-     * changes for this {@link BluetoothDevice}.
-     * Registration must be done when Bluetooth is ON and will last until
-     * {@link #removeOnMetadataChangedListener(BluetoothDevice)} is called, even when Bluetooth
-     * restarted in the middle.
-     * All input parameters should not be null or {@link NullPointerException} will be triggered.
-     * The same {@link BluetoothDevice} and {@link #OnMetadataChangedListener} pair can only be
-     * registered once, double registration would cause {@link IllegalArgumentException}.
-     *
-     * @param device {@link BluetoothDevice} that will be registered
-     * @param executor the executor for listener callback
-     * @param listener {@link #OnMetadataChangedListener} that will receive asynchronous callbacks
-     * @return true on success, false on error
-     * @throws NullPointerException If one of {@code listener}, {@code device} or {@code executor}
-     * is null.
-     * @throws IllegalArgumentException The same {@link #OnMetadataChangedListener} and
-     * {@link BluetoothDevice} are registered twice.
-     * @hide
-     */
-    @SystemApi
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public boolean addOnMetadataChangedListener(@NonNull BluetoothDevice device,
-            @NonNull Executor executor, @NonNull OnMetadataChangedListener listener) {
-        if (DBG) Log.d(TAG, "addOnMetadataChangedListener()");
-
-        final IBluetooth service = mService;
-        if (service == null) {
-            Log.e(TAG, "Bluetooth is not enabled. Cannot register metadata listener");
-            return false;
-        }
-        if (listener == null) {
-            throw new NullPointerException("listener is null");
-        }
-        if (device == null) {
-            throw new NullPointerException("device is null");
-        }
-        if (executor == null) {
-            throw new NullPointerException("executor is null");
-        }
-
-        synchronized (mMetadataListeners) {
-            List<Pair<OnMetadataChangedListener, Executor>> listenerList =
-                    mMetadataListeners.get(device);
-            if (listenerList == null) {
-                // Create new listener/executor list for registeration
-                listenerList = new ArrayList<>();
-                mMetadataListeners.put(device, listenerList);
-            } else {
-                // Check whether this device was already registed by the lisenter
-                if (listenerList.stream().anyMatch((pair) -> (pair.first.equals(listener)))) {
-                    throw new IllegalArgumentException("listener was already regestered"
-                            + " for the device");
-                }
-            }
-
-            Pair<OnMetadataChangedListener, Executor> listenerPair = new Pair(listener, executor);
-            listenerList.add(listenerPair);
-
-            boolean ret = false;
-            try {
-                ret = service.registerMetadataListener(mBluetoothMetadataListener, device,
-                        mAttributionSource);
-            } catch (RemoteException e) {
-                Log.e(TAG, "registerMetadataListener fail", e);
-            } finally {
-                if (!ret) {
-                    // Remove listener registered earlier when fail.
-                    listenerList.remove(listenerPair);
-                    if (listenerList.isEmpty()) {
-                        // Remove the device if its listener list is empty
-                        mMetadataListeners.remove(device);
-                    }
-                }
-            }
-            return ret;
-        }
-    }
-
-    /**
-     * Unregister a {@link #OnMetadataChangedListener} from a registered {@link BluetoothDevice}.
-     * Unregistration can be done when Bluetooth is either ON or OFF.
-     * {@link #addOnMetadataChangedListener(OnMetadataChangedListener, BluetoothDevice, Executor)}
-     * must be called before unregisteration.
-     *
-     * @param device {@link BluetoothDevice} that will be unregistered. It
-     * should not be null or {@link NullPointerException} will be triggered.
-     * @param listener {@link OnMetadataChangedListener} that will be unregistered. It
-     * should not be null or {@link NullPointerException} will be triggered.
-     * @return true on success, false on error
-     * @throws NullPointerException If {@code listener} or {@code device} is null.
-     * @throws IllegalArgumentException If {@code device} has not been registered before.
-     * @hide
-     */
-    @SystemApi
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public boolean removeOnMetadataChangedListener(@NonNull BluetoothDevice device,
-            @NonNull OnMetadataChangedListener listener) {
-        if (DBG) Log.d(TAG, "removeOnMetadataChangedListener()");
-        if (device == null) {
-            throw new NullPointerException("device is null");
-        }
-        if (listener == null) {
-            throw new NullPointerException("listener is null");
-        }
-
-        synchronized (mMetadataListeners) {
-            if (!mMetadataListeners.containsKey(device)) {
-                throw new IllegalArgumentException("device was not registered");
-            }
-            // Remove issued listener from the registered device
-            mMetadataListeners.get(device).removeIf((pair) -> (pair.first.equals(listener)));
-
-            if (mMetadataListeners.get(device).isEmpty()) {
-                // Unregister to Bluetooth service if all listeners are removed from
-                // the registered device
-                mMetadataListeners.remove(device);
-                final IBluetooth service = mService;
-                if (service == null) {
-                    // Bluetooth is OFF, do nothing to Bluetooth service.
-                    return true;
-                }
-                try {
-                    return service.unregisterMetadataListener(device, mAttributionSource);
-                } catch (RemoteException e) {
-                    Log.e(TAG, "unregisterMetadataListener fail", e);
-                    return false;
-                }
-            }
-        }
-        return true;
-    }
-
-    /**
-     * This interface is used to implement {@link BluetoothAdapter} metadata listener.
-     * @hide
-     */
-    @SystemApi
-    public interface OnMetadataChangedListener {
-        /**
-         * Callback triggered if the metadata of {@link BluetoothDevice} registered in
-         * {@link #addOnMetadataChangedListener}.
-         *
-         * @param device changed {@link BluetoothDevice}.
-         * @param key changed metadata key, one of BluetoothDevice.METADATA_*.
-         * @param value the new value of metadata as byte array.
-         */
-        void onMetadataChanged(@NonNull BluetoothDevice device, int key,
-                @Nullable byte[] value);
-    }
-
-    @SuppressLint("AndroidFrameworkBluetoothPermission")
-    private final IBluetoothConnectionCallback mConnectionCallback =
-            new IBluetoothConnectionCallback.Stub() {
-        @Override
-        public void onDeviceConnected(BluetoothDevice device) {
-            Attributable.setAttributionSource(device, mAttributionSource);
-            for (Map.Entry<BluetoothConnectionCallback, Executor> callbackExecutorEntry:
-                    mBluetoothConnectionCallbackExecutorMap.entrySet()) {
-                BluetoothConnectionCallback callback = callbackExecutorEntry.getKey();
-                Executor executor = callbackExecutorEntry.getValue();
-                executor.execute(() -> callback.onDeviceConnected(device));
-            }
-        }
-
-        @Override
-        public void onDeviceDisconnected(BluetoothDevice device, int hciReason) {
-            Attributable.setAttributionSource(device, mAttributionSource);
-            for (Map.Entry<BluetoothConnectionCallback, Executor> callbackExecutorEntry:
-                    mBluetoothConnectionCallbackExecutorMap.entrySet()) {
-                BluetoothConnectionCallback callback = callbackExecutorEntry.getKey();
-                Executor executor = callbackExecutorEntry.getValue();
-                executor.execute(() -> callback.onDeviceDisconnected(device, hciReason));
-            }
-        }
-    };
-
-    /**
-     * Registers the BluetoothConnectionCallback to receive callback events when a bluetooth device
-     * (classic or low energy) is connected or disconnected.
-     *
-     * @param executor is the callback executor
-     * @param callback is the connection callback you wish to register
-     * @return true if the callback was registered successfully, false otherwise
-     * @throws IllegalArgumentException if the callback is already registered
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public boolean registerBluetoothConnectionCallback(@NonNull @CallbackExecutor Executor executor,
-            @NonNull BluetoothConnectionCallback callback) {
-        if (DBG) Log.d(TAG, "registerBluetoothConnectionCallback()");
-        if (callback == null) {
-            return false;
-        }
-
-        synchronized (mBluetoothConnectionCallbackExecutorMap) {
-            // If the callback map is empty, we register the service-to-app callback
-            if (mBluetoothConnectionCallbackExecutorMap.isEmpty()) {
-                try {
-                    mServiceLock.readLock().lock();
-                    if (mService != null) {
-                        if (!mService.registerBluetoothConnectionCallback(mConnectionCallback,
-                                mAttributionSource)) {
-                            return false;
-                        }
-                    }
-                } catch (RemoteException e) {
-                    Log.e(TAG, "", e);
-                    mBluetoothConnectionCallbackExecutorMap.remove(callback);
-                } finally {
-                    mServiceLock.readLock().unlock();
-                }
-            }
-
-            // Adds the passed in callback to our map of callbacks to executors
-            if (mBluetoothConnectionCallbackExecutorMap.containsKey(callback)) {
-                throw new IllegalArgumentException("This callback has already been registered");
-            }
-            mBluetoothConnectionCallbackExecutorMap.put(callback, executor);
-        }
-
-        return true;
-    }
-
-    /**
-     * Unregisters the BluetoothConnectionCallback that was previously registered by the application
-     *
-     * @param callback is the connection callback you wish to unregister
-     * @return true if the callback was unregistered successfully, false otherwise
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public boolean unregisterBluetoothConnectionCallback(
-            @NonNull BluetoothConnectionCallback callback) {
-        if (DBG) Log.d(TAG, "unregisterBluetoothConnectionCallback()");
-        if (callback == null) {
-            return false;
-        }
-
-        synchronized (mBluetoothConnectionCallbackExecutorMap) {
-            if (mBluetoothConnectionCallbackExecutorMap.remove(callback) != null) {
-                return false;
-            }
-        }
-
-        if (!mBluetoothConnectionCallbackExecutorMap.isEmpty()) {
-            return true;
-        }
-
-        // If the callback map is empty, we unregister the service-to-app callback
-        try {
-            mServiceLock.readLock().lock();
-            if (mService != null) {
-                return mService.unregisterBluetoothConnectionCallback(mConnectionCallback,
-                        mAttributionSource);
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        } finally {
-            mServiceLock.readLock().unlock();
-        }
-
-        return false;
-    }
-
-    /**
-     * This abstract class is used to implement callbacks for when a bluetooth classic or Bluetooth
-     * Low Energy (BLE) device is either connected or disconnected.
-     *
-     * @hide
-     */
-    public abstract static class BluetoothConnectionCallback {
-        /**
-         * Callback triggered when a bluetooth device (classic or BLE) is connected
-         * @param device is the connected bluetooth device
-         */
-        public void onDeviceConnected(BluetoothDevice device) {}
-
-        /**
-         * Callback triggered when a bluetooth device (classic or BLE) is disconnected
-         * @param device is the disconnected bluetooth device
-         * @param reason is the disconnect reason
-         */
-        public void onDeviceDisconnected(BluetoothDevice device, @DisconnectReason int reason) {}
-
-        /**
-         * @hide
-         */
-        @Retention(RetentionPolicy.SOURCE)
-        @IntDef(prefix = { "REASON_" }, value = {
-                BluetoothStatusCodes.ERROR_UNKNOWN,
-                BluetoothStatusCodes.ERROR_DISCONNECT_REASON_LOCAL_REQUEST,
-                BluetoothStatusCodes.ERROR_DISCONNECT_REASON_REMOTE_REQUEST,
-                BluetoothStatusCodes.ERROR_DISCONNECT_REASON_LOCAL,
-                BluetoothStatusCodes.ERROR_DISCONNECT_REASON_REMOTE,
-                BluetoothStatusCodes.ERROR_DISCONNECT_REASON_TIMEOUT,
-                BluetoothStatusCodes.ERROR_DISCONNECT_REASON_SECURITY,
-                BluetoothStatusCodes.ERROR_DISCONNECT_REASON_SYSTEM_POLICY,
-                BluetoothStatusCodes.ERROR_DISCONNECT_REASON_RESOURCE_LIMIT_REACHED,
-                BluetoothStatusCodes.ERROR_DISCONNECT_REASON_CONNECTION_ALREADY_EXISTS,
-                BluetoothStatusCodes.ERROR_DISCONNECT_REASON_BAD_PARAMETERS})
-        public @interface DisconnectReason {}
-
-        /**
-         * Returns human-readable strings corresponding to {@link DisconnectReason}.
-         */
-        public static String disconnectReasonText(@DisconnectReason int reason) {
-            switch (reason) {
-                case BluetoothStatusCodes.ERROR_UNKNOWN:
-                    return "Reason unknown";
-                case BluetoothStatusCodes.ERROR_DISCONNECT_REASON_LOCAL_REQUEST:
-                    return "Local request";
-                case BluetoothStatusCodes.ERROR_DISCONNECT_REASON_REMOTE_REQUEST:
-                    return "Remote request";
-                case BluetoothStatusCodes.ERROR_DISCONNECT_REASON_LOCAL:
-                    return "Local error";
-                case BluetoothStatusCodes.ERROR_DISCONNECT_REASON_REMOTE:
-                    return "Remote error";
-                case BluetoothStatusCodes.ERROR_DISCONNECT_REASON_TIMEOUT:
-                    return "Timeout";
-                case BluetoothStatusCodes.ERROR_DISCONNECT_REASON_SECURITY:
-                    return "Security";
-                case BluetoothStatusCodes.ERROR_DISCONNECT_REASON_SYSTEM_POLICY:
-                    return "System policy";
-                case BluetoothStatusCodes.ERROR_DISCONNECT_REASON_RESOURCE_LIMIT_REACHED:
-                    return "Resource constrained";
-                case BluetoothStatusCodes.ERROR_DISCONNECT_REASON_CONNECTION_ALREADY_EXISTS:
-                    return "Connection already exists";
-                case BluetoothStatusCodes.ERROR_DISCONNECT_REASON_BAD_PARAMETERS:
-                    return "Bad parameters";
-                default:
-                    return "Unrecognized disconnect reason: " + reason;
-            }
-        }
-    }
-
-    /**
-     * Converts old constant of priority to the new for connection policy
-     *
-     * @param priority is the priority to convert to connection policy
-     * @return the equivalent connection policy constant to the priority
-     *
-     * @hide
-     */
-    public static @ConnectionPolicy int priorityToConnectionPolicy(int priority) {
-        switch(priority) {
-            case BluetoothProfile.PRIORITY_AUTO_CONNECT:
-                return BluetoothProfile.CONNECTION_POLICY_ALLOWED;
-            case BluetoothProfile.PRIORITY_ON:
-                return BluetoothProfile.CONNECTION_POLICY_ALLOWED;
-            case BluetoothProfile.PRIORITY_OFF:
-                return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
-            case BluetoothProfile.PRIORITY_UNDEFINED:
-                return BluetoothProfile.CONNECTION_POLICY_UNKNOWN;
-            default:
-                Log.e(TAG, "setPriority: Invalid priority: " + priority);
-                return BluetoothProfile.CONNECTION_POLICY_UNKNOWN;
-        }
-    }
-
-    /**
-     * Converts new constant of connection policy to the old for priority
-     *
-     * @param connectionPolicy is the connection policy to convert to priority
-     * @return the equivalent priority constant to the connectionPolicy
-     *
-     * @hide
-     */
-    public static int connectionPolicyToPriority(@ConnectionPolicy int connectionPolicy) {
-        switch(connectionPolicy) {
-            case BluetoothProfile.CONNECTION_POLICY_ALLOWED:
-                return BluetoothProfile.PRIORITY_ON;
-            case BluetoothProfile.CONNECTION_POLICY_FORBIDDEN:
-                return BluetoothProfile.PRIORITY_OFF;
-            case BluetoothProfile.CONNECTION_POLICY_UNKNOWN:
-                return BluetoothProfile.PRIORITY_UNDEFINED;
-        }
-        return BluetoothProfile.PRIORITY_UNDEFINED;
-    }
-}
diff --git a/core/java/android/bluetooth/BluetoothAssignedNumbers.java b/core/java/android/bluetooth/BluetoothAssignedNumbers.java
deleted file mode 100644
index 41a34e0..0000000
--- a/core/java/android/bluetooth/BluetoothAssignedNumbers.java
+++ /dev/null
@@ -1,1171 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-/**
- * Bluetooth Assigned Numbers.
- * <p>
- * For now we only include Company ID values.
- *
- * @see <a href="https://www.bluetooth.org/technical/assignednumbers/identifiers.htm"> The Official
- * Bluetooth SIG Member Website | Company Identifiers</a>
- */
-public class BluetoothAssignedNumbers {
-
-    // Bluetooth SIG Company ID values
-    /*
-     * Ericsson Technology Licensing.
-     */
-    public static final int ERICSSON_TECHNOLOGY = 0x0000;
-
-    /*
-     * Nokia Mobile Phones.
-     */
-    public static final int NOKIA_MOBILE_PHONES = 0x0001;
-
-    /*
-     * Intel Corp.
-     */
-    public static final int INTEL = 0x0002;
-
-    /*
-     * IBM Corp.
-     */
-    public static final int IBM = 0x0003;
-
-    /*
-     * Toshiba Corp.
-     */
-    public static final int TOSHIBA = 0x0004;
-
-    /*
-     * 3Com.
-     */
-    public static final int THREECOM = 0x0005;
-
-    /*
-     * Microsoft.
-     */
-    public static final int MICROSOFT = 0x0006;
-
-    /*
-     * Lucent.
-     */
-    public static final int LUCENT = 0x0007;
-
-    /*
-     * Motorola.
-     */
-    public static final int MOTOROLA = 0x0008;
-
-    /*
-     * Infineon Technologies AG.
-     */
-    public static final int INFINEON_TECHNOLOGIES = 0x0009;
-
-    /*
-     * Cambridge Silicon Radio.
-     */
-    public static final int CAMBRIDGE_SILICON_RADIO = 0x000A;
-
-    /*
-     * Silicon Wave.
-     */
-    public static final int SILICON_WAVE = 0x000B;
-
-    /*
-     * Digianswer A/S.
-     */
-    public static final int DIGIANSWER = 0x000C;
-
-    /*
-     * Texas Instruments Inc.
-     */
-    public static final int TEXAS_INSTRUMENTS = 0x000D;
-
-    /*
-     * Parthus Technologies Inc.
-     */
-    public static final int PARTHUS_TECHNOLOGIES = 0x000E;
-
-    /*
-     * Broadcom Corporation.
-     */
-    public static final int BROADCOM = 0x000F;
-
-    /*
-     * Mitel Semiconductor.
-     */
-    public static final int MITEL_SEMICONDUCTOR = 0x0010;
-
-    /*
-     * Widcomm, Inc.
-     */
-    public static final int WIDCOMM = 0x0011;
-
-    /*
-     * Zeevo, Inc.
-     */
-    public static final int ZEEVO = 0x0012;
-
-    /*
-     * Atmel Corporation.
-     */
-    public static final int ATMEL = 0x0013;
-
-    /*
-     * Mitsubishi Electric Corporation.
-     */
-    public static final int MITSUBISHI_ELECTRIC = 0x0014;
-
-    /*
-     * RTX Telecom A/S.
-     */
-    public static final int RTX_TELECOM = 0x0015;
-
-    /*
-     * KC Technology Inc.
-     */
-    public static final int KC_TECHNOLOGY = 0x0016;
-
-    /*
-     * Newlogic.
-     */
-    public static final int NEWLOGIC = 0x0017;
-
-    /*
-     * Transilica, Inc.
-     */
-    public static final int TRANSILICA = 0x0018;
-
-    /*
-     * Rohde & Schwarz GmbH & Co. KG.
-     */
-    public static final int ROHDE_AND_SCHWARZ = 0x0019;
-
-    /*
-     * TTPCom Limited.
-     */
-    public static final int TTPCOM = 0x001A;
-
-    /*
-     * Signia Technologies, Inc.
-     */
-    public static final int SIGNIA_TECHNOLOGIES = 0x001B;
-
-    /*
-     * Conexant Systems Inc.
-     */
-    public static final int CONEXANT_SYSTEMS = 0x001C;
-
-    /*
-     * Qualcomm.
-     */
-    public static final int QUALCOMM = 0x001D;
-
-    /*
-     * Inventel.
-     */
-    public static final int INVENTEL = 0x001E;
-
-    /*
-     * AVM Berlin.
-     */
-    public static final int AVM_BERLIN = 0x001F;
-
-    /*
-     * BandSpeed, Inc.
-     */
-    public static final int BANDSPEED = 0x0020;
-
-    /*
-     * Mansella Ltd.
-     */
-    public static final int MANSELLA = 0x0021;
-
-    /*
-     * NEC Corporation.
-     */
-    public static final int NEC = 0x0022;
-
-    /*
-     * WavePlus Technology Co., Ltd.
-     */
-    public static final int WAVEPLUS_TECHNOLOGY = 0x0023;
-
-    /*
-     * Alcatel.
-     */
-    public static final int ALCATEL = 0x0024;
-
-    /*
-     * Philips Semiconductors.
-     */
-    public static final int PHILIPS_SEMICONDUCTORS = 0x0025;
-
-    /*
-     * C Technologies.
-     */
-    public static final int C_TECHNOLOGIES = 0x0026;
-
-    /*
-     * Open Interface.
-     */
-    public static final int OPEN_INTERFACE = 0x0027;
-
-    /*
-     * R F Micro Devices.
-     */
-    public static final int RF_MICRO_DEVICES = 0x0028;
-
-    /*
-     * Hitachi Ltd.
-     */
-    public static final int HITACHI = 0x0029;
-
-    /*
-     * Symbol Technologies, Inc.
-     */
-    public static final int SYMBOL_TECHNOLOGIES = 0x002A;
-
-    /*
-     * Tenovis.
-     */
-    public static final int TENOVIS = 0x002B;
-
-    /*
-     * Macronix International Co. Ltd.
-     */
-    public static final int MACRONIX = 0x002C;
-
-    /*
-     * GCT Semiconductor.
-     */
-    public static final int GCT_SEMICONDUCTOR = 0x002D;
-
-    /*
-     * Norwood Systems.
-     */
-    public static final int NORWOOD_SYSTEMS = 0x002E;
-
-    /*
-     * MewTel Technology Inc.
-     */
-    public static final int MEWTEL_TECHNOLOGY = 0x002F;
-
-    /*
-     * ST Microelectronics.
-     */
-    public static final int ST_MICROELECTRONICS = 0x0030;
-
-    /*
-     * Synopsys.
-     */
-    public static final int SYNOPSYS = 0x0031;
-
-    /*
-     * Red-M (Communications) Ltd.
-     */
-    public static final int RED_M = 0x0032;
-
-    /*
-     * Commil Ltd.
-     */
-    public static final int COMMIL = 0x0033;
-
-    /*
-     * Computer Access Technology Corporation (CATC).
-     */
-    public static final int CATC = 0x0034;
-
-    /*
-     * Eclipse (HQ Espana) S.L.
-     */
-    public static final int ECLIPSE = 0x0035;
-
-    /*
-     * Renesas Technology Corp.
-     */
-    public static final int RENESAS_TECHNOLOGY = 0x0036;
-
-    /*
-     * Mobilian Corporation.
-     */
-    public static final int MOBILIAN_CORPORATION = 0x0037;
-
-    /*
-     * Terax.
-     */
-    public static final int TERAX = 0x0038;
-
-    /*
-     * Integrated System Solution Corp.
-     */
-    public static final int INTEGRATED_SYSTEM_SOLUTION = 0x0039;
-
-    /*
-     * Matsushita Electric Industrial Co., Ltd.
-     */
-    public static final int MATSUSHITA_ELECTRIC = 0x003A;
-
-    /*
-     * Gennum Corporation.
-     */
-    public static final int GENNUM = 0x003B;
-
-    /*
-     * Research In Motion.
-     */
-    public static final int RESEARCH_IN_MOTION = 0x003C;
-
-    /*
-     * IPextreme, Inc.
-     */
-    public static final int IPEXTREME = 0x003D;
-
-    /*
-     * Systems and Chips, Inc.
-     */
-    public static final int SYSTEMS_AND_CHIPS = 0x003E;
-
-    /*
-     * Bluetooth SIG, Inc.
-     */
-    public static final int BLUETOOTH_SIG = 0x003F;
-
-    /*
-     * Seiko Epson Corporation.
-     */
-    public static final int SEIKO_EPSON = 0x0040;
-
-    /*
-     * Integrated Silicon Solution Taiwan, Inc.
-     */
-    public static final int INTEGRATED_SILICON_SOLUTION = 0x0041;
-
-    /*
-     * CONWISE Technology Corporation Ltd.
-     */
-    public static final int CONWISE_TECHNOLOGY = 0x0042;
-
-    /*
-     * PARROT SA.
-     */
-    public static final int PARROT = 0x0043;
-
-    /*
-     * Socket Mobile.
-     */
-    public static final int SOCKET_MOBILE = 0x0044;
-
-    /*
-     * Atheros Communications, Inc.
-     */
-    public static final int ATHEROS_COMMUNICATIONS = 0x0045;
-
-    /*
-     * MediaTek, Inc.
-     */
-    public static final int MEDIATEK = 0x0046;
-
-    /*
-     * Bluegiga.
-     */
-    public static final int BLUEGIGA = 0x0047;
-
-    /*
-     * Marvell Technology Group Ltd.
-     */
-    public static final int MARVELL = 0x0048;
-
-    /*
-     * 3DSP Corporation.
-     */
-    public static final int THREE_DSP = 0x0049;
-
-    /*
-     * Accel Semiconductor Ltd.
-     */
-    public static final int ACCEL_SEMICONDUCTOR = 0x004A;
-
-    /*
-     * Continental Automotive Systems.
-     */
-    public static final int CONTINENTAL_AUTOMOTIVE = 0x004B;
-
-    /*
-     * Apple, Inc.
-     */
-    public static final int APPLE = 0x004C;
-
-    /*
-     * Staccato Communications, Inc.
-     */
-    public static final int STACCATO_COMMUNICATIONS = 0x004D;
-
-    /*
-     * Avago Technologies.
-     */
-    public static final int AVAGO = 0x004E;
-
-    /*
-     * APT Licensing Ltd.
-     */
-    public static final int APT_LICENSING = 0x004F;
-
-    /*
-     * SiRF Technology, Inc.
-     */
-    public static final int SIRF_TECHNOLOGY = 0x0050;
-
-    /*
-     * Tzero Technologies, Inc.
-     */
-    public static final int TZERO_TECHNOLOGIES = 0x0051;
-
-    /*
-     * J&M Corporation.
-     */
-    public static final int J_AND_M = 0x0052;
-
-    /*
-     * Free2move AB.
-     */
-    public static final int FREE2MOVE = 0x0053;
-
-    /*
-     * 3DiJoy Corporation.
-     */
-    public static final int THREE_DIJOY = 0x0054;
-
-    /*
-     * Plantronics, Inc.
-     */
-    public static final int PLANTRONICS = 0x0055;
-
-    /*
-     * Sony Ericsson Mobile Communications.
-     */
-    public static final int SONY_ERICSSON = 0x0056;
-
-    /*
-     * Harman International Industries, Inc.
-     */
-    public static final int HARMAN_INTERNATIONAL = 0x0057;
-
-    /*
-     * Vizio, Inc.
-     */
-    public static final int VIZIO = 0x0058;
-
-    /*
-     * Nordic Semiconductor ASA.
-     */
-    public static final int NORDIC_SEMICONDUCTOR = 0x0059;
-
-    /*
-     * EM Microelectronic-Marin SA.
-     */
-    public static final int EM_MICROELECTRONIC_MARIN = 0x005A;
-
-    /*
-     * Ralink Technology Corporation.
-     */
-    public static final int RALINK_TECHNOLOGY = 0x005B;
-
-    /*
-     * Belkin International, Inc.
-     */
-    public static final int BELKIN_INTERNATIONAL = 0x005C;
-
-    /*
-     * Realtek Semiconductor Corporation.
-     */
-    public static final int REALTEK_SEMICONDUCTOR = 0x005D;
-
-    /*
-     * Stonestreet One, LLC.
-     */
-    public static final int STONESTREET_ONE = 0x005E;
-
-    /*
-     * Wicentric, Inc.
-     */
-    public static final int WICENTRIC = 0x005F;
-
-    /*
-     * RivieraWaves S.A.S.
-     */
-    public static final int RIVIERAWAVES = 0x0060;
-
-    /*
-     * RDA Microelectronics.
-     */
-    public static final int RDA_MICROELECTRONICS = 0x0061;
-
-    /*
-     * Gibson Guitars.
-     */
-    public static final int GIBSON_GUITARS = 0x0062;
-
-    /*
-     * MiCommand Inc.
-     */
-    public static final int MICOMMAND = 0x0063;
-
-    /*
-     * Band XI International, LLC.
-     */
-    public static final int BAND_XI_INTERNATIONAL = 0x0064;
-
-    /*
-     * Hewlett-Packard Company.
-     */
-    public static final int HEWLETT_PACKARD = 0x0065;
-
-    /*
-     * 9Solutions Oy.
-     */
-    public static final int NINE_SOLUTIONS = 0x0066;
-
-    /*
-     * GN Netcom A/S.
-     */
-    public static final int GN_NETCOM = 0x0067;
-
-    /*
-     * General Motors.
-     */
-    public static final int GENERAL_MOTORS = 0x0068;
-
-    /*
-     * A&D Engineering, Inc.
-     */
-    public static final int A_AND_D_ENGINEERING = 0x0069;
-
-    /*
-     * MindTree Ltd.
-     */
-    public static final int MINDTREE = 0x006A;
-
-    /*
-     * Polar Electro OY.
-     */
-    public static final int POLAR_ELECTRO = 0x006B;
-
-    /*
-     * Beautiful Enterprise Co., Ltd.
-     */
-    public static final int BEAUTIFUL_ENTERPRISE = 0x006C;
-
-    /*
-     * BriarTek, Inc.
-     */
-    public static final int BRIARTEK = 0x006D;
-
-    /*
-     * Summit Data Communications, Inc.
-     */
-    public static final int SUMMIT_DATA_COMMUNICATIONS = 0x006E;
-
-    /*
-     * Sound ID.
-     */
-    public static final int SOUND_ID = 0x006F;
-
-    /*
-     * Monster, LLC.
-     */
-    public static final int MONSTER = 0x0070;
-
-    /*
-     * connectBlue AB.
-     */
-    public static final int CONNECTBLUE = 0x0071;
-
-    /*
-     * ShangHai Super Smart Electronics Co. Ltd.
-     */
-    public static final int SHANGHAI_SUPER_SMART_ELECTRONICS = 0x0072;
-
-    /*
-     * Group Sense Ltd.
-     */
-    public static final int GROUP_SENSE = 0x0073;
-
-    /*
-     * Zomm, LLC.
-     */
-    public static final int ZOMM = 0x0074;
-
-    /*
-     * Samsung Electronics Co. Ltd.
-     */
-    public static final int SAMSUNG_ELECTRONICS = 0x0075;
-
-    /*
-     * Creative Technology Ltd.
-     */
-    public static final int CREATIVE_TECHNOLOGY = 0x0076;
-
-    /*
-     * Laird Technologies.
-     */
-    public static final int LAIRD_TECHNOLOGIES = 0x0077;
-
-    /*
-     * Nike, Inc.
-     */
-    public static final int NIKE = 0x0078;
-
-    /*
-     * lesswire AG.
-     */
-    public static final int LESSWIRE = 0x0079;
-
-    /*
-     * MStar Semiconductor, Inc.
-     */
-    public static final int MSTAR_SEMICONDUCTOR = 0x007A;
-
-    /*
-     * Hanlynn Technologies.
-     */
-    public static final int HANLYNN_TECHNOLOGIES = 0x007B;
-
-    /*
-     * A & R Cambridge.
-     */
-    public static final int A_AND_R_CAMBRIDGE = 0x007C;
-
-    /*
-     * Seers Technology Co. Ltd.
-     */
-    public static final int SEERS_TECHNOLOGY = 0x007D;
-
-    /*
-     * Sports Tracking Technologies Ltd.
-     */
-    public static final int SPORTS_TRACKING_TECHNOLOGIES = 0x007E;
-
-    /*
-     * Autonet Mobile.
-     */
-    public static final int AUTONET_MOBILE = 0x007F;
-
-    /*
-     * DeLorme Publishing Company, Inc.
-     */
-    public static final int DELORME_PUBLISHING_COMPANY = 0x0080;
-
-    /*
-     * WuXi Vimicro.
-     */
-    public static final int WUXI_VIMICRO = 0x0081;
-
-    /*
-     * Sennheiser Communications A/S.
-     */
-    public static final int SENNHEISER_COMMUNICATIONS = 0x0082;
-
-    /*
-     * TimeKeeping Systems, Inc.
-     */
-    public static final int TIMEKEEPING_SYSTEMS = 0x0083;
-
-    /*
-     * Ludus Helsinki Ltd.
-     */
-    public static final int LUDUS_HELSINKI = 0x0084;
-
-    /*
-     * BlueRadios, Inc.
-     */
-    public static final int BLUERADIOS = 0x0085;
-
-    /*
-     * equinox AG.
-     */
-    public static final int EQUINOX_AG = 0x0086;
-
-    /*
-     * Garmin International, Inc.
-     */
-    public static final int GARMIN_INTERNATIONAL = 0x0087;
-
-    /*
-     * Ecotest.
-     */
-    public static final int ECOTEST = 0x0088;
-
-    /*
-     * GN ReSound A/S.
-     */
-    public static final int GN_RESOUND = 0x0089;
-
-    /*
-     * Jawbone.
-     */
-    public static final int JAWBONE = 0x008A;
-
-    /*
-     * Topcorn Positioning Systems, LLC.
-     */
-    public static final int TOPCORN_POSITIONING_SYSTEMS = 0x008B;
-
-    /*
-     * Qualcomm Labs, Inc.
-     */
-    public static final int QUALCOMM_LABS = 0x008C;
-
-    /*
-     * Zscan Software.
-     */
-    public static final int ZSCAN_SOFTWARE = 0x008D;
-
-    /*
-     * Quintic Corp.
-     */
-    public static final int QUINTIC = 0x008E;
-
-    /*
-     * Stollman E+V GmbH.
-     */
-    public static final int STOLLMAN_E_PLUS_V = 0x008F;
-
-    /*
-     * Funai Electric Co., Ltd.
-     */
-    public static final int FUNAI_ELECTRIC = 0x0090;
-
-    /*
-     * Advanced PANMOBIL Systems GmbH & Co. KG.
-     */
-    public static final int ADVANCED_PANMOBIL_SYSTEMS = 0x0091;
-
-    /*
-     * ThinkOptics, Inc.
-     */
-    public static final int THINKOPTICS = 0x0092;
-
-    /*
-     * Universal Electronics, Inc.
-     */
-    public static final int UNIVERSAL_ELECTRONICS = 0x0093;
-
-    /*
-     * Airoha Technology Corp.
-     */
-    public static final int AIROHA_TECHNOLOGY = 0x0094;
-
-    /*
-     * NEC Lighting, Ltd.
-     */
-    public static final int NEC_LIGHTING = 0x0095;
-
-    /*
-     * ODM Technology, Inc.
-     */
-    public static final int ODM_TECHNOLOGY = 0x0096;
-
-    /*
-     * Bluetrek Technologies Limited.
-     */
-    public static final int BLUETREK_TECHNOLOGIES = 0x0097;
-
-    /*
-     * zer01.tv GmbH.
-     */
-    public static final int ZER01_TV = 0x0098;
-
-    /*
-     * i.Tech Dynamic Global Distribution Ltd.
-     */
-    public static final int I_TECH_DYNAMIC_GLOBAL_DISTRIBUTION = 0x0099;
-
-    /*
-     * Alpwise.
-     */
-    public static final int ALPWISE = 0x009A;
-
-    /*
-     * Jiangsu Toppower Automotive Electronics Co., Ltd.
-     */
-    public static final int JIANGSU_TOPPOWER_AUTOMOTIVE_ELECTRONICS = 0x009B;
-
-    /*
-     * Colorfy, Inc.
-     */
-    public static final int COLORFY = 0x009C;
-
-    /*
-     * Geoforce Inc.
-     */
-    public static final int GEOFORCE = 0x009D;
-
-    /*
-     * Bose Corporation.
-     */
-    public static final int BOSE = 0x009E;
-
-    /*
-     * Suunto Oy.
-     */
-    public static final int SUUNTO = 0x009F;
-
-    /*
-     * Kensington Computer Products Group.
-     */
-    public static final int KENSINGTON_COMPUTER_PRODUCTS_GROUP = 0x00A0;
-
-    /*
-     * SR-Medizinelektronik.
-     */
-    public static final int SR_MEDIZINELEKTRONIK = 0x00A1;
-
-    /*
-     * Vertu Corporation Limited.
-     */
-    public static final int VERTU = 0x00A2;
-
-    /*
-     * Meta Watch Ltd.
-     */
-    public static final int META_WATCH = 0x00A3;
-
-    /*
-     * LINAK A/S.
-     */
-    public static final int LINAK = 0x00A4;
-
-    /*
-     * OTL Dynamics LLC.
-     */
-    public static final int OTL_DYNAMICS = 0x00A5;
-
-    /*
-     * Panda Ocean Inc.
-     */
-    public static final int PANDA_OCEAN = 0x00A6;
-
-    /*
-     * Visteon Corporation.
-     */
-    public static final int VISTEON = 0x00A7;
-
-    /*
-     * ARP Devices Limited.
-     */
-    public static final int ARP_DEVICES = 0x00A8;
-
-    /*
-     * Magneti Marelli S.p.A.
-     */
-    public static final int MAGNETI_MARELLI = 0x00A9;
-
-    /*
-     * CAEN RFID srl.
-     */
-    public static final int CAEN_RFID = 0x00AA;
-
-    /*
-     * Ingenieur-Systemgruppe Zahn GmbH.
-     */
-    public static final int INGENIEUR_SYSTEMGRUPPE_ZAHN = 0x00AB;
-
-    /*
-     * Green Throttle Games.
-     */
-    public static final int GREEN_THROTTLE_GAMES = 0x00AC;
-
-    /*
-     * Peter Systemtechnik GmbH.
-     */
-    public static final int PETER_SYSTEMTECHNIK = 0x00AD;
-
-    /*
-     * Omegawave Oy.
-     */
-    public static final int OMEGAWAVE = 0x00AE;
-
-    /*
-     * Cinetix.
-     */
-    public static final int CINETIX = 0x00AF;
-
-    /*
-     * Passif Semiconductor Corp.
-     */
-    public static final int PASSIF_SEMICONDUCTOR = 0x00B0;
-
-    /*
-     * Saris Cycling Group, Inc.
-     */
-    public static final int SARIS_CYCLING_GROUP = 0x00B1;
-
-    /*
-     * Bekey A/S.
-     */
-    public static final int BEKEY = 0x00B2;
-
-    /*
-     * Clarinox Technologies Pty. Ltd.
-     */
-    public static final int CLARINOX_TECHNOLOGIES = 0x00B3;
-
-    /*
-     * BDE Technology Co., Ltd.
-     */
-    public static final int BDE_TECHNOLOGY = 0x00B4;
-
-    /*
-     * Swirl Networks.
-     */
-    public static final int SWIRL_NETWORKS = 0x00B5;
-
-    /*
-     * Meso international.
-     */
-    public static final int MESO_INTERNATIONAL = 0x00B6;
-
-    /*
-     * TreLab Ltd.
-     */
-    public static final int TRELAB = 0x00B7;
-
-    /*
-     * Qualcomm Innovation Center, Inc. (QuIC).
-     */
-    public static final int QUALCOMM_INNOVATION_CENTER = 0x00B8;
-
-    /*
-     * Johnson Controls, Inc.
-     */
-    public static final int JOHNSON_CONTROLS = 0x00B9;
-
-    /*
-     * Starkey Laboratories Inc.
-     */
-    public static final int STARKEY_LABORATORIES = 0x00BA;
-
-    /*
-     * S-Power Electronics Limited.
-     */
-    public static final int S_POWER_ELECTRONICS = 0x00BB;
-
-    /*
-     * Ace Sensor Inc.
-     */
-    public static final int ACE_SENSOR = 0x00BC;
-
-    /*
-     * Aplix Corporation.
-     */
-    public static final int APLIX = 0x00BD;
-
-    /*
-     * AAMP of America.
-     */
-    public static final int AAMP_OF_AMERICA = 0x00BE;
-
-    /*
-     * Stalmart Technology Limited.
-     */
-    public static final int STALMART_TECHNOLOGY = 0x00BF;
-
-    /*
-     * AMICCOM Electronics Corporation.
-     */
-    public static final int AMICCOM_ELECTRONICS = 0x00C0;
-
-    /*
-     * Shenzhen Excelsecu Data Technology Co.,Ltd.
-     */
-    public static final int SHENZHEN_EXCELSECU_DATA_TECHNOLOGY = 0x00C1;
-
-    /*
-     * Geneq Inc.
-     */
-    public static final int GENEQ = 0x00C2;
-
-    /*
-     * adidas AG.
-     */
-    public static final int ADIDAS = 0x00C3;
-
-    /*
-     * LG Electronics.
-     */
-    public static final int LG_ELECTRONICS = 0x00C4;
-
-    /*
-     * Onset Computer Corporation.
-     */
-    public static final int ONSET_COMPUTER = 0x00C5;
-
-    /*
-     * Selfly BV.
-     */
-    public static final int SELFLY = 0x00C6;
-
-    /*
-     * Quuppa Oy.
-     */
-    public static final int QUUPPA = 0x00C7;
-
-    /*
-     * GeLo Inc.
-     */
-    public static final int GELO = 0x00C8;
-
-    /*
-     * Evluma.
-     */
-    public static final int EVLUMA = 0x00C9;
-
-    /*
-     * MC10.
-     */
-    public static final int MC10 = 0x00CA;
-
-    /*
-     * Binauric SE.
-     */
-    public static final int BINAURIC = 0x00CB;
-
-    /*
-     * Beats Electronics.
-     */
-    public static final int BEATS_ELECTRONICS = 0x00CC;
-
-    /*
-     * Microchip Technology Inc.
-     */
-    public static final int MICROCHIP_TECHNOLOGY = 0x00CD;
-
-    /*
-     * Elgato Systems GmbH.
-     */
-    public static final int ELGATO_SYSTEMS = 0x00CE;
-
-    /*
-     * ARCHOS SA.
-     */
-    public static final int ARCHOS = 0x00CF;
-
-    /*
-     * Dexcom, Inc.
-     */
-    public static final int DEXCOM = 0x00D0;
-
-    /*
-     * Polar Electro Europe B.V.
-     */
-    public static final int POLAR_ELECTRO_EUROPE = 0x00D1;
-
-    /*
-     * Dialog Semiconductor B.V.
-     */
-    public static final int DIALOG_SEMICONDUCTOR = 0x00D2;
-
-    /*
-     * Taixingbang Technology (HK) Co,. LTD.
-     */
-    public static final int TAIXINGBANG_TECHNOLOGY = 0x00D3;
-
-    /*
-     * Kawantech.
-     */
-    public static final int KAWANTECH = 0x00D4;
-
-    /*
-     * Austco Communication Systems.
-     */
-    public static final int AUSTCO_COMMUNICATION_SYSTEMS = 0x00D5;
-
-    /*
-     * Timex Group USA, Inc.
-     */
-    public static final int TIMEX_GROUP_USA = 0x00D6;
-
-    /*
-     * Qualcomm Technologies, Inc.
-     */
-    public static final int QUALCOMM_TECHNOLOGIES = 0x00D7;
-
-    /*
-     * Qualcomm Connected Experiences, Inc.
-     */
-    public static final int QUALCOMM_CONNECTED_EXPERIENCES = 0x00D8;
-
-    /*
-     * Voyetra Turtle Beach.
-     */
-    public static final int VOYETRA_TURTLE_BEACH = 0x00D9;
-
-    /*
-     * txtr GmbH.
-     */
-    public static final int TXTR = 0x00DA;
-
-    /*
-     * Biosentronics.
-     */
-    public static final int BIOSENTRONICS = 0x00DB;
-
-    /*
-     * Procter & Gamble.
-     */
-    public static final int PROCTER_AND_GAMBLE = 0x00DC;
-
-    /*
-     * Hosiden Corporation.
-     */
-    public static final int HOSIDEN = 0x00DD;
-
-    /*
-     * Muzik LLC.
-     */
-    public static final int MUZIK = 0x00DE;
-
-    /*
-     * Misfit Wearables Corp.
-     */
-    public static final int MISFIT_WEARABLES = 0x00DF;
-
-    /*
-     * Google.
-     */
-    public static final int GOOGLE = 0x00E0;
-
-    /*
-     * Danlers Ltd.
-     */
-    public static final int DANLERS = 0x00E1;
-
-    /*
-     * Semilink Inc.
-     */
-    public static final int SEMILINK = 0x00E2;
-
-    /*
-     * You can't instantiate one of these.
-     */
-    private BluetoothAssignedNumbers() {
-    }
-
-}
diff --git a/core/java/android/bluetooth/BluetoothAudioConfig.java b/core/java/android/bluetooth/BluetoothAudioConfig.java
deleted file mode 100644
index 4c8b8c1..0000000
--- a/core/java/android/bluetooth/BluetoothAudioConfig.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2009 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.bluetooth;
-
-import android.annotation.Nullable;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Represents the audio configuration for a Bluetooth A2DP source device.
- *
- * {@see BluetoothA2dpSink}
- *
- * {@hide}
- */
-public final class BluetoothAudioConfig implements Parcelable {
-
-    private final int mSampleRate;
-    private final int mChannelConfig;
-    private final int mAudioFormat;
-
-    public BluetoothAudioConfig(int sampleRate, int channelConfig, int audioFormat) {
-        mSampleRate = sampleRate;
-        mChannelConfig = channelConfig;
-        mAudioFormat = audioFormat;
-    }
-
-    @Override
-    public boolean equals(@Nullable Object o) {
-        if (o instanceof BluetoothAudioConfig) {
-            BluetoothAudioConfig bac = (BluetoothAudioConfig) o;
-            return (bac.mSampleRate == mSampleRate && bac.mChannelConfig == mChannelConfig
-                    && bac.mAudioFormat == mAudioFormat);
-        }
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        return mSampleRate | (mChannelConfig << 24) | (mAudioFormat << 28);
-    }
-
-    @Override
-    public String toString() {
-        return "{mSampleRate:" + mSampleRate + ",mChannelConfig:" + mChannelConfig
-                + ",mAudioFormat:" + mAudioFormat + "}";
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    public static final @android.annotation.NonNull Parcelable.Creator<BluetoothAudioConfig> CREATOR =
-            new Parcelable.Creator<BluetoothAudioConfig>() {
-                public BluetoothAudioConfig createFromParcel(Parcel in) {
-                    int sampleRate = in.readInt();
-                    int channelConfig = in.readInt();
-                    int audioFormat = in.readInt();
-                    return new BluetoothAudioConfig(sampleRate, channelConfig, audioFormat);
-                }
-
-                public BluetoothAudioConfig[] newArray(int size) {
-                    return new BluetoothAudioConfig[size];
-                }
-            };
-
-    @Override
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeInt(mSampleRate);
-        out.writeInt(mChannelConfig);
-        out.writeInt(mAudioFormat);
-    }
-
-    /**
-     * Returns the sample rate in samples per second
-     *
-     * @return sample rate
-     */
-    public int getSampleRate() {
-        return mSampleRate;
-    }
-
-    /**
-     * Returns the channel configuration (either {@link android.media.AudioFormat#CHANNEL_IN_MONO}
-     * or {@link android.media.AudioFormat#CHANNEL_IN_STEREO})
-     *
-     * @return channel configuration
-     */
-    public int getChannelConfig() {
-        return mChannelConfig;
-    }
-
-    /**
-     * Returns the channel audio format (either {@link android.media.AudioFormat#ENCODING_PCM_16BIT}
-     * or {@link android.media.AudioFormat#ENCODING_PCM_8BIT}
-     *
-     * @return audio format
-     */
-    public int getAudioFormat() {
-        return mAudioFormat;
-    }
-}
diff --git a/core/java/android/bluetooth/BluetoothAvrcp.java b/core/java/android/bluetooth/BluetoothAvrcp.java
deleted file mode 100644
index 1a4c759..0000000
--- a/core/java/android/bluetooth/BluetoothAvrcp.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-/**
- * This class contains constants for Bluetooth AVRCP profile.
- *
- * {@hide}
- */
-public final class BluetoothAvrcp {
-
-    /*
-     * State flags for Passthrough commands
-    */
-    public static final int PASSTHROUGH_STATE_PRESS = 0;
-    public static final int PASSTHROUGH_STATE_RELEASE = 1;
-
-    /*
-     * Operation IDs for Passthrough commands
-    */
-    public static final int PASSTHROUGH_ID_SELECT = 0x00;    /* select */
-    public static final int PASSTHROUGH_ID_UP = 0x01;    /* up */
-    public static final int PASSTHROUGH_ID_DOWN = 0x02;    /* down */
-    public static final int PASSTHROUGH_ID_LEFT = 0x03;    /* left */
-    public static final int PASSTHROUGH_ID_RIGHT = 0x04;    /* right */
-    public static final int PASSTHROUGH_ID_RIGHT_UP = 0x05;    /* right-up */
-    public static final int PASSTHROUGH_ID_RIGHT_DOWN = 0x06;    /* right-down */
-    public static final int PASSTHROUGH_ID_LEFT_UP = 0x07;    /* left-up */
-    public static final int PASSTHROUGH_ID_LEFT_DOWN = 0x08;    /* left-down */
-    public static final int PASSTHROUGH_ID_ROOT_MENU = 0x09;    /* root menu */
-    public static final int PASSTHROUGH_ID_SETUP_MENU = 0x0A;    /* setup menu */
-    public static final int PASSTHROUGH_ID_CONT_MENU = 0x0B;    /* contents menu */
-    public static final int PASSTHROUGH_ID_FAV_MENU = 0x0C;    /* favorite menu */
-    public static final int PASSTHROUGH_ID_EXIT = 0x0D;    /* exit */
-    public static final int PASSTHROUGH_ID_0 = 0x20;    /* 0 */
-    public static final int PASSTHROUGH_ID_1 = 0x21;    /* 1 */
-    public static final int PASSTHROUGH_ID_2 = 0x22;    /* 2 */
-    public static final int PASSTHROUGH_ID_3 = 0x23;    /* 3 */
-    public static final int PASSTHROUGH_ID_4 = 0x24;    /* 4 */
-    public static final int PASSTHROUGH_ID_5 = 0x25;    /* 5 */
-    public static final int PASSTHROUGH_ID_6 = 0x26;    /* 6 */
-    public static final int PASSTHROUGH_ID_7 = 0x27;    /* 7 */
-    public static final int PASSTHROUGH_ID_8 = 0x28;    /* 8 */
-    public static final int PASSTHROUGH_ID_9 = 0x29;    /* 9 */
-    public static final int PASSTHROUGH_ID_DOT = 0x2A;    /* dot */
-    public static final int PASSTHROUGH_ID_ENTER = 0x2B;    /* enter */
-    public static final int PASSTHROUGH_ID_CLEAR = 0x2C;    /* clear */
-    public static final int PASSTHROUGH_ID_CHAN_UP = 0x30;    /* channel up */
-    public static final int PASSTHROUGH_ID_CHAN_DOWN = 0x31;    /* channel down */
-    public static final int PASSTHROUGH_ID_PREV_CHAN = 0x32;    /* previous channel */
-    public static final int PASSTHROUGH_ID_SOUND_SEL = 0x33;    /* sound select */
-    public static final int PASSTHROUGH_ID_INPUT_SEL = 0x34;    /* input select */
-    public static final int PASSTHROUGH_ID_DISP_INFO = 0x35;    /* display information */
-    public static final int PASSTHROUGH_ID_HELP = 0x36;    /* help */
-    public static final int PASSTHROUGH_ID_PAGE_UP = 0x37;    /* page up */
-    public static final int PASSTHROUGH_ID_PAGE_DOWN = 0x38;    /* page down */
-    public static final int PASSTHROUGH_ID_POWER = 0x40;    /* power */
-    public static final int PASSTHROUGH_ID_VOL_UP = 0x41;    /* volume up */
-    public static final int PASSTHROUGH_ID_VOL_DOWN = 0x42;    /* volume down */
-    public static final int PASSTHROUGH_ID_MUTE = 0x43;    /* mute */
-    public static final int PASSTHROUGH_ID_PLAY = 0x44;    /* play */
-    public static final int PASSTHROUGH_ID_STOP = 0x45;    /* stop */
-    public static final int PASSTHROUGH_ID_PAUSE = 0x46;    /* pause */
-    public static final int PASSTHROUGH_ID_RECORD = 0x47;    /* record */
-    public static final int PASSTHROUGH_ID_REWIND = 0x48;    /* rewind */
-    public static final int PASSTHROUGH_ID_FAST_FOR = 0x49;    /* fast forward */
-    public static final int PASSTHROUGH_ID_EJECT = 0x4A;    /* eject */
-    public static final int PASSTHROUGH_ID_FORWARD = 0x4B;    /* forward */
-    public static final int PASSTHROUGH_ID_BACKWARD = 0x4C;    /* backward */
-    public static final int PASSTHROUGH_ID_ANGLE = 0x50;    /* angle */
-    public static final int PASSTHROUGH_ID_SUBPICT = 0x51;    /* subpicture */
-    public static final int PASSTHROUGH_ID_F1 = 0x71;    /* F1 */
-    public static final int PASSTHROUGH_ID_F2 = 0x72;    /* F2 */
-    public static final int PASSTHROUGH_ID_F3 = 0x73;    /* F3 */
-    public static final int PASSTHROUGH_ID_F4 = 0x74;    /* F4 */
-    public static final int PASSTHROUGH_ID_F5 = 0x75;    /* F5 */
-    public static final int PASSTHROUGH_ID_VENDOR = 0x7E;    /* vendor unique */
-    public static final int PASSTHROUGH_KEYPRESSED_RELEASE = 0x80;
-}
diff --git a/core/java/android/bluetooth/BluetoothAvrcpController.java b/core/java/android/bluetooth/BluetoothAvrcpController.java
deleted file mode 100644
index 81fc3e1..0000000
--- a/core/java/android/bluetooth/BluetoothAvrcpController.java
+++ /dev/null
@@ -1,298 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-import static android.bluetooth.BluetoothUtils.getSyncTimeout;
-
-import android.annotation.RequiresPermission;
-import android.annotation.SdkConstant;
-import android.annotation.SdkConstant.SdkConstantType;
-import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
-import android.bluetooth.annotations.RequiresLegacyBluetoothPermission;
-import android.content.AttributionSource;
-import android.content.Context;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.util.Log;
-
-import com.android.modules.utils.SynchronousResultReceiver;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.TimeoutException;
-
-/**
- * This class provides the public APIs to control the Bluetooth AVRCP Controller. It currently
- * supports player information, playback support and track metadata.
- *
- * <p>BluetoothAvrcpController is a proxy object for controlling the Bluetooth AVRCP
- * Service via IPC. Use {@link BluetoothAdapter#getProfileProxy} to get
- * the BluetoothAvrcpController proxy object.
- *
- * {@hide}
- */
-public final class BluetoothAvrcpController implements BluetoothProfile {
-    private static final String TAG = "BluetoothAvrcpController";
-    private static final boolean DBG = false;
-    private static final boolean VDBG = false;
-
-    /**
-     * Intent used to broadcast the change in connection state of the AVRCP Controller
-     * profile.
-     *
-     * <p>This intent will have 3 extras:
-     * <ul>
-     * <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
-     * <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li>
-     * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
-     * </ul>
-     *
-     * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
-     * {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTING},
-     * {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTING}.
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_CONNECTION_STATE_CHANGED =
-            "android.bluetooth.avrcp-controller.profile.action.CONNECTION_STATE_CHANGED";
-
-    /**
-     * Intent used to broadcast the change in player application setting state on AVRCP AG.
-     *
-     * <p>This intent will have the following extras:
-     * <ul>
-     * <li> {@link #EXTRA_PLAYER_SETTING} - {@link BluetoothAvrcpPlayerSettings} containing the
-     * most recent player setting. </li>
-     * </ul>
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_PLAYER_SETTING =
-            "android.bluetooth.avrcp-controller.profile.action.PLAYER_SETTING";
-
-    public static final String EXTRA_PLAYER_SETTING =
-            "android.bluetooth.avrcp-controller.profile.extra.PLAYER_SETTING";
-
-    private final BluetoothAdapter mAdapter;
-    private final AttributionSource mAttributionSource;
-    private final BluetoothProfileConnector<IBluetoothAvrcpController> mProfileConnector =
-            new BluetoothProfileConnector(this, BluetoothProfile.AVRCP_CONTROLLER,
-                    "BluetoothAvrcpController", IBluetoothAvrcpController.class.getName()) {
-                @Override
-                public IBluetoothAvrcpController getServiceInterface(IBinder service) {
-                    return IBluetoothAvrcpController.Stub.asInterface(service);
-                }
-    };
-
-    /**
-     * Create a BluetoothAvrcpController proxy object for interacting with the local
-     * Bluetooth AVRCP service.
-     */
-    /* package */ BluetoothAvrcpController(Context context, ServiceListener listener,
-            BluetoothAdapter adapter) {
-        mAdapter = adapter;
-        mAttributionSource = adapter.getAttributionSource();
-        mProfileConnector.connect(context, listener);
-    }
-
-    /*package*/ void close() {
-        mProfileConnector.disconnect();
-    }
-
-    private IBluetoothAvrcpController getService() {
-        return mProfileConnector.getService();
-    }
-
-    @Override
-    public void finalize() {
-        close();
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public List<BluetoothDevice> getConnectedDevices() {
-        if (VDBG) log("getConnectedDevices()");
-        final IBluetoothAvrcpController service = getService();
-        final List<BluetoothDevice> defaultValue = new ArrayList<BluetoothDevice>();
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<List<BluetoothDevice>> recv =
-                        new SynchronousResultReceiver();
-                service.getConnectedDevices(mAttributionSource, recv);
-                return Attributable.setAttributionSource(
-                        recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
-                        mAttributionSource);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
-        if (VDBG) log("getDevicesMatchingStates()");
-        final IBluetoothAvrcpController service = getService();
-        final List<BluetoothDevice> defaultValue = new ArrayList<BluetoothDevice>();
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<List<BluetoothDevice>> recv =
-                        new SynchronousResultReceiver();
-                service.getDevicesMatchingConnectionStates(states, mAttributionSource, recv);
-                return Attributable.setAttributionSource(
-                        recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
-                        mAttributionSource);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public int getConnectionState(BluetoothDevice device) {
-        if (VDBG) log("getState(" + device + ")");
-        final IBluetoothAvrcpController service = getService();
-        final int defaultValue = BluetoothProfile.STATE_DISCONNECTED;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
-                service.getConnectionState(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Gets the player application settings.
-     *
-     * @return the {@link BluetoothAvrcpPlayerSettings} or {@link null} if there is an error.
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public BluetoothAvrcpPlayerSettings getPlayerSettings(BluetoothDevice device) {
-        if (DBG) Log.d(TAG, "getPlayerSettings");
-        BluetoothAvrcpPlayerSettings settings = null;
-        final IBluetoothAvrcpController service = getService();
-        final BluetoothAvrcpPlayerSettings defaultValue = null;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<BluetoothAvrcpPlayerSettings> recv =
-                        new SynchronousResultReceiver();
-                service.getPlayerSettings(device, mAttributionSource, recv);
-                settings = recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Sets the player app setting for current player.
-     * returns true in case setting is supported by remote, false otherwise
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean setPlayerApplicationSetting(BluetoothAvrcpPlayerSettings plAppSetting) {
-        if (DBG) Log.d(TAG, "setPlayerApplicationSetting");
-        final IBluetoothAvrcpController service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.setPlayerApplicationSetting(plAppSetting, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Send Group Navigation Command to Remote.
-     * possible keycode values: next_grp, previous_grp defined above
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public void sendGroupNavigationCmd(BluetoothDevice device, int keyCode, int keyState) {
-        Log.d(TAG, "sendGroupNavigationCmd dev = " + device + " key " + keyCode + " State = "
-                + keyState);
-        final IBluetoothAvrcpController service = getService();
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver recv = new SynchronousResultReceiver();
-                service.sendGroupNavigationCmd(device, keyCode, keyState, mAttributionSource, recv);
-                recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(null);
-                return;
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-    }
-
-    private boolean isEnabled() {
-        return mAdapter.getState() == BluetoothAdapter.STATE_ON;
-    }
-
-    private static boolean isValidDevice(BluetoothDevice device) {
-        return device != null && BluetoothAdapter.checkBluetoothAddress(device.getAddress());
-    }
-
-    private static void log(String msg) {
-        Log.d(TAG, msg);
-    }
-}
diff --git a/core/java/android/bluetooth/BluetoothAvrcpPlayerSettings.java b/core/java/android/bluetooth/BluetoothAvrcpPlayerSettings.java
deleted file mode 100644
index 30aea1a..0000000
--- a/core/java/android/bluetooth/BluetoothAvrcpPlayerSettings.java
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.Log;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Class used to identify settings associated with the player on AG.
- *
- * {@hide}
- */
-public final class BluetoothAvrcpPlayerSettings implements Parcelable {
-    public static final String TAG = "BluetoothAvrcpPlayerSettings";
-
-    /**
-     * Equalizer setting.
-     */
-    public static final int SETTING_EQUALIZER = 0x01;
-
-    /**
-     * Repeat setting.
-     */
-    public static final int SETTING_REPEAT = 0x02;
-
-    /**
-     * Shuffle setting.
-     */
-    public static final int SETTING_SHUFFLE = 0x04;
-
-    /**
-     * Scan mode setting.
-     */
-    public static final int SETTING_SCAN = 0x08;
-
-    /**
-     * Invalid state.
-     *
-     * Used for returning error codes.
-     */
-    public static final int STATE_INVALID = -1;
-
-    /**
-     * OFF state.
-     *
-     * Denotes a general OFF state. Applies to all settings.
-     */
-    public static final int STATE_OFF = 0x00;
-
-    /**
-     * ON state.
-     *
-     * Applies to {@link SETTING_EQUALIZER}.
-     */
-    public static final int STATE_ON = 0x01;
-
-    /**
-     * Single track repeat.
-     *
-     * Applies only to {@link SETTING_REPEAT}.
-     */
-    public static final int STATE_SINGLE_TRACK = 0x02;
-
-    /**
-     * All track repeat/shuffle.
-     *
-     * Applies to {@link #SETTING_REPEAT}, {@link #SETTING_SHUFFLE} and {@link #SETTING_SCAN}.
-     */
-    public static final int STATE_ALL_TRACK = 0x03;
-
-    /**
-     * Group repeat/shuffle.
-     *
-     * Applies to {@link #SETTING_REPEAT}, {@link #SETTING_SHUFFLE} and {@link #SETTING_SCAN}.
-     */
-    public static final int STATE_GROUP = 0x04;
-
-    /**
-     * List of supported settings ORed.
-     */
-    private int mSettings;
-
-    /**
-     * Hash map of current capability values.
-     */
-    private Map<Integer, Integer> mSettingsValue = new HashMap<Integer, Integer>();
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeInt(mSettings);
-        out.writeInt(mSettingsValue.size());
-        for (int k : mSettingsValue.keySet()) {
-            out.writeInt(k);
-            out.writeInt(mSettingsValue.get(k));
-        }
-    }
-
-    public static final @android.annotation.NonNull Parcelable.Creator<BluetoothAvrcpPlayerSettings> CREATOR =
-            new Parcelable.Creator<BluetoothAvrcpPlayerSettings>() {
-        public BluetoothAvrcpPlayerSettings createFromParcel(Parcel in) {
-            return new BluetoothAvrcpPlayerSettings(in);
-        }
-
-        public BluetoothAvrcpPlayerSettings[] newArray(int size) {
-            return new BluetoothAvrcpPlayerSettings[size];
-        }
-    };
-
-    private BluetoothAvrcpPlayerSettings(Parcel in) {
-        mSettings = in.readInt();
-        int numSettings = in.readInt();
-        for (int i = 0; i < numSettings; i++) {
-            mSettingsValue.put(in.readInt(), in.readInt());
-        }
-    }
-
-    /**
-     * Create a new player settings object.
-     *
-     * @param settings a ORed value of SETTINGS_* defined above.
-     */
-    public BluetoothAvrcpPlayerSettings(int settings) {
-        mSettings = settings;
-    }
-
-    /**
-     * Get the supported settings.
-     *
-     * @return int ORed value of supported settings.
-     */
-    public int getSettings() {
-        return mSettings;
-    }
-
-    /**
-     * Add a setting value.
-     *
-     * The setting must be part of possible settings in {@link getSettings()}.
-     *
-     * @param setting setting config.
-     * @param value value for the setting.
-     * @throws IllegalStateException if the setting is not supported.
-     */
-    public void addSettingValue(int setting, int value) {
-        if ((setting & mSettings) == 0) {
-            Log.e(TAG, "Setting not supported: " + setting + " " + mSettings);
-            throw new IllegalStateException("Setting not supported: " + setting);
-        }
-        mSettingsValue.put(setting, value);
-    }
-
-    /**
-     * Get a setting value.
-     *
-     * The setting must be part of possible settings in {@link getSettings()}.
-     *
-     * @param setting setting config.
-     * @return value value for the setting.
-     * @throws IllegalStateException if the setting is not supported.
-     */
-    public int getSettingValue(int setting) {
-        if ((setting & mSettings) == 0) {
-            Log.e(TAG, "Setting not supported: " + setting + " " + mSettings);
-            throw new IllegalStateException("Setting not supported: " + setting);
-        }
-        Integer i = mSettingsValue.get(setting);
-        if (i == null) return -1;
-        return i;
-    }
-}
diff --git a/core/java/android/bluetooth/BluetoothClass.java b/core/java/android/bluetooth/BluetoothClass.java
deleted file mode 100755
index 8535b4f..0000000
--- a/core/java/android/bluetooth/BluetoothClass.java
+++ /dev/null
@@ -1,441 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-import android.annotation.Nullable;
-import android.annotation.TestApi;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.os.Build;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.Arrays;
-
-/**
- * Represents a Bluetooth class, which describes general characteristics
- * and capabilities of a device. For example, a Bluetooth class will
- * specify the general device type such as a phone, a computer, or
- * headset, and whether it's capable of services such as audio or telephony.
- *
- * <p>Every Bluetooth class is composed of zero or more service classes, and
- * exactly one device class. The device class is further broken down into major
- * and minor device class components.
- *
- * <p>{@link BluetoothClass} is useful as a hint to roughly describe a device
- * (for example to show an icon in the UI), but does not reliably describe which
- * Bluetooth profiles or services are actually supported by a device. Accurate
- * service discovery is done through SDP requests, which are automatically
- * performed when creating an RFCOMM socket with {@link
- * BluetoothDevice#createRfcommSocketToServiceRecord} and {@link
- * BluetoothAdapter#listenUsingRfcommWithServiceRecord}</p>
- *
- * <p>Use {@link BluetoothDevice#getBluetoothClass} to retrieve the class for
- * a remote device.
- *
- * <!--
- * The Bluetooth class is a 32 bit field. The format of these bits is defined at
- * http://www.bluetooth.org/Technical/AssignedNumbers/baseband.htm
- * (login required). This class contains that 32 bit field, and provides
- * constants and methods to determine which Service Class(es) and Device Class
- * are encoded in that field.
- * -->
- */
-public final class BluetoothClass implements Parcelable {
-    /**
-     * Legacy error value. Applications should use null instead.
-     *
-     * @hide
-     */
-    public static final int ERROR = 0xFF000000;
-
-    private final int mClass;
-
-    /** @hide */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
-    public BluetoothClass(int classInt) {
-        mClass = classInt;
-    }
-
-    @Override
-    public boolean equals(@Nullable Object o) {
-        if (o instanceof BluetoothClass) {
-            return mClass == ((BluetoothClass) o).mClass;
-        }
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        return mClass;
-    }
-
-    @Override
-    public String toString() {
-        return Integer.toHexString(mClass);
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    public static final @android.annotation.NonNull Parcelable.Creator<BluetoothClass> CREATOR =
-            new Parcelable.Creator<BluetoothClass>() {
-                public BluetoothClass createFromParcel(Parcel in) {
-                    return new BluetoothClass(in.readInt());
-                }
-
-                public BluetoothClass[] newArray(int size) {
-                    return new BluetoothClass[size];
-                }
-            };
-
-    @Override
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeInt(mClass);
-    }
-
-    /**
-     * Defines all service class constants.
-     * <p>Each {@link BluetoothClass} encodes zero or more service classes.
-     */
-    public static final class Service {
-        private static final int BITMASK = 0xFFE000;
-
-        public static final int LIMITED_DISCOVERABILITY = 0x002000;
-        public static final int LE_AUDIO = 0x004000;
-        public static final int POSITIONING = 0x010000;
-        public static final int NETWORKING = 0x020000;
-        public static final int RENDER = 0x040000;
-        public static final int CAPTURE = 0x080000;
-        public static final int OBJECT_TRANSFER = 0x100000;
-        public static final int AUDIO = 0x200000;
-        public static final int TELEPHONY = 0x400000;
-        public static final int INFORMATION = 0x800000;
-    }
-
-    /**
-     * Return true if the specified service class is supported by this
-     * {@link BluetoothClass}.
-     * <p>Valid service classes are the public constants in
-     * {@link BluetoothClass.Service}. For example, {@link
-     * BluetoothClass.Service#AUDIO}.
-     *
-     * @param service valid service class
-     * @return true if the service class is supported
-     */
-    public boolean hasService(int service) {
-        return ((mClass & Service.BITMASK & service) != 0);
-    }
-
-    /**
-     * Defines all device class constants.
-     * <p>Each {@link BluetoothClass} encodes exactly one device class, with
-     * major and minor components.
-     * <p>The constants in {@link
-     * BluetoothClass.Device} represent a combination of major and minor
-     * device components (the complete device class). The constants in {@link
-     * BluetoothClass.Device.Major} represent only major device classes.
-     * <p>See {@link BluetoothClass.Service} for service class constants.
-     */
-    public static class Device {
-        private static final int BITMASK = 0x1FFC;
-
-        /**
-         * Defines all major device class constants.
-         * <p>See {@link BluetoothClass.Device} for minor classes.
-         */
-        public static class Major {
-            private static final int BITMASK = 0x1F00;
-
-            public static final int MISC = 0x0000;
-            public static final int COMPUTER = 0x0100;
-            public static final int PHONE = 0x0200;
-            public static final int NETWORKING = 0x0300;
-            public static final int AUDIO_VIDEO = 0x0400;
-            public static final int PERIPHERAL = 0x0500;
-            public static final int IMAGING = 0x0600;
-            public static final int WEARABLE = 0x0700;
-            public static final int TOY = 0x0800;
-            public static final int HEALTH = 0x0900;
-            public static final int UNCATEGORIZED = 0x1F00;
-        }
-
-        // Devices in the COMPUTER major class
-        public static final int COMPUTER_UNCATEGORIZED = 0x0100;
-        public static final int COMPUTER_DESKTOP = 0x0104;
-        public static final int COMPUTER_SERVER = 0x0108;
-        public static final int COMPUTER_LAPTOP = 0x010C;
-        public static final int COMPUTER_HANDHELD_PC_PDA = 0x0110;
-        public static final int COMPUTER_PALM_SIZE_PC_PDA = 0x0114;
-        public static final int COMPUTER_WEARABLE = 0x0118;
-
-        // Devices in the PHONE major class
-        public static final int PHONE_UNCATEGORIZED = 0x0200;
-        public static final int PHONE_CELLULAR = 0x0204;
-        public static final int PHONE_CORDLESS = 0x0208;
-        public static final int PHONE_SMART = 0x020C;
-        public static final int PHONE_MODEM_OR_GATEWAY = 0x0210;
-        public static final int PHONE_ISDN = 0x0214;
-
-        // Minor classes for the AUDIO_VIDEO major class
-        public static final int AUDIO_VIDEO_UNCATEGORIZED = 0x0400;
-        public static final int AUDIO_VIDEO_WEARABLE_HEADSET = 0x0404;
-        public static final int AUDIO_VIDEO_HANDSFREE = 0x0408;
-        //public static final int AUDIO_VIDEO_RESERVED              = 0x040C;
-        public static final int AUDIO_VIDEO_MICROPHONE = 0x0410;
-        public static final int AUDIO_VIDEO_LOUDSPEAKER = 0x0414;
-        public static final int AUDIO_VIDEO_HEADPHONES = 0x0418;
-        public static final int AUDIO_VIDEO_PORTABLE_AUDIO = 0x041C;
-        public static final int AUDIO_VIDEO_CAR_AUDIO = 0x0420;
-        public static final int AUDIO_VIDEO_SET_TOP_BOX = 0x0424;
-        public static final int AUDIO_VIDEO_HIFI_AUDIO = 0x0428;
-        public static final int AUDIO_VIDEO_VCR = 0x042C;
-        public static final int AUDIO_VIDEO_VIDEO_CAMERA = 0x0430;
-        public static final int AUDIO_VIDEO_CAMCORDER = 0x0434;
-        public static final int AUDIO_VIDEO_VIDEO_MONITOR = 0x0438;
-        public static final int AUDIO_VIDEO_VIDEO_DISPLAY_AND_LOUDSPEAKER = 0x043C;
-        public static final int AUDIO_VIDEO_VIDEO_CONFERENCING = 0x0440;
-        //public static final int AUDIO_VIDEO_RESERVED              = 0x0444;
-        public static final int AUDIO_VIDEO_VIDEO_GAMING_TOY = 0x0448;
-
-        // Devices in the WEARABLE major class
-        public static final int WEARABLE_UNCATEGORIZED = 0x0700;
-        public static final int WEARABLE_WRIST_WATCH = 0x0704;
-        public static final int WEARABLE_PAGER = 0x0708;
-        public static final int WEARABLE_JACKET = 0x070C;
-        public static final int WEARABLE_HELMET = 0x0710;
-        public static final int WEARABLE_GLASSES = 0x0714;
-
-        // Devices in the TOY major class
-        public static final int TOY_UNCATEGORIZED = 0x0800;
-        public static final int TOY_ROBOT = 0x0804;
-        public static final int TOY_VEHICLE = 0x0808;
-        public static final int TOY_DOLL_ACTION_FIGURE = 0x080C;
-        public static final int TOY_CONTROLLER = 0x0810;
-        public static final int TOY_GAME = 0x0814;
-
-        // Devices in the HEALTH major class
-        public static final int HEALTH_UNCATEGORIZED = 0x0900;
-        public static final int HEALTH_BLOOD_PRESSURE = 0x0904;
-        public static final int HEALTH_THERMOMETER = 0x0908;
-        public static final int HEALTH_WEIGHING = 0x090C;
-        public static final int HEALTH_GLUCOSE = 0x0910;
-        public static final int HEALTH_PULSE_OXIMETER = 0x0914;
-        public static final int HEALTH_PULSE_RATE = 0x0918;
-        public static final int HEALTH_DATA_DISPLAY = 0x091C;
-
-        // Devices in PERIPHERAL major class
-        /**
-         * @hide
-         */
-        public static final int PERIPHERAL_NON_KEYBOARD_NON_POINTING = 0x0500;
-        /**
-         * @hide
-         */
-        public static final int PERIPHERAL_KEYBOARD = 0x0540;
-        /**
-         * @hide
-         */
-        public static final int PERIPHERAL_POINTING = 0x0580;
-        /**
-         * @hide
-         */
-        public static final int PERIPHERAL_KEYBOARD_POINTING = 0x05C0;
-    }
-
-    /**
-     * Return the major device class component of this {@link BluetoothClass}.
-     * <p>Values returned from this function can be compared with the
-     * public constants in {@link BluetoothClass.Device.Major} to determine
-     * which major class is encoded in this Bluetooth class.
-     *
-     * @return major device class component
-     */
-    public int getMajorDeviceClass() {
-        return (mClass & Device.Major.BITMASK);
-    }
-
-    /**
-     * Return the (major and minor) device class component of this
-     * {@link BluetoothClass}.
-     * <p>Values returned from this function can be compared with the
-     * public constants in {@link BluetoothClass.Device} to determine which
-     * device class is encoded in this Bluetooth class.
-     *
-     * @return device class component
-     */
-    public int getDeviceClass() {
-        return (mClass & Device.BITMASK);
-    }
-
-    /**
-     * Return the Bluetooth Class of Device (CoD) value including the
-     * {@link BluetoothClass.Service}, {@link BluetoothClass.Device.Major} and
-     * minor device fields.
-     *
-     * <p>This value is an integer representation of Bluetooth CoD as in
-     * Bluetooth specification.
-     *
-     * @see <a href="Bluetooth CoD">https://www.bluetooth.com/specifications/assigned-numbers/baseband</a>
-     *
-     * @hide
-     */
-    @TestApi
-    public int getClassOfDevice() {
-        return mClass;
-    }
-
-    /**
-     * Return the Bluetooth Class of Device (CoD) value including the
-     * {@link BluetoothClass.Service}, {@link BluetoothClass.Device.Major} and
-     * minor device fields.
-     *
-     * <p>This value is a byte array representation of Bluetooth CoD as in
-     * Bluetooth specification.
-     *
-     * <p>Bluetooth COD information is 3 bytes, but stored as an int. Hence the
-     * MSB is useless and needs to be thrown away. The lower 3 bytes are
-     * converted into a byte array MSB to LSB. Hence, using BIG_ENDIAN.
-     *
-     * @see <a href="Bluetooth CoD">https://www.bluetooth.com/specifications/assigned-numbers/baseband</a>
-     *
-     * @hide
-     */
-    public byte[] getClassOfDeviceBytes() {
-        byte[] bytes = ByteBuffer.allocate(4)
-                .order(ByteOrder.BIG_ENDIAN)
-                .putInt(mClass)
-                .array();
-
-        // Discard the top byte
-        return Arrays.copyOfRange(bytes, 1, bytes.length);
-    }
-
-    /** @hide */
-    @UnsupportedAppUsage
-    public static final int PROFILE_HEADSET = 0;
-    /** @hide */
-    @UnsupportedAppUsage
-    public static final int PROFILE_A2DP = 1;
-    /** @hide */
-    public static final int PROFILE_OPP = 2;
-    /** @hide */
-    public static final int PROFILE_HID = 3;
-    /** @hide */
-    public static final int PROFILE_PANU = 4;
-    /** @hide */
-    public static final int PROFILE_NAP = 5;
-    /** @hide */
-    public static final int PROFILE_A2DP_SINK = 6;
-
-    /**
-     * Check class bits for possible bluetooth profile support.
-     * This is a simple heuristic that tries to guess if a device with the
-     * given class bits might support specified profile. It is not accurate for all
-     * devices. It tries to err on the side of false positives.
-     *
-     * @param profile The profile to be checked
-     * @return True if this device might support specified profile.
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public boolean doesClassMatch(int profile) {
-        if (profile == PROFILE_A2DP) {
-            if (hasService(Service.RENDER)) {
-                return true;
-            }
-            // By the A2DP spec, sinks must indicate the RENDER service.
-            // However we found some that do not (Chordette). So lets also
-            // match on some other class bits.
-            switch (getDeviceClass()) {
-                case Device.AUDIO_VIDEO_HIFI_AUDIO:
-                case Device.AUDIO_VIDEO_HEADPHONES:
-                case Device.AUDIO_VIDEO_LOUDSPEAKER:
-                case Device.AUDIO_VIDEO_CAR_AUDIO:
-                    return true;
-                default:
-                    return false;
-            }
-        } else if (profile == PROFILE_A2DP_SINK) {
-            if (hasService(Service.CAPTURE)) {
-                return true;
-            }
-            // By the A2DP spec, srcs must indicate the CAPTURE service.
-            // However if some device that do not, we try to
-            // match on some other class bits.
-            switch (getDeviceClass()) {
-                case Device.AUDIO_VIDEO_HIFI_AUDIO:
-                case Device.AUDIO_VIDEO_SET_TOP_BOX:
-                case Device.AUDIO_VIDEO_VCR:
-                    return true;
-                default:
-                    return false;
-            }
-        } else if (profile == PROFILE_HEADSET) {
-            // The render service class is required by the spec for HFP, so is a
-            // pretty good signal
-            if (hasService(Service.RENDER)) {
-                return true;
-            }
-            // Just in case they forgot the render service class
-            switch (getDeviceClass()) {
-                case Device.AUDIO_VIDEO_HANDSFREE:
-                case Device.AUDIO_VIDEO_WEARABLE_HEADSET:
-                case Device.AUDIO_VIDEO_CAR_AUDIO:
-                    return true;
-                default:
-                    return false;
-            }
-        } else if (profile == PROFILE_OPP) {
-            if (hasService(Service.OBJECT_TRANSFER)) {
-                return true;
-            }
-
-            switch (getDeviceClass()) {
-                case Device.COMPUTER_UNCATEGORIZED:
-                case Device.COMPUTER_DESKTOP:
-                case Device.COMPUTER_SERVER:
-                case Device.COMPUTER_LAPTOP:
-                case Device.COMPUTER_HANDHELD_PC_PDA:
-                case Device.COMPUTER_PALM_SIZE_PC_PDA:
-                case Device.COMPUTER_WEARABLE:
-                case Device.PHONE_UNCATEGORIZED:
-                case Device.PHONE_CELLULAR:
-                case Device.PHONE_CORDLESS:
-                case Device.PHONE_SMART:
-                case Device.PHONE_MODEM_OR_GATEWAY:
-                case Device.PHONE_ISDN:
-                    return true;
-                default:
-                    return false;
-            }
-        } else if (profile == PROFILE_HID) {
-            return getMajorDeviceClass() == Device.Major.PERIPHERAL;
-        } else if (profile == PROFILE_PANU || profile == PROFILE_NAP) {
-            // No good way to distinguish between the two, based on class bits.
-            if (hasService(Service.NETWORKING)) {
-                return true;
-            }
-            return getMajorDeviceClass() == Device.Major.NETWORKING;
-        } else {
-            return false;
-        }
-    }
-}
diff --git a/core/java/android/bluetooth/BluetoothCodecConfig.java b/core/java/android/bluetooth/BluetoothCodecConfig.java
deleted file mode 100644
index 9a4151a..0000000
--- a/core/java/android/bluetooth/BluetoothCodecConfig.java
+++ /dev/null
@@ -1,807 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Objects;
-
-/**
- * Represents the codec configuration for a Bluetooth A2DP source device.
- * <p>Contains the source codec type, the codec priority, the codec sample
- * rate, the codec bits per sample, and the codec channel mode.
- * <p>The source codec type values are the same as those supported by the
- * device hardware.
- *
- * {@see BluetoothA2dp}
- */
-public final class BluetoothCodecConfig implements Parcelable {
-    /** @hide */
-    @IntDef(prefix = "SOURCE_CODEC_TYPE_", value = {
-            SOURCE_CODEC_TYPE_SBC,
-            SOURCE_CODEC_TYPE_AAC,
-            SOURCE_CODEC_TYPE_APTX,
-            SOURCE_CODEC_TYPE_APTX_HD,
-            SOURCE_CODEC_TYPE_LDAC,
-            SOURCE_CODEC_TYPE_INVALID
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface SourceCodecType {}
-
-    /**
-     * Source codec type SBC. This is the mandatory source codec
-     * type.
-     */
-    public static final int SOURCE_CODEC_TYPE_SBC = 0;
-
-    /**
-     * Source codec type AAC.
-     */
-    public static final int SOURCE_CODEC_TYPE_AAC = 1;
-
-    /**
-     * Source codec type APTX.
-     */
-    public static final int SOURCE_CODEC_TYPE_APTX = 2;
-
-    /**
-     * Source codec type APTX HD.
-     */
-    public static final int SOURCE_CODEC_TYPE_APTX_HD = 3;
-
-    /**
-     * Source codec type LDAC.
-     */
-    public static final int SOURCE_CODEC_TYPE_LDAC = 4;
-
-    /**
-     * Source codec type invalid. This is the default value used for codec
-     * type.
-     */
-    public static final int SOURCE_CODEC_TYPE_INVALID = 1000 * 1000;
-
-    /**
-     * Represents the count of valid source codec types. Can be accessed via
-     * {@link #getMaxCodecType}.
-     */
-    private static final int SOURCE_CODEC_TYPE_MAX = 5;
-
-    /** @hide */
-    @IntDef(prefix = "CODEC_PRIORITY_", value = {
-            CODEC_PRIORITY_DISABLED,
-            CODEC_PRIORITY_DEFAULT,
-            CODEC_PRIORITY_HIGHEST
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface CodecPriority {}
-
-    /**
-     * Codec priority disabled.
-     * Used to indicate that this codec is disabled and should not be used.
-     */
-    public static final int CODEC_PRIORITY_DISABLED = -1;
-
-    /**
-     * Codec priority default.
-     * Default value used for codec priority.
-     */
-    public static final int CODEC_PRIORITY_DEFAULT = 0;
-
-    /**
-     * Codec priority highest.
-     * Used to indicate the highest priority a codec can have.
-     */
-    public static final int CODEC_PRIORITY_HIGHEST = 1000 * 1000;
-
-    /** @hide */
-    @IntDef(prefix = "SAMPLE_RATE_", value = {
-            SAMPLE_RATE_NONE,
-            SAMPLE_RATE_44100,
-            SAMPLE_RATE_48000,
-            SAMPLE_RATE_88200,
-            SAMPLE_RATE_96000,
-            SAMPLE_RATE_176400,
-            SAMPLE_RATE_192000
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface SampleRate {}
-
-    /**
-     * Codec sample rate 0 Hz. Default value used for
-     * codec sample rate.
-     */
-    public static final int SAMPLE_RATE_NONE = 0;
-
-    /**
-     * Codec sample rate 44100 Hz.
-     */
-    public static final int SAMPLE_RATE_44100 = 0x1 << 0;
-
-    /**
-     * Codec sample rate 48000 Hz.
-     */
-    public static final int SAMPLE_RATE_48000 = 0x1 << 1;
-
-    /**
-     * Codec sample rate 88200 Hz.
-     */
-    public static final int SAMPLE_RATE_88200 = 0x1 << 2;
-
-    /**
-     * Codec sample rate 96000 Hz.
-     */
-    public static final int SAMPLE_RATE_96000 = 0x1 << 3;
-
-    /**
-     * Codec sample rate 176400 Hz.
-     */
-    public static final int SAMPLE_RATE_176400 = 0x1 << 4;
-
-    /**
-     * Codec sample rate 192000 Hz.
-     */
-    public static final int SAMPLE_RATE_192000 = 0x1 << 5;
-
-    /** @hide */
-    @IntDef(prefix = "BITS_PER_SAMPLE_", value = {
-            BITS_PER_SAMPLE_NONE,
-            BITS_PER_SAMPLE_16,
-            BITS_PER_SAMPLE_24,
-            BITS_PER_SAMPLE_32
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface BitsPerSample {}
-
-    /**
-     * Codec bits per sample 0. Default value of the codec
-     * bits per sample.
-     */
-    public static final int BITS_PER_SAMPLE_NONE = 0;
-
-    /**
-     * Codec bits per sample 16.
-     */
-    public static final int BITS_PER_SAMPLE_16 = 0x1 << 0;
-
-    /**
-     * Codec bits per sample 24.
-     */
-    public static final int BITS_PER_SAMPLE_24 = 0x1 << 1;
-
-    /**
-     * Codec bits per sample 32.
-     */
-    public static final int BITS_PER_SAMPLE_32 = 0x1 << 2;
-
-    /** @hide */
-    @IntDef(prefix = "CHANNEL_MODE_", value = {
-            CHANNEL_MODE_NONE,
-            CHANNEL_MODE_MONO,
-            CHANNEL_MODE_STEREO
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface ChannelMode {}
-
-    /**
-     * Codec channel mode NONE. Default value of the
-     * codec channel mode.
-     */
-    public static final int CHANNEL_MODE_NONE = 0;
-
-    /**
-     * Codec channel mode MONO.
-     */
-    public static final int CHANNEL_MODE_MONO = 0x1 << 0;
-
-    /**
-     * Codec channel mode STEREO.
-     */
-    public static final int CHANNEL_MODE_STEREO = 0x1 << 1;
-
-    private final @SourceCodecType int mCodecType;
-    private @CodecPriority int mCodecPriority;
-    private final @SampleRate int mSampleRate;
-    private final @BitsPerSample int mBitsPerSample;
-    private final @ChannelMode int mChannelMode;
-    private final long mCodecSpecific1;
-    private final long mCodecSpecific2;
-    private final long mCodecSpecific3;
-    private final long mCodecSpecific4;
-
-    /**
-     * Creates a new BluetoothCodecConfig.
-     *
-     * @param codecType the source codec type
-     * @param codecPriority the priority of this codec
-     * @param sampleRate the codec sample rate
-     * @param bitsPerSample the bits per sample of this codec
-     * @param channelMode the channel mode of this codec
-     * @param codecSpecific1 the specific value 1
-     * @param codecSpecific2 the specific value 2
-     * @param codecSpecific3 the specific value 3
-     * @param codecSpecific4 the specific value 4
-     * values to 0.
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public BluetoothCodecConfig(@SourceCodecType int codecType, @CodecPriority int codecPriority,
-            @SampleRate int sampleRate, @BitsPerSample int bitsPerSample,
-            @ChannelMode int channelMode, long codecSpecific1,
-            long codecSpecific2, long codecSpecific3,
-            long codecSpecific4) {
-        mCodecType = codecType;
-        mCodecPriority = codecPriority;
-        mSampleRate = sampleRate;
-        mBitsPerSample = bitsPerSample;
-        mChannelMode = channelMode;
-        mCodecSpecific1 = codecSpecific1;
-        mCodecSpecific2 = codecSpecific2;
-        mCodecSpecific3 = codecSpecific3;
-        mCodecSpecific4 = codecSpecific4;
-    }
-
-    /**
-     * Creates a new BluetoothCodecConfig.
-     * <p> By default, the codec priority will be set
-     * to {@link BluetoothCodecConfig#CODEC_PRIORITY_DEFAULT}, the sample rate to
-     * {@link BluetoothCodecConfig#SAMPLE_RATE_NONE}, the bits per sample to
-     * {@link BluetoothCodecConfig#BITS_PER_SAMPLE_NONE}, the channel mode to
-     * {@link BluetoothCodecConfig#CHANNEL_MODE_NONE}, and all the codec specific
-     * values to 0.
-     *
-     * @param codecType the source codec type
-     */
-    public BluetoothCodecConfig(@SourceCodecType int codecType) {
-        this(codecType, BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT,
-                BluetoothCodecConfig.SAMPLE_RATE_NONE,
-                BluetoothCodecConfig.BITS_PER_SAMPLE_NONE,
-                BluetoothCodecConfig.CHANNEL_MODE_NONE, 0, 0, 0, 0);
-    }
-
-    private BluetoothCodecConfig(Parcel in) {
-        mCodecType = in.readInt();
-        mCodecPriority = in.readInt();
-        mSampleRate = in.readInt();
-        mBitsPerSample = in.readInt();
-        mChannelMode = in.readInt();
-        mCodecSpecific1 = in.readLong();
-        mCodecSpecific2 = in.readLong();
-        mCodecSpecific3 = in.readLong();
-        mCodecSpecific4 = in.readLong();
-    }
-
-    @Override
-    public boolean equals(@Nullable Object o) {
-        if (o instanceof BluetoothCodecConfig) {
-            BluetoothCodecConfig other = (BluetoothCodecConfig) o;
-            return (other.mCodecType == mCodecType
-                    && other.mCodecPriority == mCodecPriority
-                    && other.mSampleRate == mSampleRate
-                    && other.mBitsPerSample == mBitsPerSample
-                    && other.mChannelMode == mChannelMode
-                    && other.mCodecSpecific1 == mCodecSpecific1
-                    && other.mCodecSpecific2 == mCodecSpecific2
-                    && other.mCodecSpecific3 == mCodecSpecific3
-                    && other.mCodecSpecific4 == mCodecSpecific4);
-        }
-        return false;
-    }
-
-    /**
-     * Returns a hash representation of this BluetoothCodecConfig
-     * based on all the config values.
-     */
-    @Override
-    public int hashCode() {
-        return Objects.hash(mCodecType, mCodecPriority, mSampleRate,
-                mBitsPerSample, mChannelMode, mCodecSpecific1,
-                mCodecSpecific2, mCodecSpecific3, mCodecSpecific4);
-    }
-
-    /**
-     * Adds capability string to an existing string.
-     *
-     * @param prevStr the previous string with the capabilities. Can be a {@code null} pointer
-     * @param capStr the capability string to append to prevStr argument
-     * @return the result string in the form "prevStr|capStr"
-     */
-    private static String appendCapabilityToString(@Nullable String prevStr,
-            @NonNull String capStr) {
-        if (prevStr == null) {
-            return capStr;
-        }
-        return prevStr + "|" + capStr;
-    }
-
-    /**
-     * Returns a {@link String} that describes each BluetoothCodecConfig parameter
-     * current value.
-     */
-    @Override
-    public String toString() {
-        String sampleRateStr = null;
-        if (mSampleRate == SAMPLE_RATE_NONE) {
-            sampleRateStr = appendCapabilityToString(sampleRateStr, "NONE");
-        }
-        if ((mSampleRate & SAMPLE_RATE_44100) != 0) {
-            sampleRateStr = appendCapabilityToString(sampleRateStr, "44100");
-        }
-        if ((mSampleRate & SAMPLE_RATE_48000) != 0) {
-            sampleRateStr = appendCapabilityToString(sampleRateStr, "48000");
-        }
-        if ((mSampleRate & SAMPLE_RATE_88200) != 0) {
-            sampleRateStr = appendCapabilityToString(sampleRateStr, "88200");
-        }
-        if ((mSampleRate & SAMPLE_RATE_96000) != 0) {
-            sampleRateStr = appendCapabilityToString(sampleRateStr, "96000");
-        }
-        if ((mSampleRate & SAMPLE_RATE_176400) != 0) {
-            sampleRateStr = appendCapabilityToString(sampleRateStr, "176400");
-        }
-        if ((mSampleRate & SAMPLE_RATE_192000) != 0) {
-            sampleRateStr = appendCapabilityToString(sampleRateStr, "192000");
-        }
-
-        String bitsPerSampleStr = null;
-        if (mBitsPerSample == BITS_PER_SAMPLE_NONE) {
-            bitsPerSampleStr = appendCapabilityToString(bitsPerSampleStr, "NONE");
-        }
-        if ((mBitsPerSample & BITS_PER_SAMPLE_16) != 0) {
-            bitsPerSampleStr = appendCapabilityToString(bitsPerSampleStr, "16");
-        }
-        if ((mBitsPerSample & BITS_PER_SAMPLE_24) != 0) {
-            bitsPerSampleStr = appendCapabilityToString(bitsPerSampleStr, "24");
-        }
-        if ((mBitsPerSample & BITS_PER_SAMPLE_32) != 0) {
-            bitsPerSampleStr = appendCapabilityToString(bitsPerSampleStr, "32");
-        }
-
-        String channelModeStr = null;
-        if (mChannelMode == CHANNEL_MODE_NONE) {
-            channelModeStr = appendCapabilityToString(channelModeStr, "NONE");
-        }
-        if ((mChannelMode & CHANNEL_MODE_MONO) != 0) {
-            channelModeStr = appendCapabilityToString(channelModeStr, "MONO");
-        }
-        if ((mChannelMode & CHANNEL_MODE_STEREO) != 0) {
-            channelModeStr = appendCapabilityToString(channelModeStr, "STEREO");
-        }
-
-        return "{codecName:" + getCodecName()
-                + ",mCodecType:" + mCodecType
-                + ",mCodecPriority:" + mCodecPriority
-                + ",mSampleRate:" + String.format("0x%x", mSampleRate)
-                + "(" + sampleRateStr + ")"
-                + ",mBitsPerSample:" + String.format("0x%x", mBitsPerSample)
-                + "(" + bitsPerSampleStr + ")"
-                + ",mChannelMode:" + String.format("0x%x", mChannelMode)
-                + "(" + channelModeStr + ")"
-                + ",mCodecSpecific1:" + mCodecSpecific1
-                + ",mCodecSpecific2:" + mCodecSpecific2
-                + ",mCodecSpecific3:" + mCodecSpecific3
-                + ",mCodecSpecific4:" + mCodecSpecific4 + "}";
-    }
-
-    /**
-     * @return 0
-     * @hide
-     */
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    public static final @android.annotation.NonNull Parcelable.Creator<BluetoothCodecConfig> CREATOR =
-            new Parcelable.Creator<BluetoothCodecConfig>() {
-                public BluetoothCodecConfig createFromParcel(Parcel in) {
-                    return new BluetoothCodecConfig(in);
-                }
-
-                public BluetoothCodecConfig[] newArray(int size) {
-                    return new BluetoothCodecConfig[size];
-                }
-            };
-
-    /**
-     * Flattens the object to a parcel
-     *
-     * @param out The Parcel in which the object should be written
-     * @param flags Additional flags about how the object should be written
-     *
-     * @hide
-     */
-    @Override
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeInt(mCodecType);
-        out.writeInt(mCodecPriority);
-        out.writeInt(mSampleRate);
-        out.writeInt(mBitsPerSample);
-        out.writeInt(mChannelMode);
-        out.writeLong(mCodecSpecific1);
-        out.writeLong(mCodecSpecific2);
-        out.writeLong(mCodecSpecific3);
-        out.writeLong(mCodecSpecific4);
-    }
-
-    /**
-     * Returns the codec name converted to {@link String}.
-     * @hide
-     */
-    public @NonNull String getCodecName() {
-        switch (mCodecType) {
-            case SOURCE_CODEC_TYPE_SBC:
-                return "SBC";
-            case SOURCE_CODEC_TYPE_AAC:
-                return "AAC";
-            case SOURCE_CODEC_TYPE_APTX:
-                return "aptX";
-            case SOURCE_CODEC_TYPE_APTX_HD:
-                return "aptX HD";
-            case SOURCE_CODEC_TYPE_LDAC:
-                return "LDAC";
-            case SOURCE_CODEC_TYPE_INVALID:
-                return "INVALID CODEC";
-            default:
-                break;
-        }
-        return "UNKNOWN CODEC(" + mCodecType + ")";
-    }
-
-    /**
-     * Returns the source codec type of this config.
-     */
-    public @SourceCodecType int getCodecType() {
-        return mCodecType;
-    }
-
-    /**
-     * Returns the valid codec types count.
-     */
-    public static int getMaxCodecType() {
-        return SOURCE_CODEC_TYPE_MAX;
-    }
-
-    /**
-     * Checks whether the codec is mandatory.
-     * <p> The actual mandatory codec type for Android Bluetooth audio is SBC.
-     * See {@link #SOURCE_CODEC_TYPE_SBC}.
-     *
-     * @return {@code true} if the codec is mandatory, {@code false} otherwise
-     * @hide
-     */
-    public boolean isMandatoryCodec() {
-        return mCodecType == SOURCE_CODEC_TYPE_SBC;
-    }
-
-    /**
-     * Returns the codec selection priority.
-     * <p>The codec selection priority is relative to other codecs: larger value
-     * means higher priority.
-     */
-    public @CodecPriority int getCodecPriority() {
-        return mCodecPriority;
-    }
-
-    /**
-     * Sets the codec selection priority.
-     * <p>The codec selection priority is relative to other codecs: larger value
-     * means higher priority.
-     *
-     * @param codecPriority the priority this codec should have
-     * @hide
-     */
-    public void setCodecPriority(@CodecPriority int codecPriority) {
-        mCodecPriority = codecPriority;
-    }
-
-    /**
-     * Returns the codec sample rate. The value can be a bitmask with all
-     * supported sample rates.
-     */
-    public @SampleRate int getSampleRate() {
-        return mSampleRate;
-    }
-
-    /**
-     * Returns the codec bits per sample. The value can be a bitmask with all
-     * bits per sample supported.
-     */
-    public @BitsPerSample int getBitsPerSample() {
-        return mBitsPerSample;
-    }
-
-    /**
-     * Returns the codec channel mode. The value can be a bitmask with all
-     * supported channel modes.
-     */
-    public @ChannelMode int getChannelMode() {
-        return mChannelMode;
-    }
-
-    /**
-     * Returns the codec specific value1.
-     */
-    public long getCodecSpecific1() {
-        return mCodecSpecific1;
-    }
-
-    /**
-     * Returns the codec specific value2.
-     */
-    public long getCodecSpecific2() {
-        return mCodecSpecific2;
-    }
-
-    /**
-     * Returns the codec specific value3.
-     */
-    public long getCodecSpecific3() {
-        return mCodecSpecific3;
-    }
-
-    /**
-     * Returns the codec specific value4.
-     */
-    public long getCodecSpecific4() {
-        return mCodecSpecific4;
-    }
-
-    /**
-     * Checks whether a value set presented by a bitmask has zero or single bit
-     *
-     * @param valueSet the value set presented by a bitmask
-     * @return {@code true} if the valueSet contains zero or single bit, {@code false} otherwise
-     * @hide
-     */
-    private static boolean hasSingleBit(int valueSet) {
-        return (valueSet == 0 || (valueSet & (valueSet - 1)) == 0);
-    }
-
-    /**
-     * Returns whether the object contains none or single sample rate.
-     * @hide
-     */
-    public boolean hasSingleSampleRate() {
-        return hasSingleBit(mSampleRate);
-    }
-
-    /**
-     * Returns whether the object contains none or single bits per sample.
-     * @hide
-     */
-    public boolean hasSingleBitsPerSample() {
-        return hasSingleBit(mBitsPerSample);
-    }
-
-    /**
-     * Returns whether the object contains none or single channel mode.
-     * @hide
-     */
-    public boolean hasSingleChannelMode() {
-        return hasSingleBit(mChannelMode);
-    }
-
-    /**
-     * Checks whether the audio feeding parameters are the same.
-     *
-     * @param other the codec config to compare against
-     * @return {@code true} if the audio feeding parameters are same, {@code false} otherwise
-     * @hide
-     */
-    public boolean sameAudioFeedingParameters(BluetoothCodecConfig other) {
-        return (other != null && other.mSampleRate == mSampleRate
-                && other.mBitsPerSample == mBitsPerSample
-                && other.mChannelMode == mChannelMode);
-    }
-
-    /**
-     * Checks whether another codec config has the similar feeding parameters.
-     * Any parameters with NONE value will be considered to be a wildcard matching.
-     *
-     * @param other the codec config to compare against
-     * @return {@code true} if the audio feeding parameters are similar, {@code false} otherwise
-     * @hide
-     */
-    public boolean similarCodecFeedingParameters(BluetoothCodecConfig other) {
-        if (other == null || mCodecType != other.mCodecType) {
-            return false;
-        }
-        int sampleRate = other.mSampleRate;
-        if (mSampleRate == SAMPLE_RATE_NONE
-                || sampleRate == SAMPLE_RATE_NONE) {
-            sampleRate = mSampleRate;
-        }
-        int bitsPerSample = other.mBitsPerSample;
-        if (mBitsPerSample == BITS_PER_SAMPLE_NONE
-                || bitsPerSample == BITS_PER_SAMPLE_NONE) {
-            bitsPerSample = mBitsPerSample;
-        }
-        int channelMode = other.mChannelMode;
-        if (mChannelMode == CHANNEL_MODE_NONE
-                || channelMode == CHANNEL_MODE_NONE) {
-            channelMode = mChannelMode;
-        }
-        return sameAudioFeedingParameters(new BluetoothCodecConfig(
-                mCodecType, /* priority */ 0, sampleRate, bitsPerSample, channelMode,
-                /* specific1 */ 0, /* specific2 */ 0, /* specific3 */ 0,
-                /* specific4 */ 0));
-    }
-
-    /**
-     * Checks whether the codec specific parameters are the same.
-     * <p> Currently, only AAC VBR and LDAC Playback Quality on CodecSpecific1
-     * are compared.
-     *
-     * @param other the codec config to compare against
-     * @return {@code true} if the codec specific parameters are the same, {@code false} otherwise
-     * @hide
-     */
-    public boolean sameCodecSpecificParameters(BluetoothCodecConfig other) {
-        if (other == null && mCodecType != other.mCodecType) {
-            return false;
-        }
-        switch (mCodecType) {
-            case SOURCE_CODEC_TYPE_AAC:
-            case SOURCE_CODEC_TYPE_LDAC:
-                if (mCodecSpecific1 != other.mCodecSpecific1) {
-                    return false;
-                }
-            default:
-                return true;
-        }
-    }
-
-    /**
-     * Builder for {@link BluetoothCodecConfig}.
-     * <p> By default, the codec type will be set to
-     * {@link BluetoothCodecConfig#SOURCE_CODEC_TYPE_INVALID}, the codec priority
-     * to {@link BluetoothCodecConfig#CODEC_PRIORITY_DEFAULT}, the sample rate to
-     * {@link BluetoothCodecConfig#SAMPLE_RATE_NONE}, the bits per sample to
-     * {@link BluetoothCodecConfig#BITS_PER_SAMPLE_NONE}, the channel mode to
-     * {@link BluetoothCodecConfig#CHANNEL_MODE_NONE}, and all the codec specific
-     * values to 0.
-     */
-    public static final class Builder {
-        private int mCodecType = BluetoothCodecConfig.SOURCE_CODEC_TYPE_INVALID;
-        private int mCodecPriority = BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT;
-        private int mSampleRate = BluetoothCodecConfig.SAMPLE_RATE_NONE;
-        private int mBitsPerSample = BluetoothCodecConfig.BITS_PER_SAMPLE_NONE;
-        private int mChannelMode = BluetoothCodecConfig.CHANNEL_MODE_NONE;
-        private long mCodecSpecific1 = 0;
-        private long mCodecSpecific2 = 0;
-        private long mCodecSpecific3 = 0;
-        private long mCodecSpecific4 = 0;
-
-        /**
-         * Set codec type for Bluetooth codec config.
-         *
-         * @param codecType of this codec
-         * @return the same Builder instance
-         */
-        public @NonNull Builder setCodecType(@SourceCodecType int codecType) {
-            mCodecType = codecType;
-            return this;
-        }
-
-        /**
-         * Set codec priority for Bluetooth codec config.
-         *
-         * @param codecPriority of this codec
-         * @return the same Builder instance
-         */
-        public @NonNull Builder setCodecPriority(@CodecPriority int codecPriority) {
-            mCodecPriority = codecPriority;
-            return this;
-        }
-
-        /**
-         * Set sample rate for Bluetooth codec config.
-         *
-         * @param sampleRate of this codec
-         * @return the same Builder instance
-         */
-        public @NonNull Builder setSampleRate(@SampleRate int sampleRate) {
-            mSampleRate = sampleRate;
-            return this;
-        }
-
-        /**
-         * Set the bits per sample for Bluetooth codec config.
-         *
-         * @param bitsPerSample of this codec
-         * @return the same Builder instance
-         */
-        public @NonNull Builder setBitsPerSample(@BitsPerSample int bitsPerSample) {
-            mBitsPerSample = bitsPerSample;
-            return this;
-        }
-
-        /**
-         * Set the channel mode for Bluetooth codec config.
-         *
-         * @param channelMode of this codec
-         * @return the same Builder instance
-         */
-        public @NonNull Builder setChannelMode(@ChannelMode int channelMode) {
-            mChannelMode = channelMode;
-            return this;
-        }
-
-        /**
-         * Set the first codec specific values for Bluetooth codec config.
-         *
-         * @param codecSpecific1 codec specific value or 0 if default
-         * @return the same Builder instance
-         */
-        public @NonNull Builder setCodecSpecific1(long codecSpecific1) {
-            mCodecSpecific1 = codecSpecific1;
-            return this;
-        }
-
-        /**
-         * Set the second codec specific values for Bluetooth codec config.
-         *
-         * @param codecSpecific2 codec specific value or 0 if default
-         * @return the same Builder instance
-         */
-        public @NonNull Builder setCodecSpecific2(long codecSpecific2) {
-            mCodecSpecific2 = codecSpecific2;
-            return this;
-        }
-
-        /**
-         * Set the third codec specific values for Bluetooth codec config.
-         *
-         * @param codecSpecific3 codec specific value or 0 if default
-         * @return the same Builder instance
-         */
-        public @NonNull Builder setCodecSpecific3(long codecSpecific3) {
-            mCodecSpecific3 = codecSpecific3;
-            return this;
-        }
-
-        /**
-         * Set the fourth codec specific values for Bluetooth codec config.
-         *
-         * @param codecSpecific4 codec specific value or 0 if default
-         * @return the same Builder instance
-         */
-        public @NonNull Builder setCodecSpecific4(long codecSpecific4) {
-            mCodecSpecific4 = codecSpecific4;
-            return this;
-        }
-
-        /**
-         * Build {@link BluetoothCodecConfig}.
-         * @return new BluetoothCodecConfig built
-         */
-        public @NonNull BluetoothCodecConfig build() {
-            return new BluetoothCodecConfig(mCodecType, mCodecPriority,
-                    mSampleRate, mBitsPerSample,
-                    mChannelMode, mCodecSpecific1,
-                    mCodecSpecific2, mCodecSpecific3,
-                    mCodecSpecific4);
-        }
-    }
-}
diff --git a/core/java/android/bluetooth/BluetoothCodecStatus.java b/core/java/android/bluetooth/BluetoothCodecStatus.java
deleted file mode 100644
index 02606fe..0000000
--- a/core/java/android/bluetooth/BluetoothCodecStatus.java
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Objects;
-
-/**
- * Represents the codec status (configuration and capability) for a Bluetooth
- * A2DP source device.
- *
- * {@see BluetoothA2dp}
- */
-public final class BluetoothCodecStatus implements Parcelable {
-    /**
-     * Extra for the codec configuration intents of the individual profiles.
-     *
-     * This extra represents the current codec status of the A2DP
-     * profile.
-     */
-    public static final String EXTRA_CODEC_STATUS =
-            "android.bluetooth.extra.CODEC_STATUS";
-
-    private final @Nullable BluetoothCodecConfig mCodecConfig;
-    private final @Nullable List<BluetoothCodecConfig> mCodecsLocalCapabilities;
-    private final @Nullable List<BluetoothCodecConfig> mCodecsSelectableCapabilities;
-
-    public BluetoothCodecStatus(@Nullable BluetoothCodecConfig codecConfig,
-            @Nullable List<BluetoothCodecConfig> codecsLocalCapabilities,
-            @Nullable List<BluetoothCodecConfig> codecsSelectableCapabilities) {
-        mCodecConfig = codecConfig;
-        mCodecsLocalCapabilities = codecsLocalCapabilities;
-        mCodecsSelectableCapabilities = codecsSelectableCapabilities;
-    }
-
-    private BluetoothCodecStatus(Parcel in) {
-        mCodecConfig = in.readTypedObject(BluetoothCodecConfig.CREATOR);
-        mCodecsLocalCapabilities = in.createTypedArrayList(BluetoothCodecConfig.CREATOR);
-        mCodecsSelectableCapabilities = in.createTypedArrayList(BluetoothCodecConfig.CREATOR);
-    }
-
-    @Override
-    public boolean equals(@Nullable Object o) {
-        if (o instanceof BluetoothCodecStatus) {
-            BluetoothCodecStatus other = (BluetoothCodecStatus) o;
-            return (Objects.equals(other.mCodecConfig, mCodecConfig)
-                    && sameCapabilities(other.mCodecsLocalCapabilities, mCodecsLocalCapabilities)
-                    && sameCapabilities(other.mCodecsSelectableCapabilities,
-                    mCodecsSelectableCapabilities));
-        }
-        return false;
-    }
-
-    /**
-     * Checks whether two lists of capabilities contain same capabilities.
-     * The order of the capabilities in each list is ignored.
-     *
-     * @param c1 the first list of capabilities to compare
-     * @param c2 the second list of capabilities to compare
-     * @return {@code true} if both lists contain same capabilities
-     */
-    private static boolean sameCapabilities(@Nullable List<BluetoothCodecConfig> c1,
-                                           @Nullable List<BluetoothCodecConfig> c2) {
-        if (c1 == null) {
-            return (c2 == null);
-        }
-        if (c2 == null) {
-            return false;
-        }
-        if (c1.size() != c2.size()) {
-            return false;
-        }
-        return c1.containsAll(c2);
-    }
-
-    /**
-     * Checks whether the codec config matches the selectable capabilities.
-     * Any parameters of the codec config with NONE value will be considered a wildcard matching.
-     *
-     * @param codecConfig the codec config to compare against
-     * @return {@code true} if the codec config matches, {@code false} otherwise
-     */
-    public boolean isCodecConfigSelectable(@Nullable BluetoothCodecConfig codecConfig) {
-        if (codecConfig == null || !codecConfig.hasSingleSampleRate()
-                || !codecConfig.hasSingleBitsPerSample() || !codecConfig.hasSingleChannelMode()) {
-            return false;
-        }
-        for (BluetoothCodecConfig selectableConfig : mCodecsSelectableCapabilities) {
-            if (codecConfig.getCodecType() != selectableConfig.getCodecType()) {
-                continue;
-            }
-            int sampleRate = codecConfig.getSampleRate();
-            if ((sampleRate & selectableConfig.getSampleRate()) == 0
-                    && sampleRate != BluetoothCodecConfig.SAMPLE_RATE_NONE) {
-                continue;
-            }
-            int bitsPerSample = codecConfig.getBitsPerSample();
-            if ((bitsPerSample & selectableConfig.getBitsPerSample()) == 0
-                    && bitsPerSample != BluetoothCodecConfig.BITS_PER_SAMPLE_NONE) {
-                continue;
-            }
-            int channelMode = codecConfig.getChannelMode();
-            if ((channelMode & selectableConfig.getChannelMode()) == 0
-                    && channelMode != BluetoothCodecConfig.CHANNEL_MODE_NONE) {
-                continue;
-            }
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Returns a hash based on the codec config and local capabilities.
-     */
-    @Override
-    public int hashCode() {
-        return Objects.hash(mCodecConfig, mCodecsLocalCapabilities,
-                mCodecsLocalCapabilities);
-    }
-
-    /**
-     * Returns a {@link String} that describes each BluetoothCodecStatus parameter
-     * current value.
-     */
-    @Override
-    public String toString() {
-        return "{mCodecConfig:" + mCodecConfig
-                + ",mCodecsLocalCapabilities:" + mCodecsLocalCapabilities
-                + ",mCodecsSelectableCapabilities:" + mCodecsSelectableCapabilities
-                + "}";
-    }
-
-    /**
-     * @return 0
-     * @hide
-     */
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    public static final @android.annotation.NonNull Parcelable.Creator<BluetoothCodecStatus> CREATOR =
-            new Parcelable.Creator<BluetoothCodecStatus>() {
-                public BluetoothCodecStatus createFromParcel(Parcel in) {
-                    return new BluetoothCodecStatus(in);
-                }
-
-                public BluetoothCodecStatus[] newArray(int size) {
-                    return new BluetoothCodecStatus[size];
-                }
-            };
-
-    /**
-     * Flattens the object to a parcel.
-     *
-     * @param out The Parcel in which the object should be written
-     * @param flags Additional flags about how the object should be written
-     */
-    @Override
-    public void writeToParcel(@NonNull Parcel out, int flags) {
-        out.writeTypedObject(mCodecConfig, 0);
-        out.writeTypedList(mCodecsLocalCapabilities);
-        out.writeTypedList(mCodecsSelectableCapabilities);
-    }
-
-    /**
-     * Returns the current codec configuration.
-     */
-    public @Nullable BluetoothCodecConfig getCodecConfig() {
-        return mCodecConfig;
-    }
-
-    /**
-     * Returns the codecs local capabilities.
-     */
-    public @NonNull List<BluetoothCodecConfig> getCodecsLocalCapabilities() {
-        return (mCodecsLocalCapabilities == null)
-                ? Collections.emptyList() : mCodecsLocalCapabilities;
-    }
-
-    /**
-     * Returns the codecs selectable capabilities.
-     */
-    public @NonNull List<BluetoothCodecConfig> getCodecsSelectableCapabilities() {
-        return (mCodecsSelectableCapabilities == null)
-                ? Collections.emptyList() : mCodecsSelectableCapabilities;
-    }
-}
diff --git a/core/java/android/bluetooth/BluetoothCsipSetCoordinator.java b/core/java/android/bluetooth/BluetoothCsipSetCoordinator.java
deleted file mode 100644
index ba57ec4..0000000
--- a/core/java/android/bluetooth/BluetoothCsipSetCoordinator.java
+++ /dev/null
@@ -1,555 +0,0 @@
-/*
- * Copyright 2021 HIMSA II K/S - www.himsa.com.
- * Represented by EHIMA - www.ehima.com
- *
- * 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.bluetooth;
-
-import static android.bluetooth.BluetoothUtils.getSyncTimeout;
-
-import android.Manifest;
-import android.annotation.CallbackExecutor;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.RequiresPermission;
-import android.annotation.SdkConstant;
-import android.annotation.SdkConstant.SdkConstantType;
-import android.annotation.SystemApi;
-import android.content.AttributionSource;
-import android.content.Context;
-import android.os.IBinder;
-import android.os.ParcelUuid;
-import android.os.RemoteException;
-import android.util.CloseGuard;
-import android.util.Log;
-
-import com.android.modules.utils.SynchronousResultReceiver;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-import java.util.concurrent.Executor;
-import java.util.concurrent.TimeoutException;
-
-/**
- * This class provides the public APIs to control the Bluetooth CSIP set coordinator.
- *
- * <p>BluetoothCsipSetCoordinator is a proxy object for controlling the Bluetooth VC
- * Service via IPC. Use {@link BluetoothAdapter#getProfileProxy} to get
- * the BluetoothCsipSetCoordinator proxy object.
- *
- */
-public final class BluetoothCsipSetCoordinator implements BluetoothProfile, AutoCloseable {
-    private static final String TAG = "BluetoothCsipSetCoordinator";
-    private static final boolean DBG = false;
-    private static final boolean VDBG = false;
-
-    private CloseGuard mCloseGuard;
-
-    /**
-     * @hide
-     */
-    @SystemApi
-    public interface ClientLockCallback {
-        /**
-         * @hide
-         */
-        @SystemApi void onGroupLockSet(int groupId, int opStatus, boolean isLocked);
-    }
-
-    private static class BluetoothCsipSetCoordinatorLockCallbackDelegate
-            extends IBluetoothCsipSetCoordinatorLockCallback.Stub {
-        private final ClientLockCallback mCallback;
-        private final Executor mExecutor;
-
-        BluetoothCsipSetCoordinatorLockCallbackDelegate(
-                Executor executor, ClientLockCallback callback) {
-            mExecutor = executor;
-            mCallback = callback;
-        }
-
-        @Override
-        public void onGroupLockSet(int groupId, int opStatus, boolean isLocked) {
-            mExecutor.execute(() -> mCallback.onGroupLockSet(groupId, opStatus, isLocked));
-        }
-    };
-
-    /**
-     * Intent used to broadcast the change in connection state of the CSIS
-     * Client.
-     *
-     * <p>This intent will have 3 extras:
-     * <ul>
-     * <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
-     * <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li>
-     * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
-     * </ul>
-     *
-     * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
-     * {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTING},
-     * {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTING}.
-     */
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_CSIS_CONNECTION_STATE_CHANGED =
-            "android.bluetooth.action.CSIS_CONNECTION_STATE_CHANGED";
-
-    /**
-     * Intent used to expose broadcast receiving device.
-     *
-     * <p>This intent will have 2 extras:
-     * <ul>
-     * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote Broadcast receiver device. </li>
-     * <li> {@link #EXTRA_CSIS_GROUP_ID} - Group identifier. </li>
-     * <li> {@link #EXTRA_CSIS_GROUP_SIZE} - Group size. </li>
-     * <li> {@link #EXTRA_CSIS_GROUP_TYPE_UUID} - Group type UUID. </li>
-     * </ul>
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_CSIS_DEVICE_AVAILABLE =
-            "android.bluetooth.action.CSIS_DEVICE_AVAILABLE";
-
-    /**
-     * Used as an extra field in {@link #ACTION_CSIS_DEVICE_AVAILABLE} intent.
-     * Contains the group id.
-     *
-     * @hide
-     */
-    public static final String EXTRA_CSIS_GROUP_ID = "android.bluetooth.extra.CSIS_GROUP_ID";
-
-    /**
-     * Group size as int extra field in {@link #ACTION_CSIS_DEVICE_AVAILABLE} intent.
-     *
-     * @hide
-     */
-    public static final String EXTRA_CSIS_GROUP_SIZE = "android.bluetooth.extra.CSIS_GROUP_SIZE";
-
-    /**
-     * Group type uuid extra field in {@link #ACTION_CSIS_DEVICE_AVAILABLE} intent.
-     *
-     * @hide
-     */
-    public static final String EXTRA_CSIS_GROUP_TYPE_UUID =
-            "android.bluetooth.extra.CSIS_GROUP_TYPE_UUID";
-
-    /**
-     * Intent used to broadcast information about identified set member
-     * ready to connect.
-     *
-     * <p>This intent will have one extra:
-     * <ul>
-     * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. It can
-     * be null if no device is active. </li>
-     * <li>  {@link #EXTRA_CSIS_GROUP_ID} - Group identifier. </li>
-     * </ul>
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_CSIS_SET_MEMBER_AVAILABLE =
-            "android.bluetooth.action.CSIS_SET_MEMBER_AVAILABLE";
-
-    /**
-     * This represents an invalid group ID.
-     *
-     * @hide
-     */
-    public static final int GROUP_ID_INVALID = IBluetoothCsipSetCoordinator.CSIS_GROUP_ID_INVALID;
-
-    /**
-     * Indicating that group was locked with success.
-     *
-     * @hide
-     */
-    public static final int GROUP_LOCK_SUCCESS = 0;
-
-    /**
-     * Indicating that group locked failed due to invalid group ID.
-     *
-     * @hide
-     */
-    public static final int GROUP_LOCK_FAILED_INVALID_GROUP = 1;
-
-    /**
-     * Indicating that group locked failed due to empty group.
-     *
-     * @hide
-     */
-    public static final int GROUP_LOCK_FAILED_GROUP_EMPTY = 2;
-
-    /**
-     * Indicating that group locked failed due to group members being disconnected.
-     *
-     * @hide
-     */
-    public static final int GROUP_LOCK_FAILED_GROUP_NOT_CONNECTED = 3;
-
-    /**
-     * Indicating that group locked failed due to group member being already locked.
-     *
-     * @hide
-     */
-    public static final int GROUP_LOCK_FAILED_LOCKED_BY_OTHER = 4;
-
-    /**
-     * Indicating that group locked failed due to other reason.
-     *
-     * @hide
-     */
-    public static final int GROUP_LOCK_FAILED_OTHER_REASON = 5;
-
-    /**
-     * Indicating that group member in locked state was lost.
-     *
-     * @hide
-     */
-    public static final int LOCKED_GROUP_MEMBER_LOST = 6;
-
-    private final BluetoothAdapter mAdapter;
-    private final AttributionSource mAttributionSource;
-    private final BluetoothProfileConnector<IBluetoothCsipSetCoordinator> mProfileConnector =
-            new BluetoothProfileConnector(this, BluetoothProfile.CSIP_SET_COORDINATOR, TAG,
-                    IBluetoothCsipSetCoordinator.class.getName()) {
-                @Override
-                public IBluetoothCsipSetCoordinator getServiceInterface(IBinder service) {
-                    return IBluetoothCsipSetCoordinator.Stub.asInterface(service);
-                }
-            };
-
-    /**
-     * Create a BluetoothCsipSetCoordinator proxy object for interacting with the local
-     * Bluetooth CSIS service.
-     */
-    /*package*/ BluetoothCsipSetCoordinator(Context context, ServiceListener listener, BluetoothAdapter adapter) {
-        mAdapter = adapter;
-        mAttributionSource = adapter.getAttributionSource();
-        mProfileConnector.connect(context, listener);
-        mCloseGuard = new CloseGuard();
-        mCloseGuard.open("close");
-    }
-
-    /**
-     * @hide
-     */
-    protected void finalize() {
-        if (mCloseGuard != null) {
-            mCloseGuard.warnIfOpen();
-        }
-        close();
-    }
-
-    /**
-     * @hide
-     */
-    public void close() {
-        mProfileConnector.disconnect();
-    }
-
-    private IBluetoothCsipSetCoordinator getService() {
-        return mProfileConnector.getService();
-    }
-
-    /**
-     * Lock the set.
-     * @param groupId group ID to lock,
-     * @param executor callback executor,
-     * @param cb callback to report lock and unlock events - stays valid until the app unlocks
-     *           using the returned lock identifier or the lock timeouts on the remote side,
-     *           as per CSIS specification,
-     * @return unique lock identifier used for unlocking or null if lock has failed.
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
-    public
-    @Nullable UUID groupLock(int groupId, @Nullable @CallbackExecutor Executor executor,
-            @Nullable ClientLockCallback cb) {
-        if (VDBG) log("groupLockSet()");
-        final IBluetoothCsipSetCoordinator service = getService();
-        final UUID defaultValue = null;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            IBluetoothCsipSetCoordinatorLockCallback delegate = null;
-            if ((executor != null) && (cb != null)) {
-                delegate = new BluetoothCsipSetCoordinatorLockCallbackDelegate(executor, cb);
-            }
-            try {
-                final SynchronousResultReceiver<ParcelUuid> recv = new SynchronousResultReceiver();
-                service.groupLock(groupId, delegate, mAttributionSource, recv);
-                final ParcelUuid ret = recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(null);
-                return ret == null ? defaultValue : ret.getUuid();
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Unlock the set.
-     * @param lockUuid unique lock identifier
-     * @return true if unlocked, false on error
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
-    public boolean groupUnlock(@NonNull UUID lockUuid) {
-        if (VDBG) log("groupLockSet()");
-        if (lockUuid == null) {
-            return false;
-        }
-        final IBluetoothCsipSetCoordinator service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver recv = new SynchronousResultReceiver();
-                service.groupUnlock(new ParcelUuid(lockUuid), mAttributionSource, recv);
-                recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(null);
-                return true;
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Get device's groups.
-     * @param device the active device
-     * @return Map of groups ids and related UUIDs
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
-    public @NonNull Map getGroupUuidMapByDevice(@Nullable BluetoothDevice device) {
-        if (VDBG) log("getGroupUuidMapByDevice()");
-        final IBluetoothCsipSetCoordinator service = getService();
-        final Map defaultValue = new HashMap<>();
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<Map> recv = new SynchronousResultReceiver();
-                service.getGroupUuidMapByDevice(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Get group id for the given UUID
-     * @param uuid
-     * @return list of group IDs
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
-    public @NonNull List<Integer> getAllGroupIds(@Nullable ParcelUuid uuid) {
-        if (VDBG) log("getAllGroupIds()");
-        final IBluetoothCsipSetCoordinator service = getService();
-        final List<Integer> defaultValue = new ArrayList<>();
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<List<Integer>> recv =
-                        new SynchronousResultReceiver();
-                service.getAllGroupIds(uuid, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public @NonNull List<BluetoothDevice> getConnectedDevices() {
-        if (VDBG) log("getConnectedDevices()");
-        final IBluetoothCsipSetCoordinator service = getService();
-        final List<BluetoothDevice> defaultValue = new ArrayList<>();
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<List<BluetoothDevice>> recv =
-                        new SynchronousResultReceiver();
-                service.getConnectedDevices(mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public
-    @NonNull List<BluetoothDevice> getDevicesMatchingConnectionStates(@NonNull int[] states) {
-        if (VDBG) log("getDevicesMatchingStates(states=" + Arrays.toString(states) + ")");
-        final IBluetoothCsipSetCoordinator service = getService();
-        final List<BluetoothDevice> defaultValue = new ArrayList<>();
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<List<BluetoothDevice>> recv =
-                        new SynchronousResultReceiver();
-                service.getDevicesMatchingConnectionStates(states, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public
-    @BluetoothProfile.BtProfileState int getConnectionState(@Nullable BluetoothDevice device) {
-        if (VDBG) log("getState(" + device + ")");
-        final IBluetoothCsipSetCoordinator service = getService();
-        final int defaultValue = BluetoothProfile.STATE_DISCONNECTED;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
-                service.getConnectionState(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Set connection policy of the profile
-     *
-     * <p> The device should already be paired.
-     * Connection policy can be one of {@link #CONNECTION_POLICY_ALLOWED},
-     * {@link #CONNECTION_POLICY_FORBIDDEN}, {@link #CONNECTION_POLICY_UNKNOWN}
-     *
-     * @param device Paired bluetooth device
-     * @param connectionPolicy is the connection policy to set to for this profile
-     * @return true if connectionPolicy is set, false on error
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
-    public boolean setConnectionPolicy(
-            @Nullable BluetoothDevice device, @ConnectionPolicy int connectionPolicy) {
-        if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
-        final IBluetoothCsipSetCoordinator service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)
-                && (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_FORBIDDEN
-                    || connectionPolicy == BluetoothProfile.CONNECTION_POLICY_ALLOWED)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.setConnectionPolicy(device, connectionPolicy, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Get the connection policy of the profile.
-     *
-     * <p> The connection policy can be any of:
-     * {@link #CONNECTION_POLICY_ALLOWED}, {@link #CONNECTION_POLICY_FORBIDDEN},
-     * {@link #CONNECTION_POLICY_UNKNOWN}
-     *
-     * @param device Bluetooth device
-     * @return connection policy of the device
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
-    public @ConnectionPolicy int getConnectionPolicy(@Nullable BluetoothDevice device) {
-        if (VDBG) log("getConnectionPolicy(" + device + ")");
-        final IBluetoothCsipSetCoordinator service = getService();
-        final int defaultValue = BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
-                service.getConnectionPolicy(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    private boolean isEnabled() {
-        return mAdapter.getState() == BluetoothAdapter.STATE_ON;
-    }
-
-    private static boolean isValidDevice(@Nullable BluetoothDevice device) {
-        return device != null && BluetoothAdapter.checkBluetoothAddress(device.getAddress());
-    }
-
-    private static void log(String msg) {
-        Log.d(TAG, msg);
-    }
-}
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
deleted file mode 100644
index 93f0268..0000000
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ /dev/null
@@ -1,2830 +0,0 @@
-/*
- * Copyright (C) 2009 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.bluetooth;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.RequiresPermission;
-import android.annotation.SdkConstant;
-import android.annotation.SdkConstant.SdkConstantType;
-import android.annotation.SuppressLint;
-import android.annotation.SystemApi;
-import android.app.PropertyInvalidatedCache;
-import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
-import android.bluetooth.annotations.RequiresBluetoothLocationPermission;
-import android.bluetooth.annotations.RequiresBluetoothScanPermission;
-import android.bluetooth.annotations.RequiresLegacyBluetoothAdminPermission;
-import android.bluetooth.annotations.RequiresLegacyBluetoothPermission;
-import android.companion.AssociationRequest;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.content.AttributionSource;
-import android.content.Context;
-import android.os.Build;
-import android.os.Handler;
-import android.os.Parcel;
-import android.os.ParcelUuid;
-import android.os.Parcelable;
-import android.os.Process;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.UUID;
-
-/**
- * Represents a remote Bluetooth device. A {@link BluetoothDevice} lets you
- * create a connection with the respective device or query information about
- * it, such as the name, address, class, and bonding state.
- *
- * <p>This class is really just a thin wrapper for a Bluetooth hardware
- * address. Objects of this class are immutable. Operations on this class
- * are performed on the remote Bluetooth hardware address, using the
- * {@link BluetoothAdapter} that was used to create this {@link
- * BluetoothDevice}.
- *
- * <p>To get a {@link BluetoothDevice}, use
- * {@link BluetoothAdapter#getRemoteDevice(String)
- * BluetoothAdapter.getRemoteDevice(String)} to create one representing a device
- * of a known MAC address (which you can get through device discovery with
- * {@link BluetoothAdapter}) or get one from the set of bonded devices
- * returned by {@link BluetoothAdapter#getBondedDevices()
- * BluetoothAdapter.getBondedDevices()}. You can then open a
- * {@link BluetoothSocket} for communication with the remote device, using
- * {@link #createRfcommSocketToServiceRecord(UUID)} over Bluetooth BR/EDR or using
- * {@link #createL2capChannel(int)} over Bluetooth LE.
- *
- * <div class="special reference">
- * <h3>Developer Guides</h3>
- * <p>
- * For more information about using Bluetooth, read the <a href=
- * "{@docRoot}guide/topics/connectivity/bluetooth.html">Bluetooth</a> developer
- * guide.
- * </p>
- * </div>
- *
- * {@see BluetoothAdapter}
- * {@see BluetoothSocket}
- */
-public final class BluetoothDevice implements Parcelable, Attributable {
-    private static final String TAG = "BluetoothDevice";
-    private static final boolean DBG = false;
-
-    /**
-     * Connection state bitmask as returned by getConnectionState.
-     */
-    private static final int CONNECTION_STATE_DISCONNECTED = 0;
-    private static final int CONNECTION_STATE_CONNECTED = 1;
-    private static final int CONNECTION_STATE_ENCRYPTED_BREDR = 2;
-    private static final int CONNECTION_STATE_ENCRYPTED_LE = 4;
-
-    /**
-     * Sentinel error value for this class. Guaranteed to not equal any other
-     * integer constant in this class. Provided as a convenience for functions
-     * that require a sentinel error value, for example:
-     * <p><code>Intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE,
-     * BluetoothDevice.ERROR)</code>
-     */
-    public static final int ERROR = Integer.MIN_VALUE;
-
-    /**
-     * Broadcast Action: Remote device discovered.
-     * <p>Sent when a remote device is found during discovery.
-     * <p>Always contains the extra fields {@link #EXTRA_DEVICE} and {@link
-     * #EXTRA_CLASS}. Can contain the extra fields {@link #EXTRA_NAME} and/or
-     * {@link #EXTRA_RSSI} and/or {@link #EXTRA_IS_COORDINATED_SET_MEMBER} if they are available.
-     */
-    // TODO: Change API to not broadcast RSSI if not available (incoming connection)
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothScanPermission
-    @RequiresBluetoothLocationPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_FOUND =
-            "android.bluetooth.device.action.FOUND";
-
-    /**
-     * Broadcast Action: Bluetooth class of a remote device has changed.
-     * <p>Always contains the extra fields {@link #EXTRA_DEVICE} and {@link
-     * #EXTRA_CLASS}.
-     * {@see BluetoothClass}
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_CLASS_CHANGED =
-            "android.bluetooth.device.action.CLASS_CHANGED";
-
-    /**
-     * Broadcast Action: Indicates a low level (ACL) connection has been
-     * established with a remote device.
-     * <p>Always contains the extra field {@link #EXTRA_DEVICE}.
-     * <p>ACL connections are managed automatically by the Android Bluetooth
-     * stack.
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_ACL_CONNECTED =
-            "android.bluetooth.device.action.ACL_CONNECTED";
-
-    /**
-     * Broadcast Action: Indicates that a low level (ACL) disconnection has
-     * been requested for a remote device, and it will soon be disconnected.
-     * <p>This is useful for graceful disconnection. Applications should use
-     * this intent as a hint to immediately terminate higher level connections
-     * (RFCOMM, L2CAP, or profile connections) to the remote device.
-     * <p>Always contains the extra field {@link #EXTRA_DEVICE}.
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_ACL_DISCONNECT_REQUESTED =
-            "android.bluetooth.device.action.ACL_DISCONNECT_REQUESTED";
-
-    /**
-     * Broadcast Action: Indicates a low level (ACL) disconnection from a
-     * remote device.
-     * <p>Always contains the extra field {@link #EXTRA_DEVICE}.
-     * <p>ACL connections are managed automatically by the Android Bluetooth
-     * stack.
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_ACL_DISCONNECTED =
-            "android.bluetooth.device.action.ACL_DISCONNECTED";
-
-    /**
-     * Broadcast Action: Indicates the friendly name of a remote device has
-     * been retrieved for the first time, or changed since the last retrieval.
-     * <p>Always contains the extra fields {@link #EXTRA_DEVICE} and {@link
-     * #EXTRA_NAME}.
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_NAME_CHANGED =
-            "android.bluetooth.device.action.NAME_CHANGED";
-
-    /**
-     * Broadcast Action: Indicates the alias of a remote device has been
-     * changed.
-     * <p>Always contains the extra field {@link #EXTRA_DEVICE}.
-     */
-    @SuppressLint("ActionValue")
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_ALIAS_CHANGED =
-            "android.bluetooth.device.action.ALIAS_CHANGED";
-
-    /**
-     * Broadcast Action: Indicates a change in the bond state of a remote
-     * device. For example, if a device is bonded (paired).
-     * <p>Always contains the extra fields {@link #EXTRA_DEVICE}, {@link
-     * #EXTRA_BOND_STATE} and {@link #EXTRA_PREVIOUS_BOND_STATE}.
-     */
-    // Note: When EXTRA_BOND_STATE is BOND_NONE then this will also
-    // contain a hidden extra field EXTRA_REASON with the result code.
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_BOND_STATE_CHANGED =
-            "android.bluetooth.device.action.BOND_STATE_CHANGED";
-
-    /**
-     * Broadcast Action: Indicates the battery level of a remote device has
-     * been retrieved for the first time, or changed since the last retrieval
-     * <p>Always contains the extra fields {@link #EXTRA_DEVICE} and {@link
-     * #EXTRA_BATTERY_LEVEL}.
-     *
-     * @hide
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_BATTERY_LEVEL_CHANGED =
-            "android.bluetooth.device.action.BATTERY_LEVEL_CHANGED";
-
-    /**
-     * Used as an Integer extra field in {@link #ACTION_BATTERY_LEVEL_CHANGED}
-     * intent. It contains the most recently retrieved battery level information
-     * ranging from 0% to 100% for a remote device, {@link #BATTERY_LEVEL_UNKNOWN}
-     * when the valid is unknown or there is an error
-     *
-     * @hide
-     */
-    public static final String EXTRA_BATTERY_LEVEL =
-            "android.bluetooth.device.extra.BATTERY_LEVEL";
-
-    /**
-     * Used as the unknown value for {@link #EXTRA_BATTERY_LEVEL} and {@link #getBatteryLevel()}
-     *
-     * @hide
-     */
-    public static final int BATTERY_LEVEL_UNKNOWN = -1;
-
-    /**
-     * Used as an error value for {@link #getBatteryLevel()} to represent bluetooth is off
-     *
-     * @hide
-     */
-    public static final int BATTERY_LEVEL_BLUETOOTH_OFF = -100;
-
-    /**
-     * Used as a Parcelable {@link BluetoothDevice} extra field in every intent
-     * broadcast by this class. It contains the {@link BluetoothDevice} that
-     * the intent applies to.
-     */
-    public static final String EXTRA_DEVICE = "android.bluetooth.device.extra.DEVICE";
-
-    /**
-     * Used as a String extra field in {@link #ACTION_NAME_CHANGED} and {@link
-     * #ACTION_FOUND} intents. It contains the friendly Bluetooth name.
-     */
-    public static final String EXTRA_NAME = "android.bluetooth.device.extra.NAME";
-
-    /**
-     * Used as an optional short extra field in {@link #ACTION_FOUND} intents.
-     * Contains the RSSI value of the remote device as reported by the
-     * Bluetooth hardware.
-     */
-    public static final String EXTRA_RSSI = "android.bluetooth.device.extra.RSSI";
-
-    /**
-    * Used as an bool extra field in {@link #ACTION_FOUND} intents.
-    * It contains the information if device is discovered as member of a coordinated set or not.
-    * Pairing with device that belongs to a set would trigger pairing with the rest of set members.
-    * See Bluetooth CSIP specification for more details.
-    */
-    public static final String EXTRA_IS_COORDINATED_SET_MEMBER =
-            "android.bluetooth.extra.IS_COORDINATED_SET_MEMBER";
-
-    /**
-     * Used as a Parcelable {@link BluetoothClass} extra field in {@link
-     * #ACTION_FOUND} and {@link #ACTION_CLASS_CHANGED} intents.
-     */
-    public static final String EXTRA_CLASS = "android.bluetooth.device.extra.CLASS";
-
-    /**
-     * Used as an int extra field in {@link #ACTION_BOND_STATE_CHANGED} intents.
-     * Contains the bond state of the remote device.
-     * <p>Possible values are:
-     * {@link #BOND_NONE},
-     * {@link #BOND_BONDING},
-     * {@link #BOND_BONDED}.
-     */
-    public static final String EXTRA_BOND_STATE = "android.bluetooth.device.extra.BOND_STATE";
-    /**
-     * Used as an int extra field in {@link #ACTION_BOND_STATE_CHANGED} intents.
-     * Contains the previous bond state of the remote device.
-     * <p>Possible values are:
-     * {@link #BOND_NONE},
-     * {@link #BOND_BONDING},
-     * {@link #BOND_BONDED}.
-     */
-    public static final String EXTRA_PREVIOUS_BOND_STATE =
-            "android.bluetooth.device.extra.PREVIOUS_BOND_STATE";
-    /**
-     * Indicates the remote device is not bonded (paired).
-     * <p>There is no shared link key with the remote device, so communication
-     * (if it is allowed at all) will be unauthenticated and unencrypted.
-     */
-    public static final int BOND_NONE = 10;
-    /**
-     * Indicates bonding (pairing) is in progress with the remote device.
-     */
-    public static final int BOND_BONDING = 11;
-    /**
-     * Indicates the remote device is bonded (paired).
-     * <p>A shared link keys exists locally for the remote device, so
-     * communication can be authenticated and encrypted.
-     * <p><i>Being bonded (paired) with a remote device does not necessarily
-     * mean the device is currently connected. It just means that the pending
-     * procedure was completed at some earlier time, and the link key is still
-     * stored locally, ready to use on the next connection.
-     * </i>
-     */
-    public static final int BOND_BONDED = 12;
-
-    /**
-     * Used as an int extra field in {@link #ACTION_PAIRING_REQUEST}
-     * intents for unbond reason.
-     *
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public static final String EXTRA_REASON = "android.bluetooth.device.extra.REASON";
-
-    /**
-     * Used as an int extra field in {@link #ACTION_PAIRING_REQUEST}
-     * intents to indicate pairing method used. Possible values are:
-     * {@link #PAIRING_VARIANT_PIN},
-     * {@link #PAIRING_VARIANT_PASSKEY_CONFIRMATION},
-     */
-    public static final String EXTRA_PAIRING_VARIANT =
-            "android.bluetooth.device.extra.PAIRING_VARIANT";
-
-    /**
-     * Used as an int extra field in {@link #ACTION_PAIRING_REQUEST}
-     * intents as the value of passkey.
-     */
-    public static final String EXTRA_PAIRING_KEY = "android.bluetooth.device.extra.PAIRING_KEY";
-
-    /**
-     * Used as an int extra field in {@link #ACTION_PAIRING_REQUEST}
-     * intents as the value of passkey.
-     * @hide
-     */
-    public static final String EXTRA_PAIRING_INITIATOR =
-            "android.bluetooth.device.extra.PAIRING_INITIATOR";
-
-    /**
-     * Bluetooth pairing initiator, Foreground App
-     * @hide
-     */
-    public static final int EXTRA_PAIRING_INITIATOR_FOREGROUND = 1;
-
-    /**
-     * Bluetooth pairing initiator, Background
-     * @hide
-     */
-    public static final int EXTRA_PAIRING_INITIATOR_BACKGROUND = 2;
-
-    /**
-     * Bluetooth device type, Unknown
-     */
-    public static final int DEVICE_TYPE_UNKNOWN = 0;
-
-    /**
-     * Bluetooth device type, Classic - BR/EDR devices
-     */
-    public static final int DEVICE_TYPE_CLASSIC = 1;
-
-    /**
-     * Bluetooth device type, Low Energy - LE-only
-     */
-    public static final int DEVICE_TYPE_LE = 2;
-
-    /**
-     * Bluetooth device type, Dual Mode - BR/EDR/LE
-     */
-    public static final int DEVICE_TYPE_DUAL = 3;
-
-
-    /** @hide */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    public static final String ACTION_SDP_RECORD =
-            "android.bluetooth.device.action.SDP_RECORD";
-
-    /** @hide */
-    @IntDef(prefix = "METADATA_", value = {
-            METADATA_MANUFACTURER_NAME,
-            METADATA_MODEL_NAME,
-            METADATA_SOFTWARE_VERSION,
-            METADATA_HARDWARE_VERSION,
-            METADATA_COMPANION_APP,
-            METADATA_MAIN_ICON,
-            METADATA_IS_UNTETHERED_HEADSET,
-            METADATA_UNTETHERED_LEFT_ICON,
-            METADATA_UNTETHERED_RIGHT_ICON,
-            METADATA_UNTETHERED_CASE_ICON,
-            METADATA_UNTETHERED_LEFT_BATTERY,
-            METADATA_UNTETHERED_RIGHT_BATTERY,
-            METADATA_UNTETHERED_CASE_BATTERY,
-            METADATA_UNTETHERED_LEFT_CHARGING,
-            METADATA_UNTETHERED_RIGHT_CHARGING,
-            METADATA_UNTETHERED_CASE_CHARGING,
-            METADATA_ENHANCED_SETTINGS_UI_URI,
-            METADATA_DEVICE_TYPE,
-            METADATA_MAIN_BATTERY,
-            METADATA_MAIN_CHARGING,
-            METADATA_MAIN_LOW_BATTERY_THRESHOLD,
-            METADATA_UNTETHERED_LEFT_LOW_BATTERY_THRESHOLD,
-            METADATA_UNTETHERED_RIGHT_LOW_BATTERY_THRESHOLD,
-            METADATA_UNTETHERED_CASE_LOW_BATTERY_THRESHOLD})
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface MetadataKey{}
-
-    /**
-     * Maximum length of a metadata entry, this is to avoid exploding Bluetooth
-     * disk usage
-     * @hide
-     */
-    @SystemApi
-    public static final int METADATA_MAX_LENGTH = 2048;
-
-    /**
-     * Manufacturer name of this Bluetooth device
-     * Data type should be {@String} as {@link Byte} array.
-     * @hide
-     */
-    @SystemApi
-    public static final int METADATA_MANUFACTURER_NAME = 0;
-
-    /**
-     * Model name of this Bluetooth device
-     * Data type should be {@String} as {@link Byte} array.
-     * @hide
-     */
-    @SystemApi
-    public static final int METADATA_MODEL_NAME = 1;
-
-    /**
-     * Software version of this Bluetooth device
-     * Data type should be {@String} as {@link Byte} array.
-     * @hide
-     */
-    @SystemApi
-    public static final int METADATA_SOFTWARE_VERSION = 2;
-
-    /**
-     * Hardware version of this Bluetooth device
-     * Data type should be {@String} as {@link Byte} array.
-     * @hide
-     */
-    @SystemApi
-    public static final int METADATA_HARDWARE_VERSION = 3;
-
-    /**
-     * Package name of the companion app, if any
-     * Data type should be {@String} as {@link Byte} array.
-     * @hide
-     */
-    @SystemApi
-    public static final int METADATA_COMPANION_APP = 4;
-
-    /**
-     * URI to the main icon shown on the settings UI
-     * Data type should be {@link Byte} array.
-     * @hide
-     */
-    @SystemApi
-    public static final int METADATA_MAIN_ICON = 5;
-
-    /**
-     * Whether this device is an untethered headset with left, right and case
-     * Data type should be {@String} as {@link Byte} array.
-     * @hide
-     */
-    @SystemApi
-    public static final int METADATA_IS_UNTETHERED_HEADSET = 6;
-
-    /**
-     * URI to icon of the left headset
-     * Data type should be {@link Byte} array.
-     * @hide
-     */
-    @SystemApi
-    public static final int METADATA_UNTETHERED_LEFT_ICON = 7;
-
-    /**
-     * URI to icon of the right headset
-     * Data type should be {@link Byte} array.
-     * @hide
-     */
-    @SystemApi
-    public static final int METADATA_UNTETHERED_RIGHT_ICON = 8;
-
-    /**
-     * URI to icon of the headset charging case
-     * Data type should be {@link Byte} array.
-     * @hide
-     */
-    @SystemApi
-    public static final int METADATA_UNTETHERED_CASE_ICON = 9;
-
-    /**
-     * Battery level of left headset
-     * Data type should be {@String} 0-100 as {@link Byte} array, otherwise
-     * as invalid.
-     * @hide
-     */
-    @SystemApi
-    public static final int METADATA_UNTETHERED_LEFT_BATTERY = 10;
-
-    /**
-     * Battery level of rigth headset
-     * Data type should be {@String} 0-100 as {@link Byte} array, otherwise
-     * as invalid.
-     * @hide
-     */
-    @SystemApi
-    public static final int METADATA_UNTETHERED_RIGHT_BATTERY = 11;
-
-    /**
-     * Battery level of the headset charging case
-     * Data type should be {@String} 0-100 as {@link Byte} array, otherwise
-     * as invalid.
-     * @hide
-     */
-    @SystemApi
-    public static final int METADATA_UNTETHERED_CASE_BATTERY = 12;
-
-    /**
-     * Whether the left headset is charging
-     * Data type should be {@String} as {@link Byte} array.
-     * @hide
-     */
-    @SystemApi
-    public static final int METADATA_UNTETHERED_LEFT_CHARGING = 13;
-
-    /**
-     * Whether the right headset is charging
-     * Data type should be {@String} as {@link Byte} array.
-     * @hide
-     */
-    @SystemApi
-    public static final int METADATA_UNTETHERED_RIGHT_CHARGING = 14;
-
-    /**
-     * Whether the headset charging case is charging
-     * Data type should be {@String} as {@link Byte} array.
-     * @hide
-     */
-    @SystemApi
-    public static final int METADATA_UNTETHERED_CASE_CHARGING = 15;
-
-    /**
-     * URI to the enhanced settings UI slice
-     * Data type should be {@String} as {@link Byte} array, null means
-     * the UI does not exist.
-     * @hide
-     */
-    @SystemApi
-    public static final int METADATA_ENHANCED_SETTINGS_UI_URI = 16;
-
-    /**
-     * Type of the Bluetooth device, must be within the list of
-     * BluetoothDevice.DEVICE_TYPE_*
-     * Data type should be {@String} as {@link Byte} array.
-     * @hide
-     */
-    @SystemApi
-    public static final int METADATA_DEVICE_TYPE = 17;
-
-    /**
-     * Battery level of the Bluetooth device, use when the Bluetooth device
-     * does not support HFP battery indicator.
-     * Data type should be {@String} as {@link Byte} array.
-     * @hide
-     */
-    @SystemApi
-    public static final int METADATA_MAIN_BATTERY = 18;
-
-    /**
-     * Whether the device is charging.
-     * Data type should be {@String} as {@link Byte} array.
-     * @hide
-     */
-    @SystemApi
-    public static final int METADATA_MAIN_CHARGING = 19;
-
-    /**
-     * The battery threshold of the Bluetooth device to show low battery icon.
-     * Data type should be {@String} as {@link Byte} array.
-     * @hide
-     */
-    @SystemApi
-    public static final int METADATA_MAIN_LOW_BATTERY_THRESHOLD = 20;
-
-    /**
-     * The battery threshold of the left headset to show low battery icon.
-     * Data type should be {@String} as {@link Byte} array.
-     * @hide
-     */
-    @SystemApi
-    public static final int METADATA_UNTETHERED_LEFT_LOW_BATTERY_THRESHOLD = 21;
-
-    /**
-     * The battery threshold of the right headset to show low battery icon.
-     * Data type should be {@String} as {@link Byte} array.
-     * @hide
-     */
-    @SystemApi
-    public static final int METADATA_UNTETHERED_RIGHT_LOW_BATTERY_THRESHOLD = 22;
-
-    /**
-     * The battery threshold of the case to show low battery icon.
-     * Data type should be {@String} as {@link Byte} array.
-     * @hide
-     */
-    @SystemApi
-    public static final int METADATA_UNTETHERED_CASE_LOW_BATTERY_THRESHOLD = 23;
-
-    /**
-     * Device type which is used in METADATA_DEVICE_TYPE
-     * Indicates this Bluetooth device is a standard Bluetooth accessory or
-     * not listed in METADATA_DEVICE_TYPE_*.
-     * @hide
-     */
-    @SystemApi
-    public static final String DEVICE_TYPE_DEFAULT = "Default";
-
-    /**
-     * Device type which is used in METADATA_DEVICE_TYPE
-     * Indicates this Bluetooth device is a watch.
-     * @hide
-     */
-    @SystemApi
-    public static final String DEVICE_TYPE_WATCH = "Watch";
-
-    /**
-     * Device type which is used in METADATA_DEVICE_TYPE
-     * Indicates this Bluetooth device is an untethered headset.
-     * @hide
-     */
-    @SystemApi
-    public static final String DEVICE_TYPE_UNTETHERED_HEADSET = "Untethered Headset";
-
-    /**
-     * Broadcast Action: This intent is used to broadcast the {@link UUID}
-     * wrapped as a {@link android.os.ParcelUuid} of the remote device after it
-     * has been fetched. This intent is sent only when the UUIDs of the remote
-     * device are requested to be fetched using Service Discovery Protocol
-     * <p> Always contains the extra field {@link #EXTRA_DEVICE}
-     * <p> Always contains the extra field {@link #EXTRA_UUID}
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_UUID =
-            "android.bluetooth.device.action.UUID";
-
-    /** @hide */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_MAS_INSTANCE =
-            "android.bluetooth.device.action.MAS_INSTANCE";
-
-    /**
-     * Broadcast Action: Indicates a failure to retrieve the name of a remote
-     * device.
-     * <p>Always contains the extra field {@link #EXTRA_DEVICE}.
-     *
-     * @hide
-     */
-    //TODO: is this actually useful?
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_NAME_FAILED =
-            "android.bluetooth.device.action.NAME_FAILED";
-
-    /**
-     * Broadcast Action: This intent is used to broadcast PAIRING REQUEST
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_PAIRING_REQUEST =
-            "android.bluetooth.device.action.PAIRING_REQUEST";
-    /** @hide */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    @UnsupportedAppUsage
-    public static final String ACTION_PAIRING_CANCEL =
-            "android.bluetooth.device.action.PAIRING_CANCEL";
-
-    /** @hide */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_CONNECTION_ACCESS_REQUEST =
-            "android.bluetooth.device.action.CONNECTION_ACCESS_REQUEST";
-
-    /** @hide */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_CONNECTION_ACCESS_REPLY =
-            "android.bluetooth.device.action.CONNECTION_ACCESS_REPLY";
-
-    /** @hide */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_CONNECTION_ACCESS_CANCEL =
-            "android.bluetooth.device.action.CONNECTION_ACCESS_CANCEL";
-
-    /**
-     * Intent to broadcast silence mode changed.
-     * Alway contains the extra field {@link #EXTRA_DEVICE}
-     *
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    @SystemApi
-    public static final String ACTION_SILENCE_MODE_CHANGED =
-            "android.bluetooth.device.action.SILENCE_MODE_CHANGED";
-
-    /**
-     * Used as an extra field in {@link #ACTION_CONNECTION_ACCESS_REQUEST} intent.
-     *
-     * @hide
-     */
-    public static final String EXTRA_ACCESS_REQUEST_TYPE =
-            "android.bluetooth.device.extra.ACCESS_REQUEST_TYPE";
-
-    /** @hide */
-    public static final int REQUEST_TYPE_PROFILE_CONNECTION = 1;
-
-    /** @hide */
-    public static final int REQUEST_TYPE_PHONEBOOK_ACCESS = 2;
-
-    /** @hide */
-    public static final int REQUEST_TYPE_MESSAGE_ACCESS = 3;
-
-    /** @hide */
-    public static final int REQUEST_TYPE_SIM_ACCESS = 4;
-
-    /**
-     * Used as an extra field in {@link #ACTION_CONNECTION_ACCESS_REQUEST} intents,
-     * Contains package name to return reply intent to.
-     *
-     * @hide
-     */
-    public static final String EXTRA_PACKAGE_NAME = "android.bluetooth.device.extra.PACKAGE_NAME";
-
-    /**
-     * Used as an extra field in {@link #ACTION_CONNECTION_ACCESS_REQUEST} intents,
-     * Contains class name to return reply intent to.
-     *
-     * @hide
-     */
-    public static final String EXTRA_CLASS_NAME = "android.bluetooth.device.extra.CLASS_NAME";
-
-    /**
-     * Used as an extra field in {@link #ACTION_CONNECTION_ACCESS_REPLY} intent.
-     *
-     * @hide
-     */
-    public static final String EXTRA_CONNECTION_ACCESS_RESULT =
-            "android.bluetooth.device.extra.CONNECTION_ACCESS_RESULT";
-
-    /** @hide */
-    public static final int CONNECTION_ACCESS_YES = 1;
-
-    /** @hide */
-    public static final int CONNECTION_ACCESS_NO = 2;
-
-    /**
-     * Used as an extra field in {@link #ACTION_CONNECTION_ACCESS_REPLY} intents,
-     * Contains boolean to indicate if the allowed response is once-for-all so that
-     * next request will be granted without asking user again.
-     *
-     * @hide
-     */
-    public static final String EXTRA_ALWAYS_ALLOWED =
-            "android.bluetooth.device.extra.ALWAYS_ALLOWED";
-
-    /**
-     * A bond attempt succeeded
-     *
-     * @hide
-     */
-    public static final int BOND_SUCCESS = 0;
-
-    /**
-     * A bond attempt failed because pins did not match, or remote device did
-     * not respond to pin request in time
-     *
-     * @hide
-     */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    public static final int UNBOND_REASON_AUTH_FAILED = 1;
-
-    /**
-     * A bond attempt failed because the other side explicitly rejected
-     * bonding
-     *
-     * @hide
-     */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    public static final int UNBOND_REASON_AUTH_REJECTED = 2;
-
-    /**
-     * A bond attempt failed because we canceled the bonding process
-     *
-     * @hide
-     */
-    public static final int UNBOND_REASON_AUTH_CANCELED = 3;
-
-    /**
-     * A bond attempt failed because we could not contact the remote device
-     *
-     * @hide
-     */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    public static final int UNBOND_REASON_REMOTE_DEVICE_DOWN = 4;
-
-    /**
-     * A bond attempt failed because a discovery is in progress
-     *
-     * @hide
-     */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    public static final int UNBOND_REASON_DISCOVERY_IN_PROGRESS = 5;
-
-    /**
-     * A bond attempt failed because of authentication timeout
-     *
-     * @hide
-     */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    public static final int UNBOND_REASON_AUTH_TIMEOUT = 6;
-
-    /**
-     * A bond attempt failed because of repeated attempts
-     *
-     * @hide
-     */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    public static final int UNBOND_REASON_REPEATED_ATTEMPTS = 7;
-
-    /**
-     * A bond attempt failed because we received an Authentication Cancel
-     * by remote end
-     *
-     * @hide
-     */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    public static final int UNBOND_REASON_REMOTE_AUTH_CANCELED = 8;
-
-    /**
-     * An existing bond was explicitly revoked
-     *
-     * @hide
-     */
-    public static final int UNBOND_REASON_REMOVED = 9;
-
-    /**
-     * The user will be prompted to enter a pin or
-     * an app will enter a pin for user.
-     */
-    public static final int PAIRING_VARIANT_PIN = 0;
-
-    /**
-     * The user will be prompted to enter a passkey
-     *
-     * @hide
-     */
-    public static final int PAIRING_VARIANT_PASSKEY = 1;
-
-    /**
-     * The user will be prompted to confirm the passkey displayed on the screen or
-     * an app will confirm the passkey for the user.
-     */
-    public static final int PAIRING_VARIANT_PASSKEY_CONFIRMATION = 2;
-
-    /**
-     * The user will be prompted to accept or deny the incoming pairing request
-     *
-     * @hide
-     */
-    public static final int PAIRING_VARIANT_CONSENT = 3;
-
-    /**
-     * The user will be prompted to enter the passkey displayed on remote device
-     * This is used for Bluetooth 2.1 pairing.
-     *
-     * @hide
-     */
-    public static final int PAIRING_VARIANT_DISPLAY_PASSKEY = 4;
-
-    /**
-     * The user will be prompted to enter the PIN displayed on remote device.
-     * This is used for Bluetooth 2.0 pairing.
-     *
-     * @hide
-     */
-    public static final int PAIRING_VARIANT_DISPLAY_PIN = 5;
-
-    /**
-     * The user will be prompted to accept or deny the OOB pairing request
-     *
-     * @hide
-     */
-    public static final int PAIRING_VARIANT_OOB_CONSENT = 6;
-
-    /**
-     * The user will be prompted to enter a 16 digit pin or
-     * an app will enter a 16 digit pin for user.
-     *
-     * @hide
-     */
-    public static final int PAIRING_VARIANT_PIN_16_DIGITS = 7;
-
-    /**
-     * Used as an extra field in {@link #ACTION_UUID} intents,
-     * Contains the {@link android.os.ParcelUuid}s of the remote device which
-     * is a parcelable version of {@link UUID}.
-     */
-    public static final String EXTRA_UUID = "android.bluetooth.device.extra.UUID";
-
-    /** @hide */
-    public static final String EXTRA_SDP_RECORD =
-            "android.bluetooth.device.extra.SDP_RECORD";
-
-    /** @hide */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    public static final String EXTRA_SDP_SEARCH_STATUS =
-            "android.bluetooth.device.extra.SDP_SEARCH_STATUS";
-
-    /** @hide */
-    @IntDef(prefix = "ACCESS_", value = {ACCESS_UNKNOWN,
-            ACCESS_ALLOWED, ACCESS_REJECTED})
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface AccessPermission{}
-
-    /**
-     * For {@link #getPhonebookAccessPermission}, {@link #setPhonebookAccessPermission},
-     * {@link #getMessageAccessPermission} and {@link #setMessageAccessPermission}.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int ACCESS_UNKNOWN = 0;
-
-    /**
-     * For {@link #getPhonebookAccessPermission}, {@link #setPhonebookAccessPermission},
-     * {@link #getMessageAccessPermission} and {@link #setMessageAccessPermission}.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int ACCESS_ALLOWED = 1;
-
-    /**
-     * For {@link #getPhonebookAccessPermission}, {@link #setPhonebookAccessPermission},
-     * {@link #getMessageAccessPermission} and {@link #setMessageAccessPermission}.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int ACCESS_REJECTED = 2;
-
-    /** @hide */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(
-        prefix = { "TRANSPORT_" },
-        value = {
-            /** Allow host to automatically select a transport (dual-mode only) */
-            TRANSPORT_AUTO,
-            /** Use Classic or BR/EDR transport.*/
-            TRANSPORT_BREDR,
-            /** Use Low Energy transport.*/
-            TRANSPORT_LE,
-        }
-    )
-    public @interface Transport {}
-
-    /**
-     * No preference of physical transport for GATT connections to remote dual-mode devices
-     */
-    public static final int TRANSPORT_AUTO = 0;
-
-    /**
-     * Prefer BR/EDR transport for GATT connections to remote dual-mode devices
-     */
-    public static final int TRANSPORT_BREDR = 1;
-
-    /**
-     * Prefer LE transport for GATT connections to remote dual-mode devices
-     */
-    public static final int TRANSPORT_LE = 2;
-
-    /**
-     * Bluetooth LE 1M PHY. Used to refer to LE 1M Physical Channel for advertising, scanning or
-     * connection.
-     */
-    public static final int PHY_LE_1M = 1;
-
-    /**
-     * Bluetooth LE 2M PHY. Used to refer to LE 2M Physical Channel for advertising, scanning or
-     * connection.
-     */
-    public static final int PHY_LE_2M = 2;
-
-    /**
-     * Bluetooth LE Coded PHY. Used to refer to LE Coded Physical Channel for advertising, scanning
-     * or connection.
-     */
-    public static final int PHY_LE_CODED = 3;
-
-    /**
-     * Bluetooth LE 1M PHY mask. Used to specify LE 1M Physical Channel as one of many available
-     * options in a bitmask.
-     */
-    public static final int PHY_LE_1M_MASK = 1;
-
-    /**
-     * Bluetooth LE 2M PHY mask. Used to specify LE 2M Physical Channel as one of many available
-     * options in a bitmask.
-     */
-    public static final int PHY_LE_2M_MASK = 2;
-
-    /**
-     * Bluetooth LE Coded PHY mask. Used to specify LE Coded Physical Channel as one of many
-     * available options in a bitmask.
-     */
-    public static final int PHY_LE_CODED_MASK = 4;
-
-    /**
-     * No preferred coding when transmitting on the LE Coded PHY.
-     */
-    public static final int PHY_OPTION_NO_PREFERRED = 0;
-
-    /**
-     * Prefer the S=2 coding to be used when transmitting on the LE Coded PHY.
-     */
-    public static final int PHY_OPTION_S2 = 1;
-
-    /**
-     * Prefer the S=8 coding to be used when transmitting on the LE Coded PHY.
-     */
-    public static final int PHY_OPTION_S8 = 2;
-
-
-    /** @hide */
-    public static final String EXTRA_MAS_INSTANCE =
-            "android.bluetooth.device.extra.MAS_INSTANCE";
-
-    /** @hide */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(
-        prefix = { "ADDRESS_TYPE_" },
-        value = {
-            /** Hardware MAC Address */
-            ADDRESS_TYPE_PUBLIC,
-            /** Address is either resolvable, non-resolvable or static.*/
-            ADDRESS_TYPE_RANDOM,
-        }
-    )
-    public @interface AddressType {}
-
-    /** Hardware MAC Address of the device */
-    public static final int ADDRESS_TYPE_PUBLIC = 0;
-    /** Address is either resolvable, non-resolvable or static. */
-    public static final int ADDRESS_TYPE_RANDOM = 1;
-
-    private static final String NULL_MAC_ADDRESS = "00:00:00:00:00:00";
-
-    /**
-     * Lazy initialization. Guaranteed final after first object constructed, or
-     * getService() called.
-     * TODO: Unify implementation of sService amongst BluetoothFoo API's
-     */
-    private static volatile IBluetooth sService;
-
-    private final String mAddress;
-    @AddressType private final int mAddressType;
-
-    private AttributionSource mAttributionSource;
-
-    /*package*/
-    @UnsupportedAppUsage
-    static IBluetooth getService() {
-        synchronized (BluetoothDevice.class) {
-            if (sService == null) {
-                BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
-                sService = adapter.getBluetoothService(sStateChangeCallback);
-            }
-        }
-        return sService;
-    }
-
-    static IBluetoothManagerCallback sStateChangeCallback = new IBluetoothManagerCallback.Stub() {
-
-        public void onBluetoothServiceUp(IBluetooth bluetoothService)
-                throws RemoteException {
-            synchronized (BluetoothDevice.class) {
-                if (sService == null) {
-                    sService = bluetoothService;
-                }
-            }
-        }
-
-        public void onBluetoothServiceDown()
-                throws RemoteException {
-            synchronized (BluetoothDevice.class) {
-                sService = null;
-            }
-        }
-
-        public void onBrEdrDown() {
-            if (DBG) Log.d(TAG, "onBrEdrDown: reached BLE ON state");
-        }
-
-        public void onOobData(@Transport int transport, OobData oobData) {
-            if (DBG) Log.d(TAG, "onOobData: got data");
-        }
-    };
-
-    /**
-     * Create a new BluetoothDevice
-     * Bluetooth MAC address must be upper case, such as "00:11:22:33:AA:BB",
-     * and is validated in this constructor.
-     *
-     * @param address valid Bluetooth MAC address
-     * @param attributionSource attribution for permission-protected calls
-     * @throws RuntimeException Bluetooth is not available on this platform
-     * @throws IllegalArgumentException address is invalid
-     * @hide
-     */
-    @UnsupportedAppUsage
-    /*package*/ BluetoothDevice(String address) {
-        getService();  // ensures sService is initialized
-        if (!BluetoothAdapter.checkBluetoothAddress(address)) {
-            throw new IllegalArgumentException(address + " is not a valid Bluetooth address");
-        }
-
-        mAddress = address;
-        mAddressType = ADDRESS_TYPE_PUBLIC;
-        mAttributionSource = AttributionSource.myAttributionSource();
-    }
-
-    /** {@hide} */
-    public void setAttributionSource(@NonNull AttributionSource attributionSource) {
-        mAttributionSource = attributionSource;
-    }
-
-    /** {@hide} */
-    public void prepareToEnterProcess(@NonNull AttributionSource attributionSource) {
-        setAttributionSource(attributionSource);
-    }
-
-    @Override
-    public boolean equals(@Nullable Object o) {
-        if (o instanceof BluetoothDevice) {
-            return mAddress.equals(((BluetoothDevice) o).getAddress());
-        }
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        return mAddress.hashCode();
-    }
-
-    /**
-     * Returns a string representation of this BluetoothDevice.
-     * <p>Currently this is the Bluetooth hardware address, for example
-     * "00:11:22:AA:BB:CC". However, you should always use {@link #getAddress}
-     * if you explicitly require the Bluetooth hardware address in case the
-     * {@link #toString} representation changes in the future.
-     *
-     * @return string representation of this BluetoothDevice
-     */
-    @Override
-    public String toString() {
-        return mAddress;
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    public static final @android.annotation.NonNull Parcelable.Creator<BluetoothDevice> CREATOR =
-            new Parcelable.Creator<BluetoothDevice>() {
-                public BluetoothDevice createFromParcel(Parcel in) {
-                    return new BluetoothDevice(in.readString());
-                }
-
-                public BluetoothDevice[] newArray(int size) {
-                    return new BluetoothDevice[size];
-                }
-            };
-
-    @Override
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeString(mAddress);
-    }
-
-    /**
-     * Returns the hardware address of this BluetoothDevice.
-     * <p> For example, "00:11:22:AA:BB:CC".
-     *
-     * @return Bluetooth hardware address as string
-     */
-    public String getAddress() {
-        if (DBG) Log.d(TAG, "mAddress: " + mAddress);
-        return mAddress;
-    }
-
-    /**
-     * Returns the anonymized hardware address of this BluetoothDevice. The first three octets
-     * will be suppressed for anonymization.
-     * <p> For example, "XX:XX:XX:AA:BB:CC".
-     *
-     * @return Anonymized bluetooth hardware address as string
-     * @hide
-     */
-    public String getAnonymizedAddress() {
-        return "XX:XX:XX" + getAddress().substring(8);
-    }
-
-    /**
-     * Get the friendly Bluetooth name of the remote device.
-     *
-     * <p>The local adapter will automatically retrieve remote names when
-     * performing a device scan, and will cache them. This method just returns
-     * the name for this device from the cache.
-     *
-     * @return the Bluetooth name, or null if there was a problem.
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public String getName() {
-        final IBluetooth service = sService;
-        if (service == null) {
-            Log.e(TAG, "BT not enabled. Cannot get Remote Device name");
-            return null;
-        }
-        try {
-            String name = service.getRemoteName(this, mAttributionSource);
-            if (name != null) {
-                // remove whitespace characters from the name
-                return name
-                        .replace('\t', ' ')
-                        .replace('\n', ' ')
-                        .replace('\r', ' ');
-            }
-            return null;
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        }
-        return null;
-    }
-
-    /**
-     * Get the Bluetooth device type of the remote device.
-     *
-     * @return the device type {@link #DEVICE_TYPE_CLASSIC}, {@link #DEVICE_TYPE_LE} {@link
-     * #DEVICE_TYPE_DUAL}. {@link #DEVICE_TYPE_UNKNOWN} if it's not available
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public int getType() {
-        final IBluetooth service = sService;
-        if (service == null) {
-            Log.e(TAG, "BT not enabled. Cannot get Remote Device type");
-            return DEVICE_TYPE_UNKNOWN;
-        }
-        try {
-            return service.getRemoteType(this, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        }
-        return DEVICE_TYPE_UNKNOWN;
-    }
-
-    /**
-     * Get the locally modifiable name (alias) of the remote Bluetooth device.
-     *
-     * @return the Bluetooth alias, the friendly device name if no alias, or
-     * null if there was a problem
-     */
-    @Nullable
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public String getAlias() {
-        final IBluetooth service = sService;
-        if (service == null) {
-            Log.e(TAG, "BT not enabled. Cannot get Remote Device Alias");
-            return null;
-        }
-        try {
-            String alias = service.getRemoteAliasWithAttribution(this, mAttributionSource);
-            if (alias == null) {
-                return getName();
-            }
-            return alias
-                    .replace('\t', ' ')
-                    .replace('\n', ' ')
-                    .replace('\r', ' ');
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        }
-        return null;
-    }
-
-    /** @hide */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(value = {
-            BluetoothStatusCodes.SUCCESS,
-            BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED,
-            BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ALLOWED,
-            BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION,
-            BluetoothStatusCodes.ERROR_DEVICE_NOT_BONDED
-    })
-    public @interface SetAliasReturnValues{}
-
-    /**
-     * Sets the locally modifiable name (alias) of the remote Bluetooth device. This method
-     * overwrites the previously stored alias. The new alias is saved in local
-     * storage so that the change is preserved over power cycles.
-     *
-     * <p>This method requires the calling app to be associated with Companion Device Manager (see
-     * {@link android.companion.CompanionDeviceManager#associate(AssociationRequest,
-     * android.companion.CompanionDeviceManager.Callback, Handler)}) and have the
-     * {@link android.Manifest.permission#BLUETOOTH_CONNECT} permission. Alternatively, if the
-     * caller has the {@link android.Manifest.permission#BLUETOOTH_PRIVILEGED} permission, they can
-     * bypass the Companion Device Manager association requirement as well as other permission
-     * requirements.
-     *
-     * @param alias is the new locally modifiable name for the remote Bluetooth device which must
-     *              be the empty string. If null, we clear the alias.
-     * @return whether the alias was successfully changed
-     * @throws IllegalArgumentException if the alias is the empty string
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public @SetAliasReturnValues int setAlias(@Nullable String alias) {
-        if (alias != null && alias.isEmpty()) {
-            throw new IllegalArgumentException("alias cannot be the empty string");
-        }
-        final IBluetooth service = sService;
-        if (service == null) {
-            Log.e(TAG, "BT not enabled. Cannot set Remote Device name");
-            return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED;
-        }
-        try {
-            return service.setRemoteAlias(this, alias, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Get the most recent identified battery level of this Bluetooth device
-     *
-     * @return Battery level in percents from 0 to 100, {@link #BATTERY_LEVEL_BLUETOOTH_OFF} if
-     * Bluetooth is disabled or {@link #BATTERY_LEVEL_UNKNOWN} if device is disconnected, or does
-     * not have any battery reporting service, or return value is invalid
-     * @hide
-     */
-    @UnsupportedAppUsage
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public int getBatteryLevel() {
-        final IBluetooth service = sService;
-        if (service == null) {
-            Log.e(TAG, "Bluetooth disabled. Cannot get remote device battery level");
-            return BATTERY_LEVEL_BLUETOOTH_OFF;
-        }
-        try {
-            return service.getBatteryLevel(this, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        }
-        return BATTERY_LEVEL_UNKNOWN;
-    }
-
-    /**
-     * Start the bonding (pairing) process with the remote device.
-     * <p>This is an asynchronous call, it will return immediately. Register
-     * for {@link #ACTION_BOND_STATE_CHANGED} intents to be notified when
-     * the bonding process completes, and its result.
-     * <p>Android system services will handle the necessary user interactions
-     * to confirm and complete the bonding process.
-     *
-     * @return false on immediate error, true if bonding will begin
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean createBond() {
-        return createBond(TRANSPORT_AUTO);
-    }
-
-    /**
-     * Start the bonding (pairing) process with the remote device using the
-     * specified transport.
-     *
-     * <p>This is an asynchronous call, it will return immediately. Register
-     * for {@link #ACTION_BOND_STATE_CHANGED} intents to be notified when
-     * the bonding process completes, and its result.
-     * <p>Android system services will handle the necessary user interactions
-     * to confirm and complete the bonding process.
-     *
-     * @param transport The transport to use for the pairing procedure.
-     * @return false on immediate error, true if bonding will begin
-     * @throws IllegalArgumentException if an invalid transport was specified
-     * @hide
-     */
-    @SystemApi
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean createBond(int transport) {
-        return createBondInternal(transport, null, null);
-    }
-
-    /**
-     * Start the bonding (pairing) process with the remote device using the
-     * Out Of Band mechanism.
-     *
-     * <p>This is an asynchronous call, it will return immediately. Register
-     * for {@link #ACTION_BOND_STATE_CHANGED} intents to be notified when
-     * the bonding process completes, and its result.
-     *
-     * <p>Android system services will handle the necessary user interactions
-     * to confirm and complete the bonding process.
-     *
-     * <p>There are two possible versions of OOB Data.  This data can come in as
-     * P192 or P256.  This is a reference to the cryptography used to generate the key.
-     * The caller may pass one or both.  If both types of data are passed, then the
-     * P256 data will be preferred, and thus used.
-     *
-     * @param transport - Transport to use
-     * @param remoteP192Data - Out Of Band data (P192) or null
-     * @param remoteP256Data - Out Of Band data (P256) or null
-     * @return false on immediate error, true if bonding will begin
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean createBondOutOfBand(int transport, @Nullable OobData remoteP192Data,
-            @Nullable OobData remoteP256Data) {
-        if (remoteP192Data == null && remoteP256Data == null) {
-            throw new IllegalArgumentException(
-                "One or both arguments for the OOB data types are required to not be null."
-                + "  Please use createBond() instead if you do not have OOB data to pass.");
-        }
-        return createBondInternal(transport, remoteP192Data, remoteP256Data);
-    }
-
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    private boolean createBondInternal(int transport, @Nullable OobData remoteP192Data,
-            @Nullable OobData remoteP256Data) {
-        final IBluetooth service = sService;
-        if (service == null) {
-            Log.w(TAG, "BT not enabled, createBondOutOfBand failed");
-            return false;
-        }
-        if (NULL_MAC_ADDRESS.equals(mAddress)) {
-            Log.e(TAG, "Unable to create bond, invalid address " + mAddress);
-            return false;
-        }
-        try {
-            return service.createBond(
-                    this, transport, remoteP192Data, remoteP256Data, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        }
-        return false;
-    }
-
-    /**
-     * Gets whether bonding was initiated locally
-     *
-     * @return true if bonding is initiated locally, false otherwise
-     *
-     * @hide
-     */
-    @UnsupportedAppUsage
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean isBondingInitiatedLocally() {
-        final IBluetooth service = sService;
-        if (service == null) {
-            Log.w(TAG, "BT not enabled, isBondingInitiatedLocally failed");
-            return false;
-        }
-        try {
-            return service.isBondingInitiatedLocally(this, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        }
-        return false;
-    }
-
-    /**
-     * Cancel an in-progress bonding request started with {@link #createBond}.
-     *
-     * @return true on success, false on error
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean cancelBondProcess() {
-        final IBluetooth service = sService;
-        if (service == null) {
-            Log.e(TAG, "BT not enabled. Cannot cancel Remote Device bond");
-            return false;
-        }
-        try {
-            Log.i(TAG, "cancelBondProcess() for device " + getAddress()
-                    + " called by pid: " + Process.myPid()
-                    + " tid: " + Process.myTid());
-            return service.cancelBondProcess(this, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        }
-        return false;
-    }
-
-    /**
-     * Remove bond (pairing) with the remote device.
-     * <p>Delete the link key associated with the remote device, and
-     * immediately terminate connections to that device that require
-     * authentication and encryption.
-     *
-     * @return true on success, false on error
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean removeBond() {
-        final IBluetooth service = sService;
-        if (service == null) {
-            Log.e(TAG, "BT not enabled. Cannot remove Remote Device bond");
-            return false;
-        }
-        try {
-            Log.i(TAG, "removeBond() for device " + getAddress()
-                    + " called by pid: " + Process.myPid()
-                    + " tid: " + Process.myTid());
-            return service.removeBond(this, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        }
-        return false;
-    }
-
-    private static final String BLUETOOTH_BONDING_CACHE_PROPERTY =
-            "cache_key.bluetooth.get_bond_state";
-    private final PropertyInvalidatedCache<BluetoothDevice, Integer> mBluetoothBondCache =
-            new PropertyInvalidatedCache<BluetoothDevice, Integer>(
-                8, BLUETOOTH_BONDING_CACHE_PROPERTY) {
-                @Override
-                @SuppressLint("AndroidFrameworkRequiresPermission")
-                protected Integer recompute(BluetoothDevice query) {
-                    try {
-                        return sService.getBondState(query, mAttributionSource);
-                    } catch (RemoteException e) {
-                        throw e.rethrowAsRuntimeException();
-                    }
-                }
-            };
-
-    /** @hide */
-    public void disableBluetoothGetBondStateCache() {
-        mBluetoothBondCache.disableLocal();
-    }
-
-    /** @hide */
-    public static void invalidateBluetoothGetBondStateCache() {
-        PropertyInvalidatedCache.invalidateCache(BLUETOOTH_BONDING_CACHE_PROPERTY);
-    }
-
-    /**
-     * Get the bond state of the remote device.
-     * <p>Possible values for the bond state are:
-     * {@link #BOND_NONE},
-     * {@link #BOND_BONDING},
-     * {@link #BOND_BONDED}.
-     *
-     * @return the bond state
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SuppressLint("AndroidFrameworkRequiresPermission")
-    public int getBondState() {
-        final IBluetooth service = sService;
-        if (service == null) {
-            Log.e(TAG, "BT not enabled. Cannot get bond state");
-            return BOND_NONE;
-        }
-        try {
-            return mBluetoothBondCache.query(this);
-        } catch (RuntimeException e) {
-            if (e.getCause() instanceof RemoteException) {
-                Log.e(TAG, "", e);
-            } else {
-                throw e;
-            }
-        }
-        return BOND_NONE;
-    }
-
-    /**
-     * Checks whether this bluetooth device is associated with CDM and meets the criteria to skip
-     * the bluetooth pairing dialog because it has been already consented by the CDM prompt.
-     *
-     * @return true if we can bond without the dialog, false otherwise
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public boolean canBondWithoutDialog() {
-        final IBluetooth service = sService;
-        if (service == null) {
-            Log.e(TAG, "BT not enabled. Cannot check if we can skip pairing dialog");
-            return false;
-        }
-        try {
-            if (DBG) Log.d(TAG, "canBondWithoutDialog, device: " + this);
-            return service.canBondWithoutDialog(this, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        }
-        return false;
-    }
-
-    /** @hide */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(value = {
-            BluetoothStatusCodes.SUCCESS,
-            BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED,
-            BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ALLOWED,
-            BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION,
-            BluetoothStatusCodes.ERROR_DEVICE_NOT_BONDED
-    })
-    public @interface ConnectionReturnValues{}
-
-    /**
-     * Connects all user enabled and supported bluetooth profiles between the local and remote
-     * device. If no profiles are user enabled (e.g. first connection), we connect all supported
-     * profiles. If the device is not already connected, this will page the device before initiating
-     * profile connections. Connection is asynchronous and you should listen to each profile's
-     * broadcast intent ACTION_CONNECTION_STATE_CHANGED to verify whether connection was successful.
-     * For example, to verify a2dp is connected, you would listen for
-     * {@link BluetoothA2dp#ACTION_CONNECTION_STATE_CHANGED}
-     *
-     * @return whether the messages were successfully sent to try to connect all profiles
-     * @throws IllegalArgumentException if the device address is invalid
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-            android.Manifest.permission.MODIFY_PHONE_STATE,
-    })
-    public @ConnectionReturnValues int connect() {
-        if (!BluetoothAdapter.checkBluetoothAddress(getAddress())) {
-            throw new IllegalArgumentException("device cannot have an invalid address");
-        }
-
-        try {
-            if (sService == null) {
-                Log.e(TAG, "BT not enabled. Cannot connect to remote device.");
-                return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED;
-            }
-            return sService.connectAllEnabledProfiles(this, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Disconnects all connected bluetooth profiles between the local and remote device.
-     * Disconnection is asynchronous and you should listen to each profile's broadcast intent
-     * ACTION_CONNECTION_STATE_CHANGED to verify whether disconnection was successful. For example,
-     * to verify a2dp is disconnected, you would listen for
-     * {@link BluetoothA2dp#ACTION_CONNECTION_STATE_CHANGED}
-     *
-     * @return whether the messages were successfully sent to try to disconnect all profiles
-     * @throws IllegalArgumentException if the device address is invalid
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public @ConnectionReturnValues int disconnect() {
-        if (!BluetoothAdapter.checkBluetoothAddress(getAddress())) {
-            throw new IllegalArgumentException("device cannot have an invalid address");
-        }
-
-        try {
-            if (sService == null) {
-                Log.e(TAG, "BT not enabled. Cannot disconnect from remote device.");
-                return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED;
-            }
-            return sService.disconnectAllEnabledProfiles(this, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Returns whether there is an open connection to this device.
-     *
-     * @return True if there is at least one open connection to this device.
-     * @hide
-     */
-    @SystemApi
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean isConnected() {
-        final IBluetooth service = sService;
-        if (service == null) {
-            // BT is not enabled, we cannot be connected.
-            return false;
-        }
-        try {
-            return service.getConnectionStateWithAttribution(this, mAttributionSource)
-                    != CONNECTION_STATE_DISCONNECTED;
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-            return false;
-        }
-    }
-
-    /**
-     * Returns whether there is an open connection to this device
-     * that has been encrypted.
-     *
-     * @return True if there is at least one encrypted connection to this device.
-     * @hide
-     */
-    @SystemApi
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean isEncrypted() {
-        final IBluetooth service = sService;
-        if (service == null) {
-            // BT is not enabled, we cannot be connected.
-            return false;
-        }
-        try {
-            return service.getConnectionStateWithAttribution(this, mAttributionSource)
-                    > CONNECTION_STATE_CONNECTED;
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-            return false;
-        }
-    }
-
-    /**
-     * Get the Bluetooth class of the remote device.
-     *
-     * @return Bluetooth class object, or null on error
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public BluetoothClass getBluetoothClass() {
-        final IBluetooth service = sService;
-        if (service == null) {
-            Log.e(TAG, "BT not enabled. Cannot get Bluetooth Class");
-            return null;
-        }
-        try {
-            int classInt = service.getRemoteClass(this, mAttributionSource);
-            if (classInt == BluetoothClass.ERROR) return null;
-            return new BluetoothClass(classInt);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        }
-        return null;
-    }
-
-    /**
-     * Returns the supported features (UUIDs) of the remote device.
-     *
-     * <p>This method does not start a service discovery procedure to retrieve the UUIDs
-     * from the remote device. Instead, the local cached copy of the service
-     * UUIDs are returned.
-     * <p>Use {@link #fetchUuidsWithSdp} if fresh UUIDs are desired.
-     *
-     * @return the supported features (UUIDs) of the remote device, or null on error
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public ParcelUuid[] getUuids() {
-        final IBluetooth service = sService;
-        if (service == null || !isBluetoothEnabled()) {
-            Log.e(TAG, "BT not enabled. Cannot get remote device Uuids");
-            return null;
-        }
-        try {
-            return service.getRemoteUuids(this, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        }
-        return null;
-    }
-
-    /**
-     * Perform a service discovery on the remote device to get the UUIDs supported.
-     *
-     * <p>This API is asynchronous and {@link #ACTION_UUID} intent is sent,
-     * with the UUIDs supported by the remote end. If there is an error
-     * in getting the SDP records or if the process takes a long time, or the device is bonding and
-     * we have its UUIDs cached, {@link #ACTION_UUID} intent is sent with the UUIDs that is
-     * currently present in the cache. Clients should use the {@link #getUuids} to get UUIDs
-     * if service discovery is not to be performed. If there is an ongoing bonding process,
-     * service discovery or device inquiry, the request will be queued.
-     *
-     * @return False if the check fails, True if the process of initiating an ACL connection
-     * to the remote device was started or cached UUIDs will be broadcast.
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean fetchUuidsWithSdp() {
-        return fetchUuidsWithSdp(TRANSPORT_AUTO);
-    }
-
-    /**
-     * Perform a service discovery on the remote device to get the UUIDs supported with the
-     * specific transport.
-     *
-     * <p>This API is asynchronous and {@link #ACTION_UUID} intent is sent,
-     * with the UUIDs supported by the remote end. If there is an error
-     * in getting the SDP or GATT records or if the process takes a long time, or the device
-     * is bonding and we have its UUIDs cached, {@link #ACTION_UUID} intent is sent with the
-     * UUIDs that is currently present in the cache. Clients should use the {@link #getUuids}
-     * to get UUIDs if service discovery is not to be performed. If there is an ongoing bonding
-     * process, service discovery or device inquiry, the request will be queued.
-     *
-     * @param transport - provide type of transport (e.g. LE or Classic).
-     * @return False if the check fails, True if the process of initiating an ACL connection
-     * to the remote device was started or cached UUIDs will be broadcast with the specific
-     * transport.
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public boolean fetchUuidsWithSdp(@Transport int transport) {
-        final IBluetooth service = sService;
-        if (service == null || !isBluetoothEnabled()) {
-            Log.e(TAG, "BT not enabled. Cannot fetchUuidsWithSdp");
-            return false;
-        }
-        try {
-            return service.fetchRemoteUuidsWithAttribution(this, transport, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        }
-        return false;
-    }
-
-    /**
-     * Perform a service discovery on the remote device to get the SDP records associated
-     * with the specified UUID.
-     *
-     * <p>This API is asynchronous and {@link #ACTION_SDP_RECORD} intent is sent,
-     * with the SDP records found on the remote end. If there is an error
-     * in getting the SDP records or if the process takes a long time,
-     * {@link #ACTION_SDP_RECORD} intent is sent with an status value in
-     * {@link #EXTRA_SDP_SEARCH_STATUS} different from 0.
-     * Detailed status error codes can be found by members of the Bluetooth package in
-     * the AbstractionLayer class.
-     * <p>The SDP record data will be stored in the intent as {@link #EXTRA_SDP_RECORD}.
-     * The object type will match one of the SdpXxxRecord types, depending on the UUID searched
-     * for.
-     *
-     * @return False if the check fails, True if the process
-     *               of initiating an ACL connection to the remote device
-     *               was started.
-     */
-    /** @hide */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean sdpSearch(ParcelUuid uuid) {
-        final IBluetooth service = sService;
-        if (service == null) {
-            Log.e(TAG, "BT not enabled. Cannot query remote device sdp records");
-            return false;
-        }
-        try {
-            return service.sdpSearch(this, uuid, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        }
-        return false;
-    }
-
-    /**
-     * Set the pin during pairing when the pairing method is {@link #PAIRING_VARIANT_PIN}
-     *
-     * @return true pin has been set false for error
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean setPin(byte[] pin) {
-        final IBluetooth service = sService;
-        if (service == null) {
-            Log.e(TAG, "BT not enabled. Cannot set Remote Device pin");
-            return false;
-        }
-        try {
-            return service.setPin(this, true, pin.length, pin, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        }
-        return false;
-    }
-
-    /**
-     * Set the pin during pairing when the pairing method is {@link #PAIRING_VARIANT_PIN}
-     *
-     * @return true pin has been set false for error
-     * @hide
-     */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean setPin(@NonNull String pin) {
-        byte[] pinBytes = convertPinToBytes(pin);
-        if (pinBytes == null) {
-            return false;
-        }
-        return setPin(pinBytes);
-    }
-
-    /**
-     * Confirm passkey for {@link #PAIRING_VARIANT_PASSKEY_CONFIRMATION} pairing.
-     *
-     * @return true confirmation has been sent out false for error
-     */
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public boolean setPairingConfirmation(boolean confirm) {
-        final IBluetooth service = sService;
-        if (service == null) {
-            Log.e(TAG, "BT not enabled. Cannot set pairing confirmation");
-            return false;
-        }
-        try {
-            return service.setPairingConfirmation(this, confirm, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        }
-        return false;
-    }
-
-    /**
-     * Cancels pairing to this device
-     *
-     * @return true if pairing cancelled successfully, false otherwise
-     *
-     * @hide
-     */
-    @UnsupportedAppUsage
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean cancelPairing() {
-        final IBluetooth service = sService;
-        if (service == null) {
-            Log.e(TAG, "BT not enabled. Cannot cancel pairing");
-            return false;
-        }
-        try {
-            return service.cancelBondProcess(this, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        }
-        return false;
-    }
-
-    boolean isBluetoothEnabled() {
-        boolean ret = false;
-        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
-        if (adapter != null && adapter.isEnabled()) {
-            ret = true;
-        }
-        return ret;
-    }
-
-    /**
-     * Gets whether the phonebook access is allowed for this bluetooth device
-     *
-     * @return Whether the phonebook access is allowed to this device. Can be {@link
-     * #ACCESS_UNKNOWN}, {@link #ACCESS_ALLOWED} or {@link #ACCESS_REJECTED}.
-     * @hide
-     */
-    @UnsupportedAppUsage
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public @AccessPermission int getPhonebookAccessPermission() {
-        final IBluetooth service = sService;
-        if (service == null) {
-            return ACCESS_UNKNOWN;
-        }
-        try {
-            return service.getPhonebookAccessPermission(this, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        }
-        return ACCESS_UNKNOWN;
-    }
-
-    /**
-     * Sets whether the {@link BluetoothDevice} enters silence mode. Audio will not
-     * be routed to the {@link BluetoothDevice} if set to {@code true}.
-     *
-     * When the {@link BluetoothDevice} enters silence mode, and the {@link BluetoothDevice}
-     * is an active device (for A2DP or HFP), the active device for that profile
-     * will be set to null.
-     * If the {@link BluetoothDevice} exits silence mode while the A2DP or HFP
-     * active device is null, the {@link BluetoothDevice} will be set as the
-     * active device for that profile.
-     * If the {@link BluetoothDevice} is disconnected, it exits silence mode.
-     * If the {@link BluetoothDevice} is set as the active device for A2DP or
-     * HFP, while silence mode is enabled, then the device will exit silence mode.
-     * If the {@link BluetoothDevice} is in silence mode, AVRCP position change
-     * event and HFP AG indicators will be disabled.
-     * If the {@link BluetoothDevice} is not connected with A2DP or HFP, it cannot
-     * enter silence mode.
-     *
-     * @param silence true to enter silence mode, false to exit
-     * @return true on success, false on error.
-     * @throws IllegalStateException if Bluetooth is not turned ON.
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public boolean setSilenceMode(boolean silence) {
-        final IBluetooth service = sService;
-        if (service == null) {
-            throw new IllegalStateException("Bluetooth is not turned ON");
-        }
-        try {
-            return service.setSilenceMode(this, silence, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "setSilenceMode fail", e);
-            return false;
-        }
-    }
-
-    /**
-     * Check whether the {@link BluetoothDevice} is in silence mode
-     *
-     * @return true on device in silence mode, otherwise false.
-     * @throws IllegalStateException if Bluetooth is not turned ON.
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public boolean isInSilenceMode() {
-        final IBluetooth service = sService;
-        if (service == null) {
-            throw new IllegalStateException("Bluetooth is not turned ON");
-        }
-        try {
-            return service.getSilenceMode(this, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "isInSilenceMode fail", e);
-            return false;
-        }
-    }
-
-    /**
-     * Sets whether the phonebook access is allowed to this device.
-     *
-     * @param value Can be {@link #ACCESS_UNKNOWN}, {@link #ACCESS_ALLOWED} or {@link
-     * #ACCESS_REJECTED}.
-     * @return Whether the value has been successfully set.
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public boolean setPhonebookAccessPermission(@AccessPermission int value) {
-        final IBluetooth service = sService;
-        if (service == null) {
-            return false;
-        }
-        try {
-            return service.setPhonebookAccessPermission(this, value, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        }
-        return false;
-    }
-
-    /**
-     * Gets whether message access is allowed to this bluetooth device
-     *
-     * @return Whether the message access is allowed to this device.
-     * @hide
-     */
-    @UnsupportedAppUsage
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public @AccessPermission int getMessageAccessPermission() {
-        final IBluetooth service = sService;
-        if (service == null) {
-            return ACCESS_UNKNOWN;
-        }
-        try {
-            return service.getMessageAccessPermission(this, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        }
-        return ACCESS_UNKNOWN;
-    }
-
-    /**
-     * Sets whether the message access is allowed to this device.
-     *
-     * @param value Can be {@link #ACCESS_UNKNOWN} if the device is unbonded,
-     * {@link #ACCESS_ALLOWED} if the permission is being granted, or {@link #ACCESS_REJECTED} if
-     * the permission is not being granted.
-     * @return Whether the value has been successfully set.
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public boolean setMessageAccessPermission(@AccessPermission int value) {
-        // Validates param value is one of the accepted constants
-        if (value != ACCESS_ALLOWED && value != ACCESS_REJECTED && value != ACCESS_UNKNOWN) {
-            throw new IllegalArgumentException(value + "is not a valid AccessPermission value");
-        }
-        final IBluetooth service = sService;
-        if (service == null) {
-            return false;
-        }
-        try {
-            return service.setMessageAccessPermission(this, value, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        }
-        return false;
-    }
-
-    /**
-     * Gets whether sim access is allowed for this bluetooth device
-     *
-     * @return Whether the Sim access is allowed to this device.
-     * @hide
-     */
-    @SystemApi
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public @AccessPermission int getSimAccessPermission() {
-        final IBluetooth service = sService;
-        if (service == null) {
-            return ACCESS_UNKNOWN;
-        }
-        try {
-            return service.getSimAccessPermission(this, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        }
-        return ACCESS_UNKNOWN;
-    }
-
-    /**
-     * Sets whether the Sim access is allowed to this device.
-     *
-     * @param value Can be {@link #ACCESS_UNKNOWN} if the device is unbonded,
-     * {@link #ACCESS_ALLOWED} if the permission is being granted, or {@link #ACCESS_REJECTED} if
-     * the permission is not being granted.
-     * @return Whether the value has been successfully set.
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public boolean setSimAccessPermission(int value) {
-        final IBluetooth service = sService;
-        if (service == null) {
-            return false;
-        }
-        try {
-            return service.setSimAccessPermission(this, value, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        }
-        return false;
-    }
-
-    /**
-     * Create an RFCOMM {@link BluetoothSocket} ready to start a secure
-     * outgoing connection to this remote device on given channel.
-     * <p>The remote device will be authenticated and communication on this
-     * socket will be encrypted.
-     * <p> Use this socket only if an authenticated socket link is possible.
-     * Authentication refers to the authentication of the link key to
-     * prevent person-in-the-middle type of attacks.
-     * For example, for Bluetooth 2.1 devices, if any of the devices does not
-     * have an input and output capability or just has the ability to
-     * display a numeric key, a secure socket connection is not possible.
-     * In such a case, use {@link createInsecureRfcommSocket}.
-     * For more details, refer to the Security Model section 5.2 (vol 3) of
-     * Bluetooth Core Specification version 2.1 + EDR.
-     * <p>Use {@link BluetoothSocket#connect} to initiate the outgoing
-     * connection.
-     * <p>Valid RFCOMM channels are in range 1 to 30.
-     *
-     * @param channel RFCOMM channel to connect to
-     * @return a RFCOMM BluetoothServerSocket ready for an outgoing connection
-     * @throws IOException on error, for example Bluetooth not available, or insufficient
-     * permissions
-     * @hide
-     */
-    @UnsupportedAppUsage
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SuppressLint("AndroidFrameworkRequiresPermission")
-    public BluetoothSocket createRfcommSocket(int channel) throws IOException {
-        if (!isBluetoothEnabled()) {
-            Log.e(TAG, "Bluetooth is not enabled");
-            throw new IOException();
-        }
-        return new BluetoothSocket(BluetoothSocket.TYPE_RFCOMM, -1, true, true, this, channel,
-                null);
-    }
-
-    /**
-     * Create an L2cap {@link BluetoothSocket} ready to start a secure
-     * outgoing connection to this remote device on given channel.
-     * <p>The remote device will be authenticated and communication on this
-     * socket will be encrypted.
-     * <p> Use this socket only if an authenticated socket link is possible.
-     * Authentication refers to the authentication of the link key to
-     * prevent person-in-the-middle type of attacks.
-     * For example, for Bluetooth 2.1 devices, if any of the devices does not
-     * have an input and output capability or just has the ability to
-     * display a numeric key, a secure socket connection is not possible.
-     * In such a case, use {@link createInsecureRfcommSocket}.
-     * For more details, refer to the Security Model section 5.2 (vol 3) of
-     * Bluetooth Core Specification version 2.1 + EDR.
-     * <p>Use {@link BluetoothSocket#connect} to initiate the outgoing
-     * connection.
-     * <p>Valid L2CAP PSM channels are in range 1 to 2^16.
-     *
-     * @param channel L2cap PSM/channel to connect to
-     * @return a RFCOMM BluetoothServerSocket ready for an outgoing connection
-     * @throws IOException on error, for example Bluetooth not available, or insufficient
-     * permissions
-     * @hide
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SuppressLint("AndroidFrameworkRequiresPermission")
-    public BluetoothSocket createL2capSocket(int channel) throws IOException {
-        return new BluetoothSocket(BluetoothSocket.TYPE_L2CAP, -1, true, true, this, channel,
-                null);
-    }
-
-    /**
-     * Create an L2cap {@link BluetoothSocket} ready to start an insecure
-     * outgoing connection to this remote device on given channel.
-     * <p>The remote device will be not authenticated and communication on this
-     * socket will not be encrypted.
-     * <p>Use {@link BluetoothSocket#connect} to initiate the outgoing
-     * connection.
-     * <p>Valid L2CAP PSM channels are in range 1 to 2^16.
-     *
-     * @param channel L2cap PSM/channel to connect to
-     * @return a RFCOMM BluetoothServerSocket ready for an outgoing connection
-     * @throws IOException on error, for example Bluetooth not available, or insufficient
-     * permissions
-     * @hide
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SuppressLint("AndroidFrameworkRequiresPermission")
-    public BluetoothSocket createInsecureL2capSocket(int channel) throws IOException {
-        return new BluetoothSocket(BluetoothSocket.TYPE_L2CAP, -1, false, false, this, channel,
-                null);
-    }
-
-    /**
-     * Create an RFCOMM {@link BluetoothSocket} ready to start a secure
-     * outgoing connection to this remote device using SDP lookup of uuid.
-     * <p>This is designed to be used with {@link
-     * BluetoothAdapter#listenUsingRfcommWithServiceRecord} for peer-peer
-     * Bluetooth applications.
-     * <p>Use {@link BluetoothSocket#connect} to initiate the outgoing
-     * connection. This will also perform an SDP lookup of the given uuid to
-     * determine which channel to connect to.
-     * <p>The remote device will be authenticated and communication on this
-     * socket will be encrypted.
-     * <p> Use this socket only if an authenticated socket link is possible.
-     * Authentication refers to the authentication of the link key to
-     * prevent person-in-the-middle type of attacks.
-     * For example, for Bluetooth 2.1 devices, if any of the devices does not
-     * have an input and output capability or just has the ability to
-     * display a numeric key, a secure socket connection is not possible.
-     * In such a case, use {@link #createInsecureRfcommSocketToServiceRecord}.
-     * For more details, refer to the Security Model section 5.2 (vol 3) of
-     * Bluetooth Core Specification version 2.1 + EDR.
-     * <p>Hint: If you are connecting to a Bluetooth serial board then try
-     * using the well-known SPP UUID 00001101-0000-1000-8000-00805F9B34FB.
-     * However if you are connecting to an Android peer then please generate
-     * your own unique UUID.
-     *
-     * @param uuid service record uuid to lookup RFCOMM channel
-     * @return a RFCOMM BluetoothServerSocket ready for an outgoing connection
-     * @throws IOException on error, for example Bluetooth not available, or insufficient
-     * permissions
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SuppressLint("AndroidFrameworkRequiresPermission")
-    public BluetoothSocket createRfcommSocketToServiceRecord(UUID uuid) throws IOException {
-        if (!isBluetoothEnabled()) {
-            Log.e(TAG, "Bluetooth is not enabled");
-            throw new IOException();
-        }
-
-        return new BluetoothSocket(BluetoothSocket.TYPE_RFCOMM, -1, true, true, this, -1,
-                new ParcelUuid(uuid));
-    }
-
-    /**
-     * Create an RFCOMM {@link BluetoothSocket} socket ready to start an insecure
-     * outgoing connection to this remote device using SDP lookup of uuid.
-     * <p> The communication channel will not have an authenticated link key
-     * i.e it will be subject to person-in-the-middle attacks. For Bluetooth 2.1
-     * devices, the link key will be encrypted, as encryption is mandatory.
-     * For legacy devices (pre Bluetooth 2.1 devices) the link key will
-     * be not be encrypted. Use {@link #createRfcommSocketToServiceRecord} if an
-     * encrypted and authenticated communication channel is desired.
-     * <p>This is designed to be used with {@link
-     * BluetoothAdapter#listenUsingInsecureRfcommWithServiceRecord} for peer-peer
-     * Bluetooth applications.
-     * <p>Use {@link BluetoothSocket#connect} to initiate the outgoing
-     * connection. This will also perform an SDP lookup of the given uuid to
-     * determine which channel to connect to.
-     * <p>The remote device will be authenticated and communication on this
-     * socket will be encrypted.
-     * <p>Hint: If you are connecting to a Bluetooth serial board then try
-     * using the well-known SPP UUID 00001101-0000-1000-8000-00805F9B34FB.
-     * However if you are connecting to an Android peer then please generate
-     * your own unique UUID.
-     *
-     * @param uuid service record uuid to lookup RFCOMM channel
-     * @return a RFCOMM BluetoothServerSocket ready for an outgoing connection
-     * @throws IOException on error, for example Bluetooth not available, or insufficient
-     * permissions
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SuppressLint("AndroidFrameworkRequiresPermission")
-    public BluetoothSocket createInsecureRfcommSocketToServiceRecord(UUID uuid) throws IOException {
-        if (!isBluetoothEnabled()) {
-            Log.e(TAG, "Bluetooth is not enabled");
-            throw new IOException();
-        }
-        return new BluetoothSocket(BluetoothSocket.TYPE_RFCOMM, -1, false, false, this, -1,
-                new ParcelUuid(uuid));
-    }
-
-    /**
-     * Construct an insecure RFCOMM socket ready to start an outgoing
-     * connection.
-     * Call #connect on the returned #BluetoothSocket to begin the connection.
-     * The remote device will not be authenticated and communication on this
-     * socket will not be encrypted.
-     *
-     * @param port remote port
-     * @return An RFCOMM BluetoothSocket
-     * @throws IOException On error, for example Bluetooth not available, or insufficient
-     * permissions.
-     * @hide
-     */
-    @UnsupportedAppUsage(publicAlternatives = "Use "
-            + "{@link #createInsecureRfcommSocketToServiceRecord} instead.")
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SuppressLint("AndroidFrameworkRequiresPermission")
-    public BluetoothSocket createInsecureRfcommSocket(int port) throws IOException {
-        if (!isBluetoothEnabled()) {
-            Log.e(TAG, "Bluetooth is not enabled");
-            throw new IOException();
-        }
-        return new BluetoothSocket(BluetoothSocket.TYPE_RFCOMM, -1, false, false, this, port,
-                null);
-    }
-
-    /**
-     * Construct a SCO socket ready to start an outgoing connection.
-     * Call #connect on the returned #BluetoothSocket to begin the connection.
-     *
-     * @return a SCO BluetoothSocket
-     * @throws IOException on error, for example Bluetooth not available, or insufficient
-     * permissions.
-     * @hide
-     */
-    @UnsupportedAppUsage
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SuppressLint("AndroidFrameworkRequiresPermission")
-    public BluetoothSocket createScoSocket() throws IOException {
-        if (!isBluetoothEnabled()) {
-            Log.e(TAG, "Bluetooth is not enabled");
-            throw new IOException();
-        }
-        return new BluetoothSocket(BluetoothSocket.TYPE_SCO, -1, true, true, this, -1, null);
-    }
-
-    /**
-     * Check that a pin is valid and convert to byte array.
-     *
-     * Bluetooth pin's are 1 to 16 bytes of UTF-8 characters.
-     *
-     * @param pin pin as java String
-     * @return the pin code as a UTF-8 byte array, or null if it is an invalid Bluetooth pin.
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public static byte[] convertPinToBytes(String pin) {
-        if (pin == null) {
-            return null;
-        }
-        byte[] pinBytes;
-        try {
-            pinBytes = pin.getBytes("UTF-8");
-        } catch (UnsupportedEncodingException uee) {
-            Log.e(TAG, "UTF-8 not supported?!?");  // this should not happen
-            return null;
-        }
-        if (pinBytes.length <= 0 || pinBytes.length > 16) {
-            return null;
-        }
-        return pinBytes;
-    }
-
-    /**
-     * Connect to GATT Server hosted by this device. Caller acts as GATT client.
-     * The callback is used to deliver results to Caller, such as connection status as well
-     * as any further GATT client operations.
-     * The method returns a BluetoothGatt instance. You can use BluetoothGatt to conduct
-     * GATT client operations.
-     *
-     * @param callback GATT callback handler that will receive asynchronous callbacks.
-     * @param autoConnect Whether to directly connect to the remote device (false) or to
-     * automatically connect as soon as the remote device becomes available (true).
-     * @throws IllegalArgumentException if callback is null
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public BluetoothGatt connectGatt(Context context, boolean autoConnect,
-            BluetoothGattCallback callback) {
-        return (connectGatt(context, autoConnect, callback, TRANSPORT_AUTO));
-    }
-
-    /**
-     * Connect to GATT Server hosted by this device. Caller acts as GATT client.
-     * The callback is used to deliver results to Caller, such as connection status as well
-     * as any further GATT client operations.
-     * The method returns a BluetoothGatt instance. You can use BluetoothGatt to conduct
-     * GATT client operations.
-     *
-     * @param callback GATT callback handler that will receive asynchronous callbacks.
-     * @param autoConnect Whether to directly connect to the remote device (false) or to
-     * automatically connect as soon as the remote device becomes available (true).
-     * @param transport preferred transport for GATT connections to remote dual-mode devices {@link
-     * BluetoothDevice#TRANSPORT_AUTO} or {@link BluetoothDevice#TRANSPORT_BREDR} or {@link
-     * BluetoothDevice#TRANSPORT_LE}
-     * @throws IllegalArgumentException if callback is null
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public BluetoothGatt connectGatt(Context context, boolean autoConnect,
-            BluetoothGattCallback callback, int transport) {
-        return (connectGatt(context, autoConnect, callback, transport, PHY_LE_1M_MASK));
-    }
-
-    /**
-     * Connect to GATT Server hosted by this device. Caller acts as GATT client.
-     * The callback is used to deliver results to Caller, such as connection status as well
-     * as any further GATT client operations.
-     * The method returns a BluetoothGatt instance. You can use BluetoothGatt to conduct
-     * GATT client operations.
-     *
-     * @param callback GATT callback handler that will receive asynchronous callbacks.
-     * @param autoConnect Whether to directly connect to the remote device (false) or to
-     * automatically connect as soon as the remote device becomes available (true).
-     * @param transport preferred transport for GATT connections to remote dual-mode devices {@link
-     * BluetoothDevice#TRANSPORT_AUTO} or {@link BluetoothDevice#TRANSPORT_BREDR} or {@link
-     * BluetoothDevice#TRANSPORT_LE}
-     * @param phy preferred PHY for connections to remote LE device. Bitwise OR of any of {@link
-     * BluetoothDevice#PHY_LE_1M_MASK}, {@link BluetoothDevice#PHY_LE_2M_MASK}, and {@link
-     * BluetoothDevice#PHY_LE_CODED_MASK}. This option does not take effect if {@code autoConnect}
-     * is set to true.
-     * @throws NullPointerException if callback is null
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public BluetoothGatt connectGatt(Context context, boolean autoConnect,
-            BluetoothGattCallback callback, int transport, int phy) {
-        return connectGatt(context, autoConnect, callback, transport, phy, null);
-    }
-
-    /**
-     * Connect to GATT Server hosted by this device. Caller acts as GATT client.
-     * The callback is used to deliver results to Caller, such as connection status as well
-     * as any further GATT client operations.
-     * The method returns a BluetoothGatt instance. You can use BluetoothGatt to conduct
-     * GATT client operations.
-     *
-     * @param callback GATT callback handler that will receive asynchronous callbacks.
-     * @param autoConnect Whether to directly connect to the remote device (false) or to
-     * automatically connect as soon as the remote device becomes available (true).
-     * @param transport preferred transport for GATT connections to remote dual-mode devices {@link
-     * BluetoothDevice#TRANSPORT_AUTO} or {@link BluetoothDevice#TRANSPORT_BREDR} or {@link
-     * BluetoothDevice#TRANSPORT_LE}
-     * @param phy preferred PHY for connections to remote LE device. Bitwise OR of any of {@link
-     * BluetoothDevice#PHY_LE_1M_MASK}, {@link BluetoothDevice#PHY_LE_2M_MASK}, an d{@link
-     * BluetoothDevice#PHY_LE_CODED_MASK}. This option does not take effect if {@code autoConnect}
-     * is set to true.
-     * @param handler The handler to use for the callback. If {@code null}, callbacks will happen on
-     * an un-specified background thread.
-     * @throws NullPointerException if callback is null
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public BluetoothGatt connectGatt(Context context, boolean autoConnect,
-            BluetoothGattCallback callback, int transport, int phy,
-            Handler handler) {
-        return connectGatt(context, autoConnect, callback, transport, false, phy, handler);
-    }
-
-    /**
-     * Connect to GATT Server hosted by this device. Caller acts as GATT client.
-     * The callback is used to deliver results to Caller, such as connection status as well
-     * as any further GATT client operations.
-     * The method returns a BluetoothGatt instance. You can use BluetoothGatt to conduct
-     * GATT client operations.
-     *
-     * @param callback GATT callback handler that will receive asynchronous callbacks.
-     * @param autoConnect Whether to directly connect to the remote device (false) or to
-     * automatically connect as soon as the remote device becomes available (true).
-     * @param transport preferred transport for GATT connections to remote dual-mode devices {@link
-     * BluetoothDevice#TRANSPORT_AUTO} or {@link BluetoothDevice#TRANSPORT_BREDR} or {@link
-     * BluetoothDevice#TRANSPORT_LE}
-     * @param opportunistic Whether this GATT client is opportunistic. An opportunistic GATT client
-     * does not hold a GATT connection. It automatically disconnects when no other GATT connections
-     * are active for the remote device.
-     * @param phy preferred PHY for connections to remote LE device. Bitwise OR of any of {@link
-     * BluetoothDevice#PHY_LE_1M_MASK}, {@link BluetoothDevice#PHY_LE_2M_MASK}, an d{@link
-     * BluetoothDevice#PHY_LE_CODED_MASK}. This option does not take effect if {@code autoConnect}
-     * is set to true.
-     * @param handler The handler to use for the callback. If {@code null}, callbacks will happen on
-     * an un-specified background thread.
-     * @return A BluetoothGatt instance. You can use BluetoothGatt to conduct GATT client
-     * operations.
-     * @hide
-     */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public BluetoothGatt connectGatt(Context context, boolean autoConnect,
-            BluetoothGattCallback callback, int transport,
-            boolean opportunistic, int phy, Handler handler) {
-        if (callback == null) {
-            throw new NullPointerException("callback is null");
-        }
-
-        // TODO(Bluetooth) check whether platform support BLE
-        //     Do the check here or in GattServer?
-        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
-        IBluetoothManager managerService = adapter.getBluetoothManager();
-        try {
-            IBluetoothGatt iGatt = managerService.getBluetoothGatt();
-            if (iGatt == null) {
-                // BLE is not supported
-                return null;
-            }
-            BluetoothGatt gatt = new BluetoothGatt(
-                    iGatt, this, transport, opportunistic, phy, mAttributionSource);
-            gatt.connect(autoConnect, callback, handler);
-            return gatt;
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        }
-        return null;
-    }
-
-    /**
-     * Create a Bluetooth L2CAP Connection-oriented Channel (CoC) {@link BluetoothSocket} that can
-     * be used to start a secure outgoing connection to the remote device with the same dynamic
-     * protocol/service multiplexer (PSM) value. The supported Bluetooth transport is LE only.
-     * <p>This is designed to be used with {@link BluetoothAdapter#listenUsingL2capChannel()} for
-     * peer-peer Bluetooth applications.
-     * <p>Use {@link BluetoothSocket#connect} to initiate the outgoing connection.
-     * <p>Application using this API is responsible for obtaining PSM value from remote device.
-     * <p>The remote device will be authenticated and communication on this socket will be
-     * encrypted.
-     * <p> Use this socket if an authenticated socket link is possible. Authentication refers
-     * to the authentication of the link key to prevent person-in-the-middle type of attacks.
-     *
-     * @param psm dynamic PSM value from remote device
-     * @return a CoC #BluetoothSocket ready for an outgoing connection
-     * @throws IOException on error, for example Bluetooth not available, or insufficient
-     * permissions
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SuppressLint("AndroidFrameworkRequiresPermission")
-    public @NonNull BluetoothSocket createL2capChannel(int psm) throws IOException {
-        if (!isBluetoothEnabled()) {
-            Log.e(TAG, "createL2capChannel: Bluetooth is not enabled");
-            throw new IOException();
-        }
-        if (DBG) Log.d(TAG, "createL2capChannel: psm=" + psm);
-        return new BluetoothSocket(BluetoothSocket.TYPE_L2CAP_LE, -1, true, true, this, psm,
-                null);
-    }
-
-    /**
-     * Create a Bluetooth L2CAP Connection-oriented Channel (CoC) {@link BluetoothSocket} that can
-     * be used to start a secure outgoing connection to the remote device with the same dynamic
-     * protocol/service multiplexer (PSM) value. The supported Bluetooth transport is LE only.
-     * <p>This is designed to be used with {@link
-     * BluetoothAdapter#listenUsingInsecureL2capChannel()} for peer-peer Bluetooth applications.
-     * <p>Use {@link BluetoothSocket#connect} to initiate the outgoing connection.
-     * <p>Application using this API is responsible for obtaining PSM value from remote device.
-     * <p> The communication channel may not have an authenticated link key, i.e. it may be subject
-     * to person-in-the-middle attacks. Use {@link #createL2capChannel(int)} if an encrypted and
-     * authenticated communication channel is possible.
-     *
-     * @param psm dynamic PSM value from remote device
-     * @return a CoC #BluetoothSocket ready for an outgoing connection
-     * @throws IOException on error, for example Bluetooth not available, or insufficient
-     * permissions
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SuppressLint("AndroidFrameworkRequiresPermission")
-    public @NonNull BluetoothSocket createInsecureL2capChannel(int psm) throws IOException {
-        if (!isBluetoothEnabled()) {
-            Log.e(TAG, "createInsecureL2capChannel: Bluetooth is not enabled");
-            throw new IOException();
-        }
-        if (DBG) {
-            Log.d(TAG, "createInsecureL2capChannel: psm=" + psm);
-        }
-        return new BluetoothSocket(BluetoothSocket.TYPE_L2CAP_LE, -1, false, false, this, psm,
-                null);
-    }
-
-    /**
-     * Set a keyed metadata of this {@link BluetoothDevice} to a
-     * {@link String} value.
-     * Only bonded devices's metadata will be persisted across Bluetooth
-     * restart.
-     * Metadata will be removed when the device's bond state is moved to
-     * {@link #BOND_NONE}.
-     *
-     * @param key must be within the list of BluetoothDevice.METADATA_*
-     * @param value a byte array data to set for key. Must be less than
-     * {@link BluetoothAdapter#METADATA_MAX_LENGTH} characters in length
-     * @return true on success, false on error
-     * @hide
-    */
-    @SystemApi
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public boolean setMetadata(@MetadataKey int key, @NonNull byte[] value) {
-        final IBluetooth service = sService;
-        if (service == null) {
-            Log.e(TAG, "Bluetooth is not enabled. Cannot set metadata");
-            return false;
-        }
-        if (value.length > METADATA_MAX_LENGTH) {
-            throw new IllegalArgumentException("value length is " + value.length
-                    + ", should not over " + METADATA_MAX_LENGTH);
-        }
-        try {
-            return service.setMetadata(this, key, value, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "setMetadata fail", e);
-            return false;
-        }
-    }
-
-    /**
-     * Get a keyed metadata for this {@link BluetoothDevice} as {@link String}
-     *
-     * @param key must be within the list of BluetoothDevice.METADATA_*
-     * @return Metadata of the key as byte array, null on error or not found
-     * @hide
-     */
-    @SystemApi
-    @Nullable
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public byte[] getMetadata(@MetadataKey int key) {
-        final IBluetooth service = sService;
-        if (service == null) {
-            Log.e(TAG, "Bluetooth is not enabled. Cannot get metadata");
-            return null;
-        }
-        try {
-            return service.getMetadata(this, key, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "getMetadata fail", e);
-            return null;
-        }
-    }
-
-    /**
-     * Get the maxinum metadata key ID.
-     *
-     * @return the last supported metadata key
-     * @hide
-     */
-    public static @MetadataKey int getMaxMetadataKey() {
-        return METADATA_UNTETHERED_CASE_LOW_BATTERY_THRESHOLD;
-    }
-}
diff --git a/core/java/android/bluetooth/BluetoothDevicePicker.java b/core/java/android/bluetooth/BluetoothDevicePicker.java
deleted file mode 100644
index 26e4657..0000000
--- a/core/java/android/bluetooth/BluetoothDevicePicker.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2009 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.bluetooth;
-
-import android.annotation.RequiresPermission;
-import android.annotation.SdkConstant;
-import android.annotation.SdkConstant.SdkConstantType;
-import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
-
-/**
- * A helper to show a system "Device Picker" activity to the user.
- *
- * @hide
- */
-public interface BluetoothDevicePicker {
-    public static final String EXTRA_NEED_AUTH =
-            "android.bluetooth.devicepicker.extra.NEED_AUTH";
-    public static final String EXTRA_FILTER_TYPE =
-            "android.bluetooth.devicepicker.extra.FILTER_TYPE";
-    public static final String EXTRA_LAUNCH_PACKAGE =
-            "android.bluetooth.devicepicker.extra.LAUNCH_PACKAGE";
-    public static final String EXTRA_LAUNCH_CLASS =
-            "android.bluetooth.devicepicker.extra.DEVICE_PICKER_LAUNCH_CLASS";
-
-    /**
-     * Broadcast when one BT device is selected from BT device picker screen.
-     * Selected {@link BluetoothDevice} is returned in extra data named
-     * {@link BluetoothDevice#EXTRA_DEVICE}.
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_DEVICE_SELECTED =
-            "android.bluetooth.devicepicker.action.DEVICE_SELECTED";
-
-    /**
-     * Broadcast when someone want to select one BT device from devices list.
-     * This intent contains below extra data:
-     * - {@link #EXTRA_NEED_AUTH} (boolean): if need authentication
-     * - {@link #EXTRA_FILTER_TYPE} (int): what kinds of device should be
-     * listed
-     * - {@link #EXTRA_LAUNCH_PACKAGE} (string): where(which package) this
-     * intent come from
-     * - {@link #EXTRA_LAUNCH_CLASS} (string): where(which class) this intent
-     * come from
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_LAUNCH =
-            "android.bluetooth.devicepicker.action.LAUNCH";
-
-    /** Ask device picker to show all kinds of BT devices */
-    public static final int FILTER_TYPE_ALL = 0;
-    /** Ask device picker to show BT devices that support AUDIO profiles */
-    public static final int FILTER_TYPE_AUDIO = 1;
-    /** Ask device picker to show BT devices that support Object Transfer */
-    public static final int FILTER_TYPE_TRANSFER = 2;
-    /**
-     * Ask device picker to show BT devices that support
-     * Personal Area Networking User (PANU) profile
-     */
-    public static final int FILTER_TYPE_PANU = 3;
-    /** Ask device picker to show BT devices that support Network Access Point (NAP) profile */
-    public static final int FILTER_TYPE_NAP = 4;
-}
diff --git a/core/java/android/bluetooth/BluetoothGatt.java b/core/java/android/bluetooth/BluetoothGatt.java
deleted file mode 100644
index b531829..0000000
--- a/core/java/android/bluetooth/BluetoothGatt.java
+++ /dev/null
@@ -1,1848 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.RequiresNoPermission;
-import android.annotation.RequiresPermission;
-import android.annotation.SuppressLint;
-import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
-import android.bluetooth.annotations.RequiresLegacyBluetoothPermission;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.content.AttributionSource;
-import android.os.Build;
-import android.os.Handler;
-import android.os.ParcelUuid;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.UUID;
-
-/**
- * Public API for the Bluetooth GATT Profile.
- *
- * <p>This class provides Bluetooth GATT functionality to enable communication
- * with Bluetooth Smart or Smart Ready devices.
- *
- * <p>To connect to a remote peripheral device, create a {@link BluetoothGattCallback}
- * and call {@link BluetoothDevice#connectGatt} to get a instance of this class.
- * GATT capable devices can be discovered using the Bluetooth device discovery or BLE
- * scan process.
- */
-public final class BluetoothGatt implements BluetoothProfile {
-    private static final String TAG = "BluetoothGatt";
-    private static final boolean DBG = true;
-    private static final boolean VDBG = false;
-
-    @UnsupportedAppUsage
-    private IBluetoothGatt mService;
-    @UnsupportedAppUsage
-    private volatile BluetoothGattCallback mCallback;
-    private Handler mHandler;
-    @UnsupportedAppUsage
-    private int mClientIf;
-    private BluetoothDevice mDevice;
-    @UnsupportedAppUsage
-    private boolean mAutoConnect;
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
-    private int mAuthRetryState;
-    private int mConnState;
-    private final Object mStateLock = new Object();
-    private final Object mDeviceBusyLock = new Object();
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    private Boolean mDeviceBusy = false;
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    private int mTransport;
-    private int mPhy;
-    private boolean mOpportunistic;
-    private final AttributionSource mAttributionSource;
-
-    private static final int AUTH_RETRY_STATE_IDLE = 0;
-    private static final int AUTH_RETRY_STATE_NO_MITM = 1;
-    private static final int AUTH_RETRY_STATE_MITM = 2;
-
-    private static final int CONN_STATE_IDLE = 0;
-    private static final int CONN_STATE_CONNECTING = 1;
-    private static final int CONN_STATE_CONNECTED = 2;
-    private static final int CONN_STATE_DISCONNECTING = 3;
-    private static final int CONN_STATE_CLOSED = 4;
-
-    private static final int WRITE_CHARACTERISTIC_MAX_RETRIES = 5;
-    private static final int WRITE_CHARACTERISTIC_TIME_TO_WAIT = 10; // milliseconds
-
-    private List<BluetoothGattService> mServices;
-
-    /** A GATT operation completed successfully */
-    public static final int GATT_SUCCESS = 0;
-
-    /** GATT read operation is not permitted */
-    public static final int GATT_READ_NOT_PERMITTED = 0x2;
-
-    /** GATT write operation is not permitted */
-    public static final int GATT_WRITE_NOT_PERMITTED = 0x3;
-
-    /** Insufficient authentication for a given operation */
-    public static final int GATT_INSUFFICIENT_AUTHENTICATION = 0x5;
-
-    /** The given request is not supported */
-    public static final int GATT_REQUEST_NOT_SUPPORTED = 0x6;
-
-    /** Insufficient encryption for a given operation */
-    public static final int GATT_INSUFFICIENT_ENCRYPTION = 0xf;
-
-    /** A read or write operation was requested with an invalid offset */
-    public static final int GATT_INVALID_OFFSET = 0x7;
-
-    /** Insufficient authorization for a given operation */
-    public static final int GATT_INSUFFICIENT_AUTHORIZATION = 0x8;
-
-    /** A write operation exceeds the maximum length of the attribute */
-    public static final int GATT_INVALID_ATTRIBUTE_LENGTH = 0xd;
-
-    /** A remote device connection is congested. */
-    public static final int GATT_CONNECTION_CONGESTED = 0x8f;
-
-    /** A GATT operation failed, errors other than the above */
-    public static final int GATT_FAILURE = 0x101;
-
-    /**
-     * Connection parameter update - Use the connection parameters recommended by the
-     * Bluetooth SIG. This is the default value if no connection parameter update
-     * is requested.
-     */
-    public static final int CONNECTION_PRIORITY_BALANCED = 0;
-
-    /**
-     * Connection parameter update - Request a high priority, low latency connection.
-     * An application should only request high priority connection parameters to transfer large
-     * amounts of data over LE quickly. Once the transfer is complete, the application should
-     * request {@link BluetoothGatt#CONNECTION_PRIORITY_BALANCED} connection parameters to reduce
-     * energy use.
-     */
-    public static final int CONNECTION_PRIORITY_HIGH = 1;
-
-    /** Connection parameter update - Request low power, reduced data rate connection parameters. */
-    public static final int CONNECTION_PRIORITY_LOW_POWER = 2;
-
-    /**
-     * No authentication required.
-     *
-     * @hide
-     */
-    /*package*/ static final int AUTHENTICATION_NONE = 0;
-
-    /**
-     * Authentication requested; no person-in-the-middle protection required.
-     *
-     * @hide
-     */
-    /*package*/ static final int AUTHENTICATION_NO_MITM = 1;
-
-    /**
-     * Authentication with person-in-the-middle protection requested.
-     *
-     * @hide
-     */
-    /*package*/ static final int AUTHENTICATION_MITM = 2;
-
-    /**
-     * Bluetooth GATT callbacks. Overrides the default BluetoothGattCallback implementation.
-     */
-    @SuppressLint("AndroidFrameworkBluetoothPermission")
-    private final IBluetoothGattCallback mBluetoothGattCallback =
-            new IBluetoothGattCallback.Stub() {
-                /**
-                 * Application interface registered - app is ready to go
-                 * @hide
-                 */
-                @Override
-                @SuppressLint("AndroidFrameworkRequiresPermission")
-                public void onClientRegistered(int status, int clientIf) {
-                    if (DBG) {
-                        Log.d(TAG, "onClientRegistered() - status=" + status
-                                + " clientIf=" + clientIf);
-                    }
-                    if (VDBG) {
-                        synchronized (mStateLock) {
-                            if (mConnState != CONN_STATE_CONNECTING) {
-                                Log.e(TAG, "Bad connection state: " + mConnState);
-                            }
-                        }
-                    }
-                    mClientIf = clientIf;
-                    if (status != GATT_SUCCESS) {
-                        runOrQueueCallback(new Runnable() {
-                            @Override
-                            public void run() {
-                                final BluetoothGattCallback callback = mCallback;
-                                if (callback != null) {
-                                    callback.onConnectionStateChange(BluetoothGatt.this,
-                                            GATT_FAILURE,
-                                            BluetoothProfile.STATE_DISCONNECTED);
-                                }
-                            }
-                        });
-
-                        synchronized (mStateLock) {
-                            mConnState = CONN_STATE_IDLE;
-                        }
-                        return;
-                    }
-                    try {
-                        mService.clientConnect(mClientIf, mDevice.getAddress(),
-                                !mAutoConnect, mTransport, mOpportunistic,
-                                mPhy, mAttributionSource); // autoConnect is inverse of "isDirect"
-                    } catch (RemoteException e) {
-                        Log.e(TAG, "", e);
-                    }
-                }
-
-                /**
-                 * Phy update callback
-                 * @hide
-                 */
-                @Override
-                public void onPhyUpdate(String address, int txPhy, int rxPhy, int status) {
-                    if (DBG) {
-                        Log.d(TAG, "onPhyUpdate() - status=" + status
-                                + " address=" + address + " txPhy=" + txPhy + " rxPhy=" + rxPhy);
-                    }
-                    if (!address.equals(mDevice.getAddress())) {
-                        return;
-                    }
-
-                    runOrQueueCallback(new Runnable() {
-                        @Override
-                        public void run() {
-                            final BluetoothGattCallback callback = mCallback;
-                            if (callback != null) {
-                                callback.onPhyUpdate(BluetoothGatt.this, txPhy, rxPhy, status);
-                            }
-                        }
-                    });
-                }
-
-                /**
-                 * Phy read callback
-                 * @hide
-                 */
-                @Override
-                public void onPhyRead(String address, int txPhy, int rxPhy, int status) {
-                    if (DBG) {
-                        Log.d(TAG, "onPhyRead() - status=" + status
-                                + " address=" + address + " txPhy=" + txPhy + " rxPhy=" + rxPhy);
-                    }
-                    if (!address.equals(mDevice.getAddress())) {
-                        return;
-                    }
-
-                    runOrQueueCallback(new Runnable() {
-                        @Override
-                        public void run() {
-                            final BluetoothGattCallback callback = mCallback;
-                            if (callback != null) {
-                                callback.onPhyRead(BluetoothGatt.this, txPhy, rxPhy, status);
-                            }
-                        }
-                    });
-                }
-
-                /**
-                 * Client connection state changed
-                 * @hide
-                 */
-                @Override
-                public void onClientConnectionState(int status, int clientIf,
-                        boolean connected, String address) {
-                    if (DBG) {
-                        Log.d(TAG, "onClientConnectionState() - status=" + status
-                                + " clientIf=" + clientIf + " device=" + address);
-                    }
-                    if (!address.equals(mDevice.getAddress())) {
-                        return;
-                    }
-                    int profileState = connected ? BluetoothProfile.STATE_CONNECTED :
-                            BluetoothProfile.STATE_DISCONNECTED;
-
-                    runOrQueueCallback(new Runnable() {
-                        @Override
-                        public void run() {
-                            final BluetoothGattCallback callback = mCallback;
-                            if (callback != null) {
-                                callback.onConnectionStateChange(BluetoothGatt.this, status,
-                                        profileState);
-                            }
-                        }
-                    });
-
-                    synchronized (mStateLock) {
-                        if (connected) {
-                            mConnState = CONN_STATE_CONNECTED;
-                        } else {
-                            mConnState = CONN_STATE_IDLE;
-                        }
-                    }
-
-                    synchronized (mDeviceBusyLock) {
-                        mDeviceBusy = false;
-                    }
-                }
-
-                /**
-                 * Remote search has been completed.
-                 * The internal object structure should now reflect the state
-                 * of the remote device database. Let the application know that
-                 * we are done at this point.
-                 * @hide
-                 */
-                @Override
-                public void onSearchComplete(String address, List<BluetoothGattService> services,
-                        int status) {
-                    if (DBG) {
-                        Log.d(TAG,
-                                "onSearchComplete() = Device=" + address + " Status=" + status);
-                    }
-                    if (!address.equals(mDevice.getAddress())) {
-                        return;
-                    }
-
-                    for (BluetoothGattService s : services) {
-                        //services we receive don't have device set properly.
-                        s.setDevice(mDevice);
-                    }
-
-                    mServices.addAll(services);
-
-                    // Fix references to included services, as they doesn't point to right objects.
-                    for (BluetoothGattService fixedService : mServices) {
-                        ArrayList<BluetoothGattService> includedServices =
-                                new ArrayList(fixedService.getIncludedServices());
-                        fixedService.getIncludedServices().clear();
-
-                        for (BluetoothGattService brokenRef : includedServices) {
-                            BluetoothGattService includedService = getService(mDevice,
-                                    brokenRef.getUuid(), brokenRef.getInstanceId());
-                            if (includedService != null) {
-                                fixedService.addIncludedService(includedService);
-                            } else {
-                                Log.e(TAG, "Broken GATT database: can't find included service.");
-                            }
-                        }
-                    }
-
-                    runOrQueueCallback(new Runnable() {
-                        @Override
-                        public void run() {
-                            final BluetoothGattCallback callback = mCallback;
-                            if (callback != null) {
-                                callback.onServicesDiscovered(BluetoothGatt.this, status);
-                            }
-                        }
-                    });
-                }
-
-                /**
-                 * Remote characteristic has been read.
-                 * Updates the internal value.
-                 * @hide
-                 */
-                @Override
-                @SuppressLint("AndroidFrameworkRequiresPermission")
-                public void onCharacteristicRead(String address, int status, int handle,
-                        byte[] value) {
-                    if (VDBG) {
-                        Log.d(TAG, "onCharacteristicRead() - Device=" + address
-                                + " handle=" + handle + " Status=" + status);
-                    }
-
-                    if (!address.equals(mDevice.getAddress())) {
-                        return;
-                    }
-
-                    synchronized (mDeviceBusyLock) {
-                        mDeviceBusy = false;
-                    }
-
-                    if ((status == GATT_INSUFFICIENT_AUTHENTICATION
-                            || status == GATT_INSUFFICIENT_ENCRYPTION)
-                            && (mAuthRetryState != AUTH_RETRY_STATE_MITM)) {
-                        try {
-                            final int authReq = (mAuthRetryState == AUTH_RETRY_STATE_IDLE)
-                                    ? AUTHENTICATION_NO_MITM : AUTHENTICATION_MITM;
-                            mService.readCharacteristic(
-                                    mClientIf, address, handle, authReq, mAttributionSource);
-                            mAuthRetryState++;
-                            return;
-                        } catch (RemoteException e) {
-                            Log.e(TAG, "", e);
-                        }
-                    }
-
-                    mAuthRetryState = AUTH_RETRY_STATE_IDLE;
-
-                    BluetoothGattCharacteristic characteristic = getCharacteristicById(mDevice,
-                            handle);
-                    if (characteristic == null) {
-                        Log.w(TAG, "onCharacteristicRead() failed to find characteristic!");
-                        return;
-                    }
-
-                    runOrQueueCallback(new Runnable() {
-                        @Override
-                        public void run() {
-                            final BluetoothGattCallback callback = mCallback;
-                            if (callback != null) {
-                                if (status == 0) characteristic.setValue(value);
-                                callback.onCharacteristicRead(BluetoothGatt.this, characteristic,
-                                        value, status);
-                                // Keep calling deprecated callback to maintain app compatibility
-                                callback.onCharacteristicRead(BluetoothGatt.this, characteristic,
-                                        status);
-                            }
-                        }
-                    });
-                }
-
-                /**
-                 * Characteristic has been written to the remote device.
-                 * Let the app know how we did...
-                 * @hide
-                 */
-                @Override
-                @SuppressLint("AndroidFrameworkRequiresPermission")
-                public void onCharacteristicWrite(String address, int status, int handle,
-                        byte[] value) {
-                    if (VDBG) {
-                        Log.d(TAG, "onCharacteristicWrite() - Device=" + address
-                                + " handle=" + handle + " Status=" + status);
-                    }
-
-                    if (!address.equals(mDevice.getAddress())) {
-                        return;
-                    }
-
-                    synchronized (mDeviceBusyLock) {
-                        mDeviceBusy = false;
-                    }
-
-                    BluetoothGattCharacteristic characteristic = getCharacteristicById(mDevice,
-                            handle);
-                    if (characteristic == null) return;
-
-                    if ((status == GATT_INSUFFICIENT_AUTHENTICATION
-                            || status == GATT_INSUFFICIENT_ENCRYPTION)
-                            && (mAuthRetryState != AUTH_RETRY_STATE_MITM)) {
-                        try {
-                            final int authReq = (mAuthRetryState == AUTH_RETRY_STATE_IDLE)
-                                    ? AUTHENTICATION_NO_MITM : AUTHENTICATION_MITM;
-                            int requestStatus = BluetoothStatusCodes.ERROR_UNKNOWN;
-                            for (int i = 0; i < WRITE_CHARACTERISTIC_MAX_RETRIES; i++) {
-                                requestStatus =  mService.writeCharacteristic(mClientIf, address,
-                                                  handle, characteristic.getWriteType(), authReq,
-                                                  value, mAttributionSource);
-                                if (requestStatus
-                                        != BluetoothStatusCodes.ERROR_GATT_WRITE_REQUEST_BUSY) {
-                                    break;
-                                }
-                                try {
-                                    Thread.sleep(WRITE_CHARACTERISTIC_TIME_TO_WAIT);
-                                } catch (InterruptedException e) {
-                                }
-                            }
-                            mAuthRetryState++;
-                            return;
-                        } catch (RemoteException e) {
-                            Log.e(TAG, "", e);
-                        }
-                    }
-
-                    mAuthRetryState = AUTH_RETRY_STATE_IDLE;
-                    runOrQueueCallback(new Runnable() {
-                        @Override
-                        public void run() {
-                            final BluetoothGattCallback callback = mCallback;
-                            if (callback != null) {
-                                callback.onCharacteristicWrite(BluetoothGatt.this, characteristic,
-                                        status);
-                            }
-                        }
-                    });
-                }
-
-                /**
-                 * Remote characteristic has been updated.
-                 * Updates the internal value.
-                 * @hide
-                 */
-                @Override
-                public void onNotify(String address, int handle, byte[] value) {
-                    if (VDBG) Log.d(TAG, "onNotify() - Device=" + address + " handle=" + handle);
-
-                    if (!address.equals(mDevice.getAddress())) {
-                        return;
-                    }
-
-                    BluetoothGattCharacteristic characteristic = getCharacteristicById(mDevice,
-                            handle);
-                    if (characteristic == null) return;
-
-                    runOrQueueCallback(new Runnable() {
-                        @Override
-                        public void run() {
-                            final BluetoothGattCallback callback = mCallback;
-                            if (callback != null) {
-                                characteristic.setValue(value);
-                                callback.onCharacteristicChanged(BluetoothGatt.this,
-                                        characteristic, value);
-                                // Keep calling deprecated callback to maintain app compatibility
-                                callback.onCharacteristicChanged(BluetoothGatt.this,
-                                        characteristic);
-                            }
-                        }
-                    });
-                }
-
-                /**
-                 * Descriptor has been read.
-                 * @hide
-                 */
-                @Override
-                @SuppressLint("AndroidFrameworkRequiresPermission")
-                public void onDescriptorRead(String address, int status, int handle, byte[] value) {
-                    if (VDBG) {
-                        Log.d(TAG,
-                                "onDescriptorRead() - Device=" + address + " handle=" + handle);
-                    }
-
-                    if (!address.equals(mDevice.getAddress())) {
-                        return;
-                    }
-
-                    synchronized (mDeviceBusyLock) {
-                        mDeviceBusy = false;
-                    }
-
-                    BluetoothGattDescriptor descriptor = getDescriptorById(mDevice, handle);
-                    if (descriptor == null) return;
-
-
-                    if ((status == GATT_INSUFFICIENT_AUTHENTICATION
-                            || status == GATT_INSUFFICIENT_ENCRYPTION)
-                            && (mAuthRetryState != AUTH_RETRY_STATE_MITM)) {
-                        try {
-                            final int authReq = (mAuthRetryState == AUTH_RETRY_STATE_IDLE)
-                                    ? AUTHENTICATION_NO_MITM : AUTHENTICATION_MITM;
-                            mService.readDescriptor(
-                                    mClientIf, address, handle, authReq, mAttributionSource);
-                            mAuthRetryState++;
-                            return;
-                        } catch (RemoteException e) {
-                            Log.e(TAG, "", e);
-                        }
-                    }
-
-                    mAuthRetryState = AUTH_RETRY_STATE_IDLE;
-
-                    runOrQueueCallback(new Runnable() {
-                        @Override
-                        public void run() {
-                            final BluetoothGattCallback callback = mCallback;
-                            if (callback != null) {
-                                if (status == 0) descriptor.setValue(value);
-                                callback.onDescriptorRead(BluetoothGatt.this, descriptor, status,
-                                        value);
-                                // Keep calling deprecated callback to maintain app compatibility
-                                callback.onDescriptorRead(BluetoothGatt.this, descriptor, status);
-                            }
-                        }
-                    });
-                }
-
-                /**
-                 * Descriptor write operation complete.
-                 * @hide
-                 */
-                @Override
-                @SuppressLint("AndroidFrameworkRequiresPermission")
-                public void onDescriptorWrite(String address, int status, int handle,
-                        byte[] value) {
-                    if (VDBG) {
-                        Log.d(TAG,
-                                "onDescriptorWrite() - Device=" + address + " handle=" + handle);
-                    }
-
-                    if (!address.equals(mDevice.getAddress())) {
-                        return;
-                    }
-
-                    synchronized (mDeviceBusyLock) {
-                        mDeviceBusy = false;
-                    }
-
-                    BluetoothGattDescriptor descriptor = getDescriptorById(mDevice, handle);
-                    if (descriptor == null) return;
-
-                    if ((status == GATT_INSUFFICIENT_AUTHENTICATION
-                            || status == GATT_INSUFFICIENT_ENCRYPTION)
-                            && (mAuthRetryState != AUTH_RETRY_STATE_MITM)) {
-                        try {
-                            final int authReq = (mAuthRetryState == AUTH_RETRY_STATE_IDLE)
-                                    ? AUTHENTICATION_NO_MITM : AUTHENTICATION_MITM;
-                            mService.writeDescriptor(mClientIf, address, handle,
-                                    authReq, value, mAttributionSource);
-                            mAuthRetryState++;
-                            return;
-                        } catch (RemoteException e) {
-                            Log.e(TAG, "", e);
-                        }
-                    }
-
-                    mAuthRetryState = AUTH_RETRY_STATE_IDLE;
-
-                    runOrQueueCallback(new Runnable() {
-                        @Override
-                        public void run() {
-                            final BluetoothGattCallback callback = mCallback;
-                            if (callback != null) {
-                                callback.onDescriptorWrite(BluetoothGatt.this, descriptor, status);
-                            }
-                        }
-                    });
-                }
-
-                /**
-                 * Prepared write transaction completed (or aborted)
-                 * @hide
-                 */
-                @Override
-                public void onExecuteWrite(String address, int status) {
-                    if (VDBG) {
-                        Log.d(TAG, "onExecuteWrite() - Device=" + address
-                                + " status=" + status);
-                    }
-                    if (!address.equals(mDevice.getAddress())) {
-                        return;
-                    }
-
-                    synchronized (mDeviceBusyLock) {
-                        mDeviceBusy = false;
-                    }
-
-                    runOrQueueCallback(new Runnable() {
-                        @Override
-                        public void run() {
-                            final BluetoothGattCallback callback = mCallback;
-                            if (callback != null) {
-                                callback.onReliableWriteCompleted(BluetoothGatt.this, status);
-                            }
-                        }
-                    });
-                }
-
-                /**
-                 * Remote device RSSI has been read
-                 * @hide
-                 */
-                @Override
-                public void onReadRemoteRssi(String address, int rssi, int status) {
-                    if (VDBG) {
-                        Log.d(TAG, "onReadRemoteRssi() - Device=" + address
-                                + " rssi=" + rssi + " status=" + status);
-                    }
-                    if (!address.equals(mDevice.getAddress())) {
-                        return;
-                    }
-                    runOrQueueCallback(new Runnable() {
-                        @Override
-                        public void run() {
-                            final BluetoothGattCallback callback = mCallback;
-                            if (callback != null) {
-                                callback.onReadRemoteRssi(BluetoothGatt.this, rssi, status);
-                            }
-                        }
-                    });
-                }
-
-                /**
-                 * Callback invoked when the MTU for a given connection changes
-                 * @hide
-                 */
-                @Override
-                public void onConfigureMTU(String address, int mtu, int status) {
-                    if (DBG) {
-                        Log.d(TAG, "onConfigureMTU() - Device=" + address
-                                + " mtu=" + mtu + " status=" + status);
-                    }
-                    if (!address.equals(mDevice.getAddress())) {
-                        return;
-                    }
-
-                    runOrQueueCallback(new Runnable() {
-                        @Override
-                        public void run() {
-                            final BluetoothGattCallback callback = mCallback;
-                            if (callback != null) {
-                                callback.onMtuChanged(BluetoothGatt.this, mtu, status);
-                            }
-                        }
-                    });
-                }
-
-                /**
-                 * Callback invoked when the given connection is updated
-                 * @hide
-                 */
-                @Override
-                public void onConnectionUpdated(String address, int interval, int latency,
-                        int timeout, int status) {
-                    if (DBG) {
-                        Log.d(TAG, "onConnectionUpdated() - Device=" + address
-                                + " interval=" + interval + " latency=" + latency
-                                + " timeout=" + timeout + " status=" + status);
-                    }
-                    if (!address.equals(mDevice.getAddress())) {
-                        return;
-                    }
-
-                    runOrQueueCallback(new Runnable() {
-                        @Override
-                        public void run() {
-                            final BluetoothGattCallback callback = mCallback;
-                            if (callback != null) {
-                                callback.onConnectionUpdated(BluetoothGatt.this, interval, latency,
-                                        timeout, status);
-                            }
-                        }
-                    });
-                }
-
-                /**
-                 * Callback invoked when service changed event is received
-                 * @hide
-                 */
-                @Override
-                public void onServiceChanged(String address) {
-                    if (DBG) {
-                        Log.d(TAG, "onServiceChanged() - Device=" + address);
-                    }
-
-                    if (!address.equals(mDevice.getAddress())) {
-                        return;
-                    }
-
-                    runOrQueueCallback(new Runnable() {
-                        @Override
-                        public void run() {
-                            final BluetoothGattCallback callback = mCallback;
-                            if (callback != null) {
-                                callback.onServiceChanged(BluetoothGatt.this);
-                            }
-                        }
-                    });
-                }
-            };
-
-    /* package */ BluetoothGatt(IBluetoothGatt iGatt, BluetoothDevice device, int transport,
-            boolean opportunistic, int phy, AttributionSource attributionSource) {
-        mService = iGatt;
-        mDevice = device;
-        mTransport = transport;
-        mPhy = phy;
-        mOpportunistic = opportunistic;
-        mAttributionSource = attributionSource;
-        mServices = new ArrayList<BluetoothGattService>();
-
-        mConnState = CONN_STATE_IDLE;
-        mAuthRetryState = AUTH_RETRY_STATE_IDLE;
-    }
-
-    /**
-     * Close this Bluetooth GATT client.
-     *
-     * Application should call this method as early as possible after it is done with
-     * this GATT client.
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public void close() {
-        if (DBG) Log.d(TAG, "close()");
-
-        unregisterApp();
-        mConnState = CONN_STATE_CLOSED;
-        mAuthRetryState = AUTH_RETRY_STATE_IDLE;
-    }
-
-    /**
-     * Returns a service by UUID, instance and type.
-     *
-     * @hide
-     */
-    /*package*/ BluetoothGattService getService(BluetoothDevice device, UUID uuid,
-            int instanceId) {
-        for (BluetoothGattService svc : mServices) {
-            if (svc.getDevice().equals(device)
-                    && svc.getInstanceId() == instanceId
-                    && svc.getUuid().equals(uuid)) {
-                return svc;
-            }
-        }
-        return null;
-    }
-
-
-    /**
-     * Returns a characteristic with id equal to instanceId.
-     *
-     * @hide
-     */
-    /*package*/ BluetoothGattCharacteristic getCharacteristicById(BluetoothDevice device,
-            int instanceId) {
-        for (BluetoothGattService svc : mServices) {
-            for (BluetoothGattCharacteristic charac : svc.getCharacteristics()) {
-                if (charac.getInstanceId() == instanceId) {
-                    return charac;
-                }
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Returns a descriptor with id equal to instanceId.
-     *
-     * @hide
-     */
-    /*package*/ BluetoothGattDescriptor getDescriptorById(BluetoothDevice device, int instanceId) {
-        for (BluetoothGattService svc : mServices) {
-            for (BluetoothGattCharacteristic charac : svc.getCharacteristics()) {
-                for (BluetoothGattDescriptor desc : charac.getDescriptors()) {
-                    if (desc.getInstanceId() == instanceId) {
-                        return desc;
-                    }
-                }
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Queue the runnable on a {@link Handler} provided by the user, or execute the runnable
-     * immediately if no Handler was provided.
-     */
-    private void runOrQueueCallback(final Runnable cb) {
-        if (mHandler == null) {
-            try {
-                cb.run();
-            } catch (Exception ex) {
-                Log.w(TAG, "Unhandled exception in callback", ex);
-            }
-        } else {
-            mHandler.post(cb);
-        }
-    }
-
-    /**
-     * Register an application callback to start using GATT.
-     *
-     * <p>This is an asynchronous call. The callback {@link BluetoothGattCallback#onAppRegistered}
-     * is used to notify success or failure if the function returns true.
-     *
-     * @param callback GATT callback handler that will receive asynchronous callbacks.
-     * @return If true, the callback will be called to notify success or failure, false on immediate
-     * error
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    private boolean registerApp(BluetoothGattCallback callback, Handler handler) {
-        return registerApp(callback, handler, false);
-    }
-
-    /**
-     * Register an application callback to start using GATT.
-     *
-     * <p>This is an asynchronous call. The callback {@link BluetoothGattCallback#onAppRegistered}
-     * is used to notify success or failure if the function returns true.
-     *
-     * @param callback GATT callback handler that will receive asynchronous callbacks.
-     * @param eatt_support indicate to allow for eatt support
-     * @return If true, the callback will be called to notify success or failure, false on immediate
-     * error
-     * @hide
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    private boolean registerApp(BluetoothGattCallback callback, Handler handler,
-                                boolean eatt_support) {
-        if (DBG) Log.d(TAG, "registerApp()");
-        if (mService == null) return false;
-
-        mCallback = callback;
-        mHandler = handler;
-        UUID uuid = UUID.randomUUID();
-        if (DBG) Log.d(TAG, "registerApp() - UUID=" + uuid);
-
-        try {
-            mService.registerClient(
-                    new ParcelUuid(uuid), mBluetoothGattCallback, eatt_support, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Unregister the current application and callbacks.
-     */
-    @UnsupportedAppUsage
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    private void unregisterApp() {
-        if (DBG) Log.d(TAG, "unregisterApp() - mClientIf=" + mClientIf);
-        if (mService == null || mClientIf == 0) return;
-
-        try {
-            mCallback = null;
-            mService.unregisterClient(mClientIf, mAttributionSource);
-            mClientIf = 0;
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        }
-    }
-
-    /**
-     * Initiate a connection to a Bluetooth GATT capable device.
-     *
-     * <p>The connection may not be established right away, but will be
-     * completed when the remote device is available. A
-     * {@link BluetoothGattCallback#onConnectionStateChange} callback will be
-     * invoked when the connection state changes as a result of this function.
-     *
-     * <p>The autoConnect parameter determines whether to actively connect to
-     * the remote device, or rather passively scan and finalize the connection
-     * when the remote device is in range/available. Generally, the first ever
-     * connection to a device should be direct (autoConnect set to false) and
-     * subsequent connections to known devices should be invoked with the
-     * autoConnect parameter set to true.
-     *
-     * @param device Remote device to connect to
-     * @param autoConnect Whether to directly connect to the remote device (false) or to
-     * automatically connect as soon as the remote device becomes available (true).
-     * @return true, if the connection attempt was initiated successfully
-     */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    /*package*/ boolean connect(Boolean autoConnect, BluetoothGattCallback callback,
-            Handler handler) {
-        if (DBG) {
-            Log.d(TAG,
-                    "connect() - device: " + mDevice.getAddress() + ", auto: " + autoConnect);
-        }
-        synchronized (mStateLock) {
-            if (mConnState != CONN_STATE_IDLE) {
-                throw new IllegalStateException("Not idle");
-            }
-            mConnState = CONN_STATE_CONNECTING;
-        }
-
-        mAutoConnect = autoConnect;
-
-        if (!registerApp(callback, handler)) {
-            synchronized (mStateLock) {
-                mConnState = CONN_STATE_IDLE;
-            }
-            Log.e(TAG, "Failed to register callback");
-            return false;
-        }
-
-        // The connection will continue in the onClientRegistered callback
-        return true;
-    }
-
-    /**
-     * Disconnects an established connection, or cancels a connection attempt
-     * currently in progress.
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public void disconnect() {
-        if (DBG) Log.d(TAG, "cancelOpen() - device: " + mDevice.getAddress());
-        if (mService == null || mClientIf == 0) return;
-
-        try {
-            mService.clientDisconnect(mClientIf, mDevice.getAddress(), mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        }
-    }
-
-    /**
-     * Connect back to remote device.
-     *
-     * <p>This method is used to re-connect to a remote device after the
-     * connection has been dropped. If the device is not in range, the
-     * re-connection will be triggered once the device is back in range.
-     *
-     * @return true, if the connection attempt was initiated successfully
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean connect() {
-        try {
-            // autoConnect is inverse of "isDirect"
-            mService.clientConnect(mClientIf, mDevice.getAddress(), false, mTransport,
-                    mOpportunistic, mPhy, mAttributionSource);
-            return true;
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-            return false;
-        }
-    }
-
-    /**
-     * Set the preferred connection PHY for this app. Please note that this is just a
-     * recommendation, whether the PHY change will happen depends on other applications preferences,
-     * local and remote controller capabilities. Controller can override these settings.
-     * <p>
-     * {@link BluetoothGattCallback#onPhyUpdate} will be triggered as a result of this call, even
-     * if no PHY change happens. It is also triggered when remote device updates the PHY.
-     *
-     * @param txPhy preferred transmitter PHY. Bitwise OR of any of {@link
-     * BluetoothDevice#PHY_LE_1M_MASK}, {@link BluetoothDevice#PHY_LE_2M_MASK}, and {@link
-     * BluetoothDevice#PHY_LE_CODED_MASK}.
-     * @param rxPhy preferred receiver PHY. Bitwise OR of any of {@link
-     * BluetoothDevice#PHY_LE_1M_MASK}, {@link BluetoothDevice#PHY_LE_2M_MASK}, and {@link
-     * BluetoothDevice#PHY_LE_CODED_MASK}.
-     * @param phyOptions preferred coding to use when transmitting on the LE Coded PHY. Can be one
-     * of {@link BluetoothDevice#PHY_OPTION_NO_PREFERRED}, {@link BluetoothDevice#PHY_OPTION_S2} or
-     * {@link BluetoothDevice#PHY_OPTION_S8}
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public void setPreferredPhy(int txPhy, int rxPhy, int phyOptions) {
-        try {
-            mService.clientSetPreferredPhy(mClientIf, mDevice.getAddress(), txPhy, rxPhy,
-                    phyOptions, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        }
-    }
-
-    /**
-     * Read the current transmitter PHY and receiver PHY of the connection. The values are returned
-     * in {@link BluetoothGattCallback#onPhyRead}
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public void readPhy() {
-        try {
-            mService.clientReadPhy(mClientIf, mDevice.getAddress(), mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        }
-    }
-
-    /**
-     * Return the remote bluetooth device this GATT client targets to
-     *
-     * @return remote bluetooth device
-     */
-    @RequiresNoPermission
-    public BluetoothDevice getDevice() {
-        return mDevice;
-    }
-
-    /**
-     * Discovers services offered by a remote device as well as their
-     * characteristics and descriptors.
-     *
-     * <p>This is an asynchronous operation. Once service discovery is completed,
-     * the {@link BluetoothGattCallback#onServicesDiscovered} callback is
-     * triggered. If the discovery was successful, the remote services can be
-     * retrieved using the {@link #getServices} function.
-     *
-     * @return true, if the remote service discovery has been started
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean discoverServices() {
-        if (DBG) Log.d(TAG, "discoverServices() - device: " + mDevice.getAddress());
-        if (mService == null || mClientIf == 0) return false;
-
-        mServices.clear();
-
-        try {
-            mService.discoverServices(mClientIf, mDevice.getAddress(), mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Discovers a service by UUID. This is exposed only for passing PTS tests.
-     * It should never be used by real applications. The service is not searched
-     * for characteristics and descriptors, or returned in any callback.
-     *
-     * @return true, if the remote service discovery has been started
-     * @hide
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean discoverServiceByUuid(UUID uuid) {
-        if (DBG) Log.d(TAG, "discoverServiceByUuid() - device: " + mDevice.getAddress());
-        if (mService == null || mClientIf == 0) return false;
-
-        mServices.clear();
-
-        try {
-            mService.discoverServiceByUuid(
-                    mClientIf, mDevice.getAddress(), new ParcelUuid(uuid), mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * Returns a list of GATT services offered by the remote device.
-     *
-     * <p>This function requires that service discovery has been completed
-     * for the given device.
-     *
-     * @return List of services on the remote device. Returns an empty list if service discovery has
-     * not yet been performed.
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresNoPermission
-    public List<BluetoothGattService> getServices() {
-        List<BluetoothGattService> result =
-                new ArrayList<BluetoothGattService>();
-
-        for (BluetoothGattService service : mServices) {
-            if (service.getDevice().equals(mDevice)) {
-                result.add(service);
-            }
-        }
-
-        return result;
-    }
-
-    /**
-     * Returns a {@link BluetoothGattService}, if the requested UUID is
-     * supported by the remote device.
-     *
-     * <p>This function requires that service discovery has been completed
-     * for the given device.
-     *
-     * <p>If multiple instances of the same service (as identified by UUID)
-     * exist, the first instance of the service is returned.
-     *
-     * @param uuid UUID of the requested service
-     * @return BluetoothGattService if supported, or null if the requested service is not offered by
-     * the remote device.
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresNoPermission
-    public BluetoothGattService getService(UUID uuid) {
-        for (BluetoothGattService service : mServices) {
-            if (service.getDevice().equals(mDevice) && service.getUuid().equals(uuid)) {
-                return service;
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Reads the requested characteristic from the associated remote device.
-     *
-     * <p>This is an asynchronous operation. The result of the read operation
-     * is reported by the {@link BluetoothGattCallback#onCharacteristicRead(BluetoothGatt,
-     * BluetoothGattCharacteristic, byte[], int)} callback.
-     *
-     * @param characteristic Characteristic to read from the remote device
-     * @return true, if the read operation was initiated successfully
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean readCharacteristic(BluetoothGattCharacteristic characteristic) {
-        if ((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_READ) == 0) {
-            return false;
-        }
-
-        if (VDBG) Log.d(TAG, "readCharacteristic() - uuid: " + characteristic.getUuid());
-        if (mService == null || mClientIf == 0) return false;
-
-        BluetoothGattService service = characteristic.getService();
-        if (service == null) return false;
-
-        BluetoothDevice device = service.getDevice();
-        if (device == null) return false;
-
-        synchronized (mDeviceBusyLock) {
-            if (mDeviceBusy) return false;
-            mDeviceBusy = true;
-        }
-
-        try {
-            mService.readCharacteristic(mClientIf, device.getAddress(),
-                    characteristic.getInstanceId(), AUTHENTICATION_NONE, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-            synchronized (mDeviceBusyLock) {
-                mDeviceBusy = false;
-            }
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Reads the characteristic using its UUID from the associated remote device.
-     *
-     * <p>This is an asynchronous operation. The result of the read operation
-     * is reported by the {@link BluetoothGattCallback#onCharacteristicRead(BluetoothGatt,
-     * BluetoothGattCharacteristic, byte[], int)} callback.
-     *
-     * @param uuid UUID of characteristic to read from the remote device
-     * @return true, if the read operation was initiated successfully
-     * @hide
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean readUsingCharacteristicUuid(UUID uuid, int startHandle, int endHandle) {
-        if (VDBG) Log.d(TAG, "readUsingCharacteristicUuid() - uuid: " + uuid);
-        if (mService == null || mClientIf == 0) return false;
-
-        synchronized (mDeviceBusyLock) {
-            if (mDeviceBusy) return false;
-            mDeviceBusy = true;
-        }
-
-        try {
-            mService.readUsingCharacteristicUuid(mClientIf, mDevice.getAddress(),
-                    new ParcelUuid(uuid), startHandle, endHandle, AUTHENTICATION_NONE,
-                    mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-            synchronized (mDeviceBusyLock) {
-                mDeviceBusy = false;
-            }
-            return false;
-        }
-
-        return true;
-    }
-
-
-    /**
-     * Writes a given characteristic and its values to the associated remote device.
-     *
-     * <p>Once the write operation has been completed, the
-     * {@link BluetoothGattCallback#onCharacteristicWrite} callback is invoked,
-     * reporting the result of the operation.
-     *
-     * @param characteristic Characteristic to write on the remote device
-     * @return true, if the write operation was initiated successfully
-     * @throws IllegalArgumentException if characteristic or its value are null
-     *
-     * @deprecated Use {@link BluetoothGatt#writeCharacteristic(BluetoothGattCharacteristic, byte[],
-     * int)} as this is not memory safe.
-     */
-    @Deprecated
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean writeCharacteristic(BluetoothGattCharacteristic characteristic) {
-        try {
-            return writeCharacteristic(characteristic, characteristic.getValue(),
-                    characteristic.getWriteType()) == BluetoothStatusCodes.SUCCESS;
-        } catch (Exception e) {
-            return false;
-        }
-    }
-
-    /** @hide */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(value = {
-            BluetoothStatusCodes.SUCCESS,
-            BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION,
-            BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_PRIVILEGED_PERMISSION,
-            BluetoothStatusCodes.ERROR_DEVICE_NOT_CONNECTED,
-            BluetoothStatusCodes.ERROR_PROFILE_SERVICE_NOT_BOUND,
-            BluetoothStatusCodes.ERROR_GATT_WRITE_NOT_ALLOWED,
-            BluetoothStatusCodes.ERROR_GATT_WRITE_REQUEST_BUSY,
-            BluetoothStatusCodes.ERROR_UNKNOWN
-    })
-    public @interface WriteOperationReturnValues{}
-
-    /**
-     * Writes a given characteristic and its values to the associated remote device.
-     *
-     * <p>Once the write operation has been completed, the
-     * {@link BluetoothGattCallback#onCharacteristicWrite} callback is invoked,
-     * reporting the result of the operation.
-     *
-     * @param characteristic Characteristic to write on the remote device
-     * @return whether the characteristic was successfully written to
-     * @throws IllegalArgumentException if characteristic or value are null
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @WriteOperationReturnValues
-    public int writeCharacteristic(@NonNull BluetoothGattCharacteristic characteristic,
-            @NonNull byte[] value, int writeType) {
-        if (characteristic == null) {
-            throw new IllegalArgumentException("characteristic must not be null");
-        }
-        if (value == null) {
-            throw new IllegalArgumentException("value must not be null");
-        }
-        if (VDBG) Log.d(TAG, "writeCharacteristic() - uuid: " + characteristic.getUuid());
-        if ((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_WRITE) == 0
-                && (characteristic.getProperties()
-                & BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) == 0) {
-            return BluetoothStatusCodes.ERROR_GATT_WRITE_NOT_ALLOWED;
-        }
-        if (mService == null || mClientIf == 0) {
-            return BluetoothStatusCodes.ERROR_PROFILE_SERVICE_NOT_BOUND;
-        }
-
-        BluetoothGattService service = characteristic.getService();
-        if (service == null) {
-            throw new IllegalArgumentException("Characteristic must have a non-null service");
-        }
-
-        BluetoothDevice device = service.getDevice();
-        if (device == null) {
-            throw new IllegalArgumentException("Service must have a non-null device");
-        }
-
-        synchronized (mDeviceBusyLock) {
-            if (mDeviceBusy) {
-                return BluetoothStatusCodes.ERROR_GATT_WRITE_REQUEST_BUSY;
-            }
-            mDeviceBusy = true;
-        }
-
-        int requestStatus = BluetoothStatusCodes.ERROR_UNKNOWN;
-        try {
-            for (int i = 0; i < WRITE_CHARACTERISTIC_MAX_RETRIES; i++) {
-                requestStatus = mService.writeCharacteristic(mClientIf, device.getAddress(),
-                        characteristic.getInstanceId(), writeType, AUTHENTICATION_NONE, value,
-                        mAttributionSource);
-                if (requestStatus != BluetoothStatusCodes.ERROR_GATT_WRITE_REQUEST_BUSY) {
-                    break;
-                }
-                try {
-                    Thread.sleep(WRITE_CHARACTERISTIC_TIME_TO_WAIT);
-                } catch (InterruptedException e) {
-                }
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-            synchronized (mDeviceBusyLock) {
-                mDeviceBusy = false;
-            }
-            throw e.rethrowFromSystemServer();
-        }
-
-        return requestStatus;
-    }
-
-    /**
-     * Reads the value for a given descriptor from the associated remote device.
-     *
-     * <p>Once the read operation has been completed, the
-     * {@link BluetoothGattCallback#onDescriptorRead} callback is
-     * triggered, signaling the result of the operation.
-     *
-     * @param descriptor Descriptor value to read from the remote device
-     * @return true, if the read operation was initiated successfully
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean readDescriptor(BluetoothGattDescriptor descriptor) {
-        if (VDBG) Log.d(TAG, "readDescriptor() - uuid: " + descriptor.getUuid());
-        if (mService == null || mClientIf == 0) return false;
-
-        BluetoothGattCharacteristic characteristic = descriptor.getCharacteristic();
-        if (characteristic == null) return false;
-
-        BluetoothGattService service = characteristic.getService();
-        if (service == null) return false;
-
-        BluetoothDevice device = service.getDevice();
-        if (device == null) return false;
-
-        synchronized (mDeviceBusyLock) {
-            if (mDeviceBusy) return false;
-            mDeviceBusy = true;
-        }
-
-        try {
-            mService.readDescriptor(mClientIf, device.getAddress(),
-                    descriptor.getInstanceId(), AUTHENTICATION_NONE, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-            synchronized (mDeviceBusyLock) {
-                mDeviceBusy = false;
-            }
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Write the value of a given descriptor to the associated remote device.
-     *
-     * <p>A {@link BluetoothGattCallback#onDescriptorWrite} callback is triggered to report the
-     * result of the write operation.
-     *
-     * @param descriptor Descriptor to write to the associated remote device
-     * @return true, if the write operation was initiated successfully
-     * @throws IllegalArgumentException if descriptor or its value are null
-     *
-     * @deprecated Use {@link BluetoothGatt#writeDescriptor(BluetoothGattDescriptor, byte[])} as
-     * this is not memory safe.
-     */
-    @Deprecated
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean writeDescriptor(BluetoothGattDescriptor descriptor) {
-        try {
-            return writeDescriptor(descriptor, descriptor.getValue())
-                    == BluetoothStatusCodes.SUCCESS;
-        } catch (Exception e) {
-            return false;
-        }
-    }
-
-    /**
-     * Write the value of a given descriptor to the associated remote device.
-     *
-     * <p>A {@link BluetoothGattCallback#onDescriptorWrite} callback is triggered to report the
-     * result of the write operation.
-     *
-     * @param descriptor Descriptor to write to the associated remote device
-     * @return true, if the write operation was initiated successfully
-     * @throws IllegalArgumentException if descriptor or value are null
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @WriteOperationReturnValues
-    public int writeDescriptor(@NonNull BluetoothGattDescriptor descriptor,
-            @NonNull byte[] value) {
-        if (descriptor == null) {
-            throw new IllegalArgumentException("descriptor must not be null");
-        }
-        if (value == null) {
-            throw new IllegalArgumentException("value must not be null");
-        }
-        if (VDBG) Log.d(TAG, "writeDescriptor() - uuid: " + descriptor.getUuid());
-        if (mService == null || mClientIf == 0) {
-            return BluetoothStatusCodes.ERROR_PROFILE_SERVICE_NOT_BOUND;
-        }
-
-        BluetoothGattCharacteristic characteristic = descriptor.getCharacteristic();
-        if (characteristic == null) {
-            throw new IllegalArgumentException("Descriptor must have a non-null characteristic");
-        }
-
-        BluetoothGattService service = characteristic.getService();
-        if (service == null) {
-            throw new IllegalArgumentException("Characteristic must have a non-null service");
-        }
-
-        BluetoothDevice device = service.getDevice();
-        if (device == null) {
-            throw new IllegalArgumentException("Service must have a non-null device");
-        }
-
-        synchronized (mDeviceBusyLock) {
-            if (mDeviceBusy) return BluetoothStatusCodes.ERROR_GATT_WRITE_REQUEST_BUSY;
-            mDeviceBusy = true;
-        }
-
-        try {
-            return mService.writeDescriptor(mClientIf, device.getAddress(),
-                    descriptor.getInstanceId(), AUTHENTICATION_NONE, value, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-            synchronized (mDeviceBusyLock) {
-                mDeviceBusy = false;
-            }
-            e.rethrowFromSystemServer();
-        }
-        return BluetoothStatusCodes.ERROR_UNKNOWN;
-    }
-
-    /**
-     * Initiates a reliable write transaction for a given remote device.
-     *
-     * <p>Once a reliable write transaction has been initiated, all calls
-     * to {@link #writeCharacteristic} are sent to the remote device for
-     * verification and queued up for atomic execution. The application will
-     * receive a {@link BluetoothGattCallback#onCharacteristicWrite} callback in response to every
-     * {@link #writeCharacteristic(BluetoothGattCharacteristic, byte[], int)} call and is
-     * responsible for verifying if the value has been transmitted accurately.
-     *
-     * <p>After all characteristics have been queued up and verified,
-     * {@link #executeReliableWrite} will execute all writes. If a characteristic
-     * was not written correctly, calling {@link #abortReliableWrite} will
-     * cancel the current transaction without committing any values on the
-     * remote device.
-     *
-     * @return true, if the reliable write transaction has been initiated
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean beginReliableWrite() {
-        if (VDBG) Log.d(TAG, "beginReliableWrite() - device: " + mDevice.getAddress());
-        if (mService == null || mClientIf == 0) return false;
-
-        try {
-            mService.beginReliableWrite(mClientIf, mDevice.getAddress(), mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Executes a reliable write transaction for a given remote device.
-     *
-     * <p>This function will commit all queued up characteristic write
-     * operations for a given remote device.
-     *
-     * <p>A {@link BluetoothGattCallback#onReliableWriteCompleted} callback is
-     * invoked to indicate whether the transaction has been executed correctly.
-     *
-     * @return true, if the request to execute the transaction has been sent
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean executeReliableWrite() {
-        if (VDBG) Log.d(TAG, "executeReliableWrite() - device: " + mDevice.getAddress());
-        if (mService == null || mClientIf == 0) return false;
-
-        synchronized (mDeviceBusyLock) {
-            if (mDeviceBusy) return false;
-            mDeviceBusy = true;
-        }
-
-        try {
-            mService.endReliableWrite(mClientIf, mDevice.getAddress(), true, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-            synchronized (mDeviceBusyLock) {
-                mDeviceBusy = false;
-            }
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Cancels a reliable write transaction for a given device.
-     *
-     * <p>Calling this function will discard all queued characteristic write
-     * operations for a given remote device.
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public void abortReliableWrite() {
-        if (VDBG) Log.d(TAG, "abortReliableWrite() - device: " + mDevice.getAddress());
-        if (mService == null || mClientIf == 0) return;
-
-        try {
-            mService.endReliableWrite(mClientIf, mDevice.getAddress(), false, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        }
-    }
-
-    /**
-     * @deprecated Use {@link #abortReliableWrite()}
-     */
-    @Deprecated
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public void abortReliableWrite(BluetoothDevice mDevice) {
-        abortReliableWrite();
-    }
-
-    /**
-     * Enable or disable notifications/indications for a given characteristic.
-     *
-     * <p>Once notifications are enabled for a characteristic, a
-     * {@link BluetoothGattCallback#onCharacteristicChanged(BluetoothGatt,
-     * BluetoothGattCharacteristic, byte[])} callback will be triggered if the remote device
-     * indicates that the given characteristic has changed.
-     *
-     * @param characteristic The characteristic for which to enable notifications
-     * @param enable Set to true to enable notifications/indications
-     * @return true, if the requested notification status was set successfully
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean setCharacteristicNotification(BluetoothGattCharacteristic characteristic,
-            boolean enable) {
-        if (DBG) {
-            Log.d(TAG, "setCharacteristicNotification() - uuid: " + characteristic.getUuid()
-                    + " enable: " + enable);
-        }
-        if (mService == null || mClientIf == 0) return false;
-
-        BluetoothGattService service = characteristic.getService();
-        if (service == null) return false;
-
-        BluetoothDevice device = service.getDevice();
-        if (device == null) return false;
-
-        try {
-            mService.registerForNotification(mClientIf, device.getAddress(),
-                    characteristic.getInstanceId(), enable, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Clears the internal cache and forces a refresh of the services from the
-     * remote device.
-     *
-     * @hide
-     */
-    @UnsupportedAppUsage
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean refresh() {
-        if (DBG) Log.d(TAG, "refresh() - device: " + mDevice.getAddress());
-        if (mService == null || mClientIf == 0) return false;
-
-        try {
-            mService.refreshDevice(mClientIf, mDevice.getAddress(), mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Read the RSSI for a connected remote device.
-     *
-     * <p>The {@link BluetoothGattCallback#onReadRemoteRssi} callback will be
-     * invoked when the RSSI value has been read.
-     *
-     * @return true, if the RSSI value has been requested successfully
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean readRemoteRssi() {
-        if (DBG) Log.d(TAG, "readRssi() - device: " + mDevice.getAddress());
-        if (mService == null || mClientIf == 0) return false;
-
-        try {
-            mService.readRemoteRssi(mClientIf, mDevice.getAddress(), mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Request an MTU size used for a given connection.
-     *
-     * <p>When performing a write request operation (write without response),
-     * the data sent is truncated to the MTU size. This function may be used
-     * to request a larger MTU size to be able to send more data at once.
-     *
-     * <p>A {@link BluetoothGattCallback#onMtuChanged} callback will indicate
-     * whether this operation was successful.
-     *
-     * @return true, if the new MTU value has been requested successfully
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean requestMtu(int mtu) {
-        if (DBG) {
-            Log.d(TAG, "configureMTU() - device: " + mDevice.getAddress()
-                    + " mtu: " + mtu);
-        }
-        if (mService == null || mClientIf == 0) return false;
-
-        try {
-            mService.configureMTU(mClientIf, mDevice.getAddress(), mtu, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Request a connection parameter update.
-     *
-     * <p>This function will send a connection parameter update request to the
-     * remote device.
-     *
-     * @param connectionPriority Request a specific connection priority. Must be one of {@link
-     * BluetoothGatt#CONNECTION_PRIORITY_BALANCED}, {@link BluetoothGatt#CONNECTION_PRIORITY_HIGH}
-     * or {@link BluetoothGatt#CONNECTION_PRIORITY_LOW_POWER}.
-     * @throws IllegalArgumentException If the parameters are outside of their specified range.
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean requestConnectionPriority(int connectionPriority) {
-        if (connectionPriority < CONNECTION_PRIORITY_BALANCED
-                || connectionPriority > CONNECTION_PRIORITY_LOW_POWER) {
-            throw new IllegalArgumentException("connectionPriority not within valid range");
-        }
-
-        if (DBG) Log.d(TAG, "requestConnectionPriority() - params: " + connectionPriority);
-        if (mService == null || mClientIf == 0) return false;
-
-        try {
-            mService.connectionParameterUpdate(
-                    mClientIf, mDevice.getAddress(), connectionPriority, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Request an LE connection parameter update.
-     *
-     * <p>This function will send an LE connection parameters update request to the remote device.
-     *
-     * @return true, if the request is send to the Bluetooth stack.
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean requestLeConnectionUpdate(int minConnectionInterval, int maxConnectionInterval,
-                                             int slaveLatency, int supervisionTimeout,
-                                             int minConnectionEventLen, int maxConnectionEventLen) {
-        if (DBG) {
-            Log.d(TAG, "requestLeConnectionUpdate() - min=(" + minConnectionInterval
-                        + ")" + (1.25 * minConnectionInterval)
-                        + "msec, max=(" + maxConnectionInterval + ")"
-                        + (1.25 * maxConnectionInterval) + "msec, latency=" + slaveLatency
-                        + ", timeout=" + supervisionTimeout + "msec" + ", min_ce="
-                        + minConnectionEventLen + ", max_ce=" + maxConnectionEventLen);
-        }
-        if (mService == null || mClientIf == 0) return false;
-
-        try {
-            mService.leConnectionUpdate(mClientIf, mDevice.getAddress(),
-                    minConnectionInterval, maxConnectionInterval,
-                    slaveLatency, supervisionTimeout,
-                    minConnectionEventLen, maxConnectionEventLen,
-                    mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * @deprecated Not supported - please use {@link BluetoothManager#getConnectedDevices(int)}
-     * with {@link BluetoothProfile#GATT} as argument
-     * @throws UnsupportedOperationException
-     */
-    @Override
-    @RequiresNoPermission
-    @Deprecated
-    public int getConnectionState(BluetoothDevice device) {
-        throw new UnsupportedOperationException("Use BluetoothManager#getConnectionState instead.");
-    }
-
-    /**
-     * @deprecated Not supported - please use {@link BluetoothManager#getConnectedDevices(int)}
-     * with {@link BluetoothProfile#GATT} as argument
-     *
-     * @throws UnsupportedOperationException
-     */
-    @Override
-    @RequiresNoPermission
-    @Deprecated
-    public List<BluetoothDevice> getConnectedDevices() {
-        throw new UnsupportedOperationException(
-                "Use BluetoothManager#getConnectedDevices instead.");
-    }
-
-    /**
-     * @deprecated Not supported - please use
-     * {@link BluetoothManager#getDevicesMatchingConnectionStates(int, int[])}
-     * with {@link BluetoothProfile#GATT} as first argument
-     *
-     * @throws UnsupportedOperationException
-     */
-    @Override
-    @RequiresNoPermission
-    @Deprecated
-    public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
-        throw new UnsupportedOperationException(
-                "Use BluetoothManager#getDevicesMatchingConnectionStates instead.");
-    }
-}
diff --git a/core/java/android/bluetooth/BluetoothGattCallback.java b/core/java/android/bluetooth/BluetoothGattCallback.java
deleted file mode 100644
index d0a5a1e..0000000
--- a/core/java/android/bluetooth/BluetoothGattCallback.java
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-import android.annotation.NonNull;
-
-/**
- * This abstract class is used to implement {@link BluetoothGatt} callbacks.
- */
-public abstract class BluetoothGattCallback {
-
-    /**
-     * Callback triggered as result of {@link BluetoothGatt#setPreferredPhy}, or as a result of
-     * remote device changing the PHY.
-     *
-     * @param gatt GATT client
-     * @param txPhy the transmitter PHY in use. One of {@link BluetoothDevice#PHY_LE_1M}, {@link
-     * BluetoothDevice#PHY_LE_2M}, and {@link BluetoothDevice#PHY_LE_CODED}.
-     * @param rxPhy the receiver PHY in use. One of {@link BluetoothDevice#PHY_LE_1M}, {@link
-     * BluetoothDevice#PHY_LE_2M}, and {@link BluetoothDevice#PHY_LE_CODED}.
-     * @param status Status of the PHY update operation. {@link BluetoothGatt#GATT_SUCCESS} if the
-     * operation succeeds.
-     */
-    public void onPhyUpdate(BluetoothGatt gatt, int txPhy, int rxPhy, int status) {
-    }
-
-    /**
-     * Callback triggered as result of {@link BluetoothGatt#readPhy}
-     *
-     * @param gatt GATT client
-     * @param txPhy the transmitter PHY in use. One of {@link BluetoothDevice#PHY_LE_1M}, {@link
-     * BluetoothDevice#PHY_LE_2M}, and {@link BluetoothDevice#PHY_LE_CODED}.
-     * @param rxPhy the receiver PHY in use. One of {@link BluetoothDevice#PHY_LE_1M}, {@link
-     * BluetoothDevice#PHY_LE_2M}, and {@link BluetoothDevice#PHY_LE_CODED}.
-     * @param status Status of the PHY read operation. {@link BluetoothGatt#GATT_SUCCESS} if the
-     * operation succeeds.
-     */
-    public void onPhyRead(BluetoothGatt gatt, int txPhy, int rxPhy, int status) {
-    }
-
-    /**
-     * Callback indicating when GATT client has connected/disconnected to/from a remote
-     * GATT server.
-     *
-     * @param gatt GATT client
-     * @param status Status of the connect or disconnect operation. {@link
-     * BluetoothGatt#GATT_SUCCESS} if the operation succeeds.
-     * @param newState Returns the new connection state. Can be one of {@link
-     * BluetoothProfile#STATE_DISCONNECTED} or {@link BluetoothProfile#STATE_CONNECTED}
-     */
-    public void onConnectionStateChange(BluetoothGatt gatt, int status,
-            int newState) {
-    }
-
-    /**
-     * Callback invoked when the list of remote services, characteristics and descriptors
-     * for the remote device have been updated, ie new services have been discovered.
-     *
-     * @param gatt GATT client invoked {@link BluetoothGatt#discoverServices}
-     * @param status {@link BluetoothGatt#GATT_SUCCESS} if the remote device has been explored
-     * successfully.
-     */
-    public void onServicesDiscovered(BluetoothGatt gatt, int status) {
-    }
-
-    /**
-     * Callback reporting the result of a characteristic read operation.
-     *
-     * @param gatt           GATT client invoked
-     *                       {@link BluetoothGatt#readCharacteristic(BluetoothGattCharacteristic)}
-     * @param characteristic Characteristic that was read from the associated remote device.
-     * @param status         {@link BluetoothGatt#GATT_SUCCESS} if the read operation was completed
-     *                       successfully.
-     * @deprecated Use {@link BluetoothGattCallback#onCharacteristicRead(BluetoothGatt,
-     * BluetoothGattCharacteristic, byte[], int)} as it is memory safe
-     */
-    @Deprecated
-    public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic,
-            int status) {
-    }
-
-    /**
-     * Callback reporting the result of a characteristic read operation.
-     *
-     * @param gatt           GATT client invoked
-     *                       {@link BluetoothGatt#readCharacteristic(BluetoothGattCharacteristic)}
-     * @param characteristic Characteristic that was read from the associated remote device.
-     * @param value          the value of the characteristic
-     * @param status         {@link BluetoothGatt#GATT_SUCCESS} if the read operation was completed
-     *                       successfully.
-     */
-    public void onCharacteristicRead(@NonNull BluetoothGatt gatt, @NonNull
-            BluetoothGattCharacteristic characteristic, @NonNull byte[] value, int status) {
-    }
-
-    /**
-     * Callback indicating the result of a characteristic write operation.
-     *
-     * <p>If this callback is invoked while a reliable write transaction is
-     * in progress, the value of the characteristic represents the value
-     * reported by the remote device. An application should compare this
-     * value to the desired value to be written. If the values don't match,
-     * the application must abort the reliable write transaction.
-     *
-     * @param gatt           GATT client that invoked
-     *                       {@link BluetoothGatt#writeCharacteristic(BluetoothGattCharacteristic,
-     *                       byte[], int)}
-     * @param characteristic Characteristic that was written to the associated remote device.
-     * @param status         The result of the write operation {@link BluetoothGatt#GATT_SUCCESS} if
-     *                       the
-     *                       operation succeeds.
-     */
-    public void onCharacteristicWrite(BluetoothGatt gatt,
-            BluetoothGattCharacteristic characteristic, int status) {
-    }
-
-    /**
-     * Callback triggered as a result of a remote characteristic notification.
-     *
-     * @param gatt           GATT client the characteristic is associated with
-     * @param characteristic Characteristic that has been updated as a result of a remote
-     *                       notification event.
-     * @deprecated Use {@link BluetoothGattCallback#onCharacteristicChanged(BluetoothGatt,
-     * BluetoothGattCharacteristic, byte[])} as it is memory safe by providing the characteristic
-     * value at the time of notification.
-     */
-    @Deprecated
-    public void onCharacteristicChanged(BluetoothGatt gatt,
-            BluetoothGattCharacteristic characteristic) {
-    }
-
-    /**
-     * Callback triggered as a result of a remote characteristic notification. Note that the value
-     * within the characteristic object may have changed since receiving the remote characteristic
-     * notification, so check the parameter value for the value at the time of notification.
-     *
-     * @param gatt           GATT client the characteristic is associated with
-     * @param characteristic Characteristic that has been updated as a result of a remote
-     *                       notification event.
-     * @param value          notified characteristic value
-     */
-    public void onCharacteristicChanged(@NonNull BluetoothGatt gatt,
-            @NonNull BluetoothGattCharacteristic characteristic, @NonNull byte[] value) {
-    }
-
-    /**
-     * Callback reporting the result of a descriptor read operation.
-     *
-     * @param gatt       GATT client invoked {@link BluetoothGatt#readDescriptor}
-     * @param descriptor Descriptor that was read from the associated remote device.
-     * @param status     {@link BluetoothGatt#GATT_SUCCESS} if the read operation was completed
-     *                   successfully
-     * @deprecated Use {@link BluetoothGattCallback#onDescriptorRead(BluetoothGatt,
-     * BluetoothGattDescriptor, int, byte[])} as it is memory safe by providing the descriptor
-     * value at the time it was read.
-     */
-    @Deprecated
-    public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor,
-            int status) {
-    }
-
-    /**
-     * Callback reporting the result of a descriptor read operation.
-     *
-     * @param gatt       GATT client invoked {@link BluetoothGatt#readDescriptor}
-     * @param descriptor Descriptor that was read from the associated remote device.
-     * @param status     {@link BluetoothGatt#GATT_SUCCESS} if the read operation was completed
-     *                   successfully
-     * @param value      the descriptor value at the time of the read operation
-     */
-    public void onDescriptorRead(@NonNull BluetoothGatt gatt,
-            @NonNull BluetoothGattDescriptor descriptor, int status, @NonNull byte[] value) {
-    }
-
-    /**
-     * Callback indicating the result of a descriptor write operation.
-     *
-     * @param gatt       GATT client invoked {@link BluetoothGatt#writeDescriptor}
-     * @param descriptor Descriptor that was writte to the associated remote device.
-     * @param status     The result of the write operation {@link BluetoothGatt#GATT_SUCCESS} if the
-     *                   operation succeeds.
-     */
-    public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor,
-            int status) {
-    }
-
-    /**
-     * Callback invoked when a reliable write transaction has been completed.
-     *
-     * @param gatt GATT client invoked {@link BluetoothGatt#executeReliableWrite}
-     * @param status {@link BluetoothGatt#GATT_SUCCESS} if the reliable write transaction was
-     * executed successfully
-     */
-    public void onReliableWriteCompleted(BluetoothGatt gatt, int status) {
-    }
-
-    /**
-     * Callback reporting the RSSI for a remote device connection.
-     *
-     * This callback is triggered in response to the
-     * {@link BluetoothGatt#readRemoteRssi} function.
-     *
-     * @param gatt GATT client invoked {@link BluetoothGatt#readRemoteRssi}
-     * @param rssi The RSSI value for the remote device
-     * @param status {@link BluetoothGatt#GATT_SUCCESS} if the RSSI was read successfully
-     */
-    public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
-    }
-
-    /**
-     * Callback indicating the MTU for a given device connection has changed.
-     *
-     * This callback is triggered in response to the
-     * {@link BluetoothGatt#requestMtu} function, or in response to a connection
-     * event.
-     *
-     * @param gatt GATT client invoked {@link BluetoothGatt#requestMtu}
-     * @param mtu The new MTU size
-     * @param status {@link BluetoothGatt#GATT_SUCCESS} if the MTU has been changed successfully
-     */
-    public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
-    }
-
-    /**
-     * Callback indicating the connection parameters were updated.
-     *
-     * @param gatt GATT client involved
-     * @param interval Connection interval used on this connection, 1.25ms unit. Valid range is from
-     * 6 (7.5ms) to 3200 (4000ms).
-     * @param latency Worker latency for the connection in number of connection events. Valid range
-     * is from 0 to 499
-     * @param timeout Supervision timeout for this connection, in 10ms unit. Valid range is from 10
-     * (0.1s) to 3200 (32s)
-     * @param status {@link BluetoothGatt#GATT_SUCCESS} if the connection has been updated
-     * successfully
-     * @hide
-     */
-    public void onConnectionUpdated(BluetoothGatt gatt, int interval, int latency, int timeout,
-            int status) {
-    }
-
-    /**
-     * Callback indicating service changed event is received
-     *
-     * <p>Receiving this event means that the GATT database is out of sync with
-     * the remote device. {@link BluetoothGatt#discoverServices} should be
-     * called to re-discover the services.
-     *
-     * @param gatt GATT client involved
-     */
-    public void onServiceChanged(@NonNull BluetoothGatt gatt) {
-    }
-}
diff --git a/core/java/android/bluetooth/BluetoothGattCharacteristic.java b/core/java/android/bluetooth/BluetoothGattCharacteristic.java
deleted file mode 100644
index c5e986e..0000000
--- a/core/java/android/bluetooth/BluetoothGattCharacteristic.java
+++ /dev/null
@@ -1,806 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.bluetooth;
-
-import android.compat.annotation.UnsupportedAppUsage;
-import android.os.Parcel;
-import android.os.ParcelUuid;
-import android.os.Parcelable;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.UUID;
-
-/**
- * Represents a Bluetooth GATT Characteristic
- *
- * <p>A GATT characteristic is a basic data element used to construct a GATT service,
- * {@link BluetoothGattService}. The characteristic contains a value as well as
- * additional information and optional GATT descriptors, {@link BluetoothGattDescriptor}.
- */
-public class BluetoothGattCharacteristic implements Parcelable {
-
-    /**
-     * Characteristic proprty: Characteristic is broadcastable.
-     */
-    public static final int PROPERTY_BROADCAST = 0x01;
-
-    /**
-     * Characteristic property: Characteristic is readable.
-     */
-    public static final int PROPERTY_READ = 0x02;
-
-    /**
-     * Characteristic property: Characteristic can be written without response.
-     */
-    public static final int PROPERTY_WRITE_NO_RESPONSE = 0x04;
-
-    /**
-     * Characteristic property: Characteristic can be written.
-     */
-    public static final int PROPERTY_WRITE = 0x08;
-
-    /**
-     * Characteristic property: Characteristic supports notification
-     */
-    public static final int PROPERTY_NOTIFY = 0x10;
-
-    /**
-     * Characteristic property: Characteristic supports indication
-     */
-    public static final int PROPERTY_INDICATE = 0x20;
-
-    /**
-     * Characteristic property: Characteristic supports write with signature
-     */
-    public static final int PROPERTY_SIGNED_WRITE = 0x40;
-
-    /**
-     * Characteristic property: Characteristic has extended properties
-     */
-    public static final int PROPERTY_EXTENDED_PROPS = 0x80;
-
-    /**
-     * Characteristic read permission
-     */
-    public static final int PERMISSION_READ = 0x01;
-
-    /**
-     * Characteristic permission: Allow encrypted read operations
-     */
-    public static final int PERMISSION_READ_ENCRYPTED = 0x02;
-
-    /**
-     * Characteristic permission: Allow reading with person-in-the-middle protection
-     */
-    public static final int PERMISSION_READ_ENCRYPTED_MITM = 0x04;
-
-    /**
-     * Characteristic write permission
-     */
-    public static final int PERMISSION_WRITE = 0x10;
-
-    /**
-     * Characteristic permission: Allow encrypted writes
-     */
-    public static final int PERMISSION_WRITE_ENCRYPTED = 0x20;
-
-    /**
-     * Characteristic permission: Allow encrypted writes with person-in-the-middle
-     * protection
-     */
-    public static final int PERMISSION_WRITE_ENCRYPTED_MITM = 0x40;
-
-    /**
-     * Characteristic permission: Allow signed write operations
-     */
-    public static final int PERMISSION_WRITE_SIGNED = 0x80;
-
-    /**
-     * Characteristic permission: Allow signed write operations with
-     * person-in-the-middle protection
-     */
-    public static final int PERMISSION_WRITE_SIGNED_MITM = 0x100;
-
-    /**
-     * Write characteristic, requesting acknoledgement by the remote device
-     */
-    public static final int WRITE_TYPE_DEFAULT = 0x02;
-
-    /**
-     * Write characteristic without requiring a response by the remote device
-     */
-    public static final int WRITE_TYPE_NO_RESPONSE = 0x01;
-
-    /**
-     * Write characteristic including authentication signature
-     */
-    public static final int WRITE_TYPE_SIGNED = 0x04;
-
-    /**
-     * Characteristic value format type uint8
-     */
-    public static final int FORMAT_UINT8 = 0x11;
-
-    /**
-     * Characteristic value format type uint16
-     */
-    public static final int FORMAT_UINT16 = 0x12;
-
-    /**
-     * Characteristic value format type uint32
-     */
-    public static final int FORMAT_UINT32 = 0x14;
-
-    /**
-     * Characteristic value format type sint8
-     */
-    public static final int FORMAT_SINT8 = 0x21;
-
-    /**
-     * Characteristic value format type sint16
-     */
-    public static final int FORMAT_SINT16 = 0x22;
-
-    /**
-     * Characteristic value format type sint32
-     */
-    public static final int FORMAT_SINT32 = 0x24;
-
-    /**
-     * Characteristic value format type sfloat (16-bit float)
-     */
-    public static final int FORMAT_SFLOAT = 0x32;
-
-    /**
-     * Characteristic value format type float (32-bit float)
-     */
-    public static final int FORMAT_FLOAT = 0x34;
-
-
-    /**
-     * The UUID of this characteristic.
-     *
-     * @hide
-     */
-    protected UUID mUuid;
-
-    /**
-     * Instance ID for this characteristic.
-     *
-     * @hide
-     */
-    @UnsupportedAppUsage
-    protected int mInstance;
-
-    /**
-     * Characteristic properties.
-     *
-     * @hide
-     */
-    protected int mProperties;
-
-    /**
-     * Characteristic permissions.
-     *
-     * @hide
-     */
-    protected int mPermissions;
-
-    /**
-     * Key size (default = 16).
-     *
-     * @hide
-     */
-    protected int mKeySize = 16;
-
-    /**
-     * Write type for this characteristic.
-     * See WRITE_TYPE_* constants.
-     *
-     * @hide
-     */
-    protected int mWriteType;
-
-    /**
-     * Back-reference to the service this characteristic belongs to.
-     *
-     * @hide
-     */
-    @UnsupportedAppUsage
-    protected BluetoothGattService mService;
-
-    /**
-     * The cached value of this characteristic.
-     *
-     * @hide
-     */
-    protected byte[] mValue;
-
-    /**
-     * List of descriptors included in this characteristic.
-     */
-    protected List<BluetoothGattDescriptor> mDescriptors;
-
-    /**
-     * Create a new BluetoothGattCharacteristic.
-     *
-     * @param uuid The UUID for this characteristic
-     * @param properties Properties of this characteristic
-     * @param permissions Permissions for this characteristic
-     */
-    public BluetoothGattCharacteristic(UUID uuid, int properties, int permissions) {
-        initCharacteristic(null, uuid, 0, properties, permissions);
-    }
-
-    /**
-     * Create a new BluetoothGattCharacteristic
-     *
-     * @hide
-     */
-    /*package*/ BluetoothGattCharacteristic(BluetoothGattService service,
-            UUID uuid, int instanceId,
-            int properties, int permissions) {
-        initCharacteristic(service, uuid, instanceId, properties, permissions);
-    }
-
-    /**
-     * Create a new BluetoothGattCharacteristic
-     *
-     * @hide
-     */
-    public BluetoothGattCharacteristic(UUID uuid, int instanceId,
-            int properties, int permissions) {
-        initCharacteristic(null, uuid, instanceId, properties, permissions);
-    }
-
-    private void initCharacteristic(BluetoothGattService service,
-            UUID uuid, int instanceId,
-            int properties, int permissions) {
-        mUuid = uuid;
-        mInstance = instanceId;
-        mProperties = properties;
-        mPermissions = permissions;
-        mService = service;
-        mValue = null;
-        mDescriptors = new ArrayList<BluetoothGattDescriptor>();
-
-        if ((mProperties & PROPERTY_WRITE_NO_RESPONSE) != 0) {
-            mWriteType = WRITE_TYPE_NO_RESPONSE;
-        } else {
-            mWriteType = WRITE_TYPE_DEFAULT;
-        }
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeParcelable(new ParcelUuid(mUuid), 0);
-        out.writeInt(mInstance);
-        out.writeInt(mProperties);
-        out.writeInt(mPermissions);
-        out.writeInt(mKeySize);
-        out.writeInt(mWriteType);
-        out.writeTypedList(mDescriptors);
-    }
-
-    public static final @android.annotation.NonNull Parcelable.Creator<BluetoothGattCharacteristic> CREATOR =
-            new Parcelable.Creator<BluetoothGattCharacteristic>() {
-        public BluetoothGattCharacteristic createFromParcel(Parcel in) {
-            return new BluetoothGattCharacteristic(in);
-        }
-
-        public BluetoothGattCharacteristic[] newArray(int size) {
-            return new BluetoothGattCharacteristic[size];
-        }
-    };
-
-    private BluetoothGattCharacteristic(Parcel in) {
-        mUuid = ((ParcelUuid) in.readParcelable(null)).getUuid();
-        mInstance = in.readInt();
-        mProperties = in.readInt();
-        mPermissions = in.readInt();
-        mKeySize = in.readInt();
-        mWriteType = in.readInt();
-
-        mDescriptors = new ArrayList<BluetoothGattDescriptor>();
-
-        ArrayList<BluetoothGattDescriptor> descs =
-                in.createTypedArrayList(BluetoothGattDescriptor.CREATOR);
-        if (descs != null) {
-            for (BluetoothGattDescriptor desc : descs) {
-                desc.setCharacteristic(this);
-                mDescriptors.add(desc);
-            }
-        }
-    }
-
-    /**
-     * Returns the desired key size.
-     *
-     * @hide
-     */
-    public int getKeySize() {
-        return mKeySize;
-    }
-
-    /**
-     * Adds a descriptor to this characteristic.
-     *
-     * @param descriptor Descriptor to be added to this characteristic.
-     * @return true, if the descriptor was added to the characteristic
-     */
-    public boolean addDescriptor(BluetoothGattDescriptor descriptor) {
-        mDescriptors.add(descriptor);
-        descriptor.setCharacteristic(this);
-        return true;
-    }
-
-    /**
-     * Get a descriptor by UUID and isntance id.
-     *
-     * @hide
-     */
-    /*package*/  BluetoothGattDescriptor getDescriptor(UUID uuid, int instanceId) {
-        for (BluetoothGattDescriptor descriptor : mDescriptors) {
-            if (descriptor.getUuid().equals(uuid)
-                    && descriptor.getInstanceId() == instanceId) {
-                return descriptor;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Returns the service this characteristic belongs to.
-     *
-     * @return The asscociated service
-     */
-    public BluetoothGattService getService() {
-        return mService;
-    }
-
-    /**
-     * Sets the service associated with this device.
-     *
-     * @hide
-     */
-    @UnsupportedAppUsage
-    /*package*/ void setService(BluetoothGattService service) {
-        mService = service;
-    }
-
-    /**
-     * Returns the UUID of this characteristic
-     *
-     * @return UUID of this characteristic
-     */
-    public UUID getUuid() {
-        return mUuid;
-    }
-
-    /**
-     * Returns the instance ID for this characteristic.
-     *
-     * <p>If a remote device offers multiple characteristics with the same UUID,
-     * the instance ID is used to distuinguish between characteristics.
-     *
-     * @return Instance ID of this characteristic
-     */
-    public int getInstanceId() {
-        return mInstance;
-    }
-
-    /**
-     * Force the instance ID.
-     *
-     * @hide
-     */
-    public void setInstanceId(int instanceId) {
-        mInstance = instanceId;
-    }
-
-    /**
-     * Returns the properties of this characteristic.
-     *
-     * <p>The properties contain a bit mask of property flags indicating
-     * the features of this characteristic.
-     *
-     * @return Properties of this characteristic
-     */
-    public int getProperties() {
-        return mProperties;
-    }
-
-    /**
-     * Returns the permissions for this characteristic.
-     *
-     * @return Permissions of this characteristic
-     */
-    public int getPermissions() {
-        return mPermissions;
-    }
-
-    /**
-     * Gets the write type for this characteristic.
-     *
-     * @return Write type for this characteristic
-     */
-    public int getWriteType() {
-        return mWriteType;
-    }
-
-    /**
-     * Set the write type for this characteristic
-     *
-     * <p>Setting the write type of a characteristic determines how the
-     * {@link BluetoothGatt#writeCharacteristic(BluetoothGattCharacteristic, byte[], int)} function
-     * write this characteristic.
-     *
-     * @param writeType The write type to for this characteristic. Can be one of: {@link
-     * #WRITE_TYPE_DEFAULT}, {@link #WRITE_TYPE_NO_RESPONSE} or {@link #WRITE_TYPE_SIGNED}.
-     */
-    public void setWriteType(int writeType) {
-        mWriteType = writeType;
-    }
-
-    /**
-     * Set the desired key size.
-     *
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public void setKeySize(int keySize) {
-        mKeySize = keySize;
-    }
-
-    /**
-     * Returns a list of descriptors for this characteristic.
-     *
-     * @return Descriptors for this characteristic
-     */
-    public List<BluetoothGattDescriptor> getDescriptors() {
-        return mDescriptors;
-    }
-
-    /**
-     * Returns a descriptor with a given UUID out of the list of
-     * descriptors for this characteristic.
-     *
-     * @return GATT descriptor object or null if no descriptor with the given UUID was found.
-     */
-    public BluetoothGattDescriptor getDescriptor(UUID uuid) {
-        for (BluetoothGattDescriptor descriptor : mDescriptors) {
-            if (descriptor.getUuid().equals(uuid)) {
-                return descriptor;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Get the stored value for this characteristic.
-     *
-     * <p>This function returns the stored value for this characteristic as
-     * retrieved by calling {@link BluetoothGatt#readCharacteristic}. The cached
-     * value of the characteristic is updated as a result of a read characteristic
-     * operation or if a characteristic update notification has been received.
-     *
-     * @return Cached value of the characteristic
-     *
-     * @deprecated Use {@link BluetoothGatt#readCharacteristic(BluetoothGattCharacteristic)} instead
-     */
-    @Deprecated
-    public byte[] getValue() {
-        return mValue;
-    }
-
-    /**
-     * Return the stored value of this characteristic.
-     *
-     * <p>The formatType parameter determines how the characteristic value
-     * is to be interpreted. For example, settting formatType to
-     * {@link #FORMAT_UINT16} specifies that the first two bytes of the
-     * characteristic value at the given offset are interpreted to generate the
-     * return value.
-     *
-     * @param formatType The format type used to interpret the characteristic value.
-     * @param offset Offset at which the integer value can be found.
-     * @return Cached value of the characteristic or null of offset exceeds value size.
-     *
-     * @deprecated Use {@link BluetoothGatt#readCharacteristic(BluetoothGattCharacteristic)} to get
-     * the characteristic value
-     */
-    @Deprecated
-    public Integer getIntValue(int formatType, int offset) {
-        if ((offset + getTypeLen(formatType)) > mValue.length) return null;
-
-        switch (formatType) {
-            case FORMAT_UINT8:
-                return unsignedByteToInt(mValue[offset]);
-
-            case FORMAT_UINT16:
-                return unsignedBytesToInt(mValue[offset], mValue[offset + 1]);
-
-            case FORMAT_UINT32:
-                return unsignedBytesToInt(mValue[offset], mValue[offset + 1],
-                        mValue[offset + 2], mValue[offset + 3]);
-            case FORMAT_SINT8:
-                return unsignedToSigned(unsignedByteToInt(mValue[offset]), 8);
-
-            case FORMAT_SINT16:
-                return unsignedToSigned(unsignedBytesToInt(mValue[offset],
-                        mValue[offset + 1]), 16);
-
-            case FORMAT_SINT32:
-                return unsignedToSigned(unsignedBytesToInt(mValue[offset],
-                        mValue[offset + 1], mValue[offset + 2], mValue[offset + 3]), 32);
-        }
-
-        return null;
-    }
-
-    /**
-     * Return the stored value of this characteristic.
-     * <p>See {@link #getValue} for details.
-     *
-     * @param formatType The format type used to interpret the characteristic value.
-     * @param offset Offset at which the float value can be found.
-     * @return Cached value of the characteristic at a given offset or null if the requested offset
-     * exceeds the value size.
-     *
-     * @deprecated Use {@link BluetoothGatt#readCharacteristic(BluetoothGattCharacteristic)} to get
-     * the characteristic value
-     */
-    @Deprecated
-    public Float getFloatValue(int formatType, int offset) {
-        if ((offset + getTypeLen(formatType)) > mValue.length) return null;
-
-        switch (formatType) {
-            case FORMAT_SFLOAT:
-                return bytesToFloat(mValue[offset], mValue[offset + 1]);
-
-            case FORMAT_FLOAT:
-                return bytesToFloat(mValue[offset], mValue[offset + 1],
-                        mValue[offset + 2], mValue[offset + 3]);
-        }
-
-        return null;
-    }
-
-    /**
-     * Return the stored value of this characteristic.
-     * <p>See {@link #getValue} for details.
-     *
-     * @param offset Offset at which the string value can be found.
-     * @return Cached value of the characteristic
-     *
-     * @deprecated Use {@link BluetoothGatt#readCharacteristic(BluetoothGattCharacteristic)} to get
-     * the characteristic value
-     */
-    @Deprecated
-    public String getStringValue(int offset) {
-        if (mValue == null || offset > mValue.length) return null;
-        byte[] strBytes = new byte[mValue.length - offset];
-        for (int i = 0; i != (mValue.length - offset); ++i) strBytes[i] = mValue[offset + i];
-        return new String(strBytes);
-    }
-
-    /**
-     * Updates the locally stored value of this characteristic.
-     *
-     * <p>This function modifies the locally stored cached value of this
-     * characteristic. To send the value to the remote device, call
-     * {@link BluetoothGatt#writeCharacteristic} to send the value to the
-     * remote device.
-     *
-     * @param value New value for this characteristic
-     * @return true if the locally stored value has been set, false if the requested value could not
-     * be stored locally.
-     *
-     * @deprecated Pass the characteristic value directly into
-     * {@link BluetoothGatt#writeCharacteristic(BluetoothGattCharacteristic, byte[], int)}
-     */
-    @Deprecated
-    public boolean setValue(byte[] value) {
-        mValue = value;
-        return true;
-    }
-
-    /**
-     * Set the locally stored value of this characteristic.
-     * <p>See {@link #setValue(byte[])} for details.
-     *
-     * @param value New value for this characteristic
-     * @param formatType Integer format type used to transform the value parameter
-     * @param offset Offset at which the value should be placed
-     * @return true if the locally stored value has been set
-     *
-     * @deprecated Pass the characteristic value directly into
-     * {@link BluetoothGatt#writeCharacteristic(BluetoothGattCharacteristic, byte[], int)}
-     */
-    @Deprecated
-    public boolean setValue(int value, int formatType, int offset) {
-        int len = offset + getTypeLen(formatType);
-        if (mValue == null) mValue = new byte[len];
-        if (len > mValue.length) return false;
-
-        switch (formatType) {
-            case FORMAT_SINT8:
-                value = intToSignedBits(value, 8);
-                // Fall-through intended
-            case FORMAT_UINT8:
-                mValue[offset] = (byte) (value & 0xFF);
-                break;
-
-            case FORMAT_SINT16:
-                value = intToSignedBits(value, 16);
-                // Fall-through intended
-            case FORMAT_UINT16:
-                mValue[offset++] = (byte) (value & 0xFF);
-                mValue[offset] = (byte) ((value >> 8) & 0xFF);
-                break;
-
-            case FORMAT_SINT32:
-                value = intToSignedBits(value, 32);
-                // Fall-through intended
-            case FORMAT_UINT32:
-                mValue[offset++] = (byte) (value & 0xFF);
-                mValue[offset++] = (byte) ((value >> 8) & 0xFF);
-                mValue[offset++] = (byte) ((value >> 16) & 0xFF);
-                mValue[offset] = (byte) ((value >> 24) & 0xFF);
-                break;
-
-            default:
-                return false;
-        }
-        return true;
-    }
-
-    /**
-     * Set the locally stored value of this characteristic.
-     * <p>See {@link #setValue(byte[])} for details.
-     *
-     * @param mantissa Mantissa for this characteristic
-     * @param exponent exponent value for this characteristic
-     * @param formatType Float format type used to transform the value parameter
-     * @param offset Offset at which the value should be placed
-     * @return true if the locally stored value has been set
-     *
-     * @deprecated Pass the characteristic value directly into
-     * {@link BluetoothGatt#writeCharacteristic(BluetoothGattCharacteristic, byte[], int)}
-     */
-    @Deprecated
-    public boolean setValue(int mantissa, int exponent, int formatType, int offset) {
-        int len = offset + getTypeLen(formatType);
-        if (mValue == null) mValue = new byte[len];
-        if (len > mValue.length) return false;
-
-        switch (formatType) {
-            case FORMAT_SFLOAT:
-                mantissa = intToSignedBits(mantissa, 12);
-                exponent = intToSignedBits(exponent, 4);
-                mValue[offset++] = (byte) (mantissa & 0xFF);
-                mValue[offset] = (byte) ((mantissa >> 8) & 0x0F);
-                mValue[offset] += (byte) ((exponent & 0x0F) << 4);
-                break;
-
-            case FORMAT_FLOAT:
-                mantissa = intToSignedBits(mantissa, 24);
-                exponent = intToSignedBits(exponent, 8);
-                mValue[offset++] = (byte) (mantissa & 0xFF);
-                mValue[offset++] = (byte) ((mantissa >> 8) & 0xFF);
-                mValue[offset++] = (byte) ((mantissa >> 16) & 0xFF);
-                mValue[offset] += (byte) (exponent & 0xFF);
-                break;
-
-            default:
-                return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Set the locally stored value of this characteristic.
-     * <p>See {@link #setValue(byte[])} for details.
-     *
-     * @param value New value for this characteristic
-     * @return true if the locally stored value has been set
-     *
-     * @deprecated Pass the characteristic value directly into
-     * {@link BluetoothGatt#writeCharacteristic(BluetoothGattCharacteristic, byte[], int)}
-     */
-    @Deprecated
-    public boolean setValue(String value) {
-        mValue = value.getBytes();
-        return true;
-    }
-
-    /**
-     * Returns the size of a give value type.
-     */
-    private int getTypeLen(int formatType) {
-        return formatType & 0xF;
-    }
-
-    /**
-     * Convert a signed byte to an unsigned int.
-     */
-    private int unsignedByteToInt(byte b) {
-        return b & 0xFF;
-    }
-
-    /**
-     * Convert signed bytes to a 16-bit unsigned int.
-     */
-    private int unsignedBytesToInt(byte b0, byte b1) {
-        return (unsignedByteToInt(b0) + (unsignedByteToInt(b1) << 8));
-    }
-
-    /**
-     * Convert signed bytes to a 32-bit unsigned int.
-     */
-    private int unsignedBytesToInt(byte b0, byte b1, byte b2, byte b3) {
-        return (unsignedByteToInt(b0) + (unsignedByteToInt(b1) << 8))
-                + (unsignedByteToInt(b2) << 16) + (unsignedByteToInt(b3) << 24);
-    }
-
-    /**
-     * Convert signed bytes to a 16-bit short float value.
-     */
-    private float bytesToFloat(byte b0, byte b1) {
-        int mantissa = unsignedToSigned(unsignedByteToInt(b0)
-                + ((unsignedByteToInt(b1) & 0x0F) << 8), 12);
-        int exponent = unsignedToSigned(unsignedByteToInt(b1) >> 4, 4);
-        return (float) (mantissa * Math.pow(10, exponent));
-    }
-
-    /**
-     * Convert signed bytes to a 32-bit short float value.
-     */
-    private float bytesToFloat(byte b0, byte b1, byte b2, byte b3) {
-        int mantissa = unsignedToSigned(unsignedByteToInt(b0)
-                + (unsignedByteToInt(b1) << 8)
-                + (unsignedByteToInt(b2) << 16), 24);
-        return (float) (mantissa * Math.pow(10, b3));
-    }
-
-    /**
-     * Convert an unsigned integer value to a two's-complement encoded
-     * signed value.
-     */
-    private int unsignedToSigned(int unsigned, int size) {
-        if ((unsigned & (1 << size - 1)) != 0) {
-            unsigned = -1 * ((1 << size - 1) - (unsigned & ((1 << size - 1) - 1)));
-        }
-        return unsigned;
-    }
-
-    /**
-     * Convert an integer into the signed bits of a given length.
-     */
-    private int intToSignedBits(int i, int size) {
-        if (i < 0) {
-            i = (1 << size - 1) + (i & ((1 << size - 1) - 1));
-        }
-        return i;
-    }
-}
diff --git a/core/java/android/bluetooth/BluetoothGattDescriptor.java b/core/java/android/bluetooth/BluetoothGattDescriptor.java
deleted file mode 100644
index a35d5b9..0000000
--- a/core/java/android/bluetooth/BluetoothGattDescriptor.java
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-import android.compat.annotation.UnsupportedAppUsage;
-import android.os.Parcel;
-import android.os.ParcelUuid;
-import android.os.Parcelable;
-
-import java.util.UUID;
-
-/**
- * Represents a Bluetooth GATT Descriptor
- *
- * <p> GATT Descriptors contain additional information and attributes of a GATT
- * characteristic, {@link BluetoothGattCharacteristic}. They can be used to describe
- * the characteristic's features or to control certain behaviours of the characteristic.
- */
-public class BluetoothGattDescriptor implements Parcelable {
-
-    /**
-     * Value used to enable notification for a client configuration descriptor
-     */
-    public static final byte[] ENABLE_NOTIFICATION_VALUE = {0x01, 0x00};
-
-    /**
-     * Value used to enable indication for a client configuration descriptor
-     */
-    public static final byte[] ENABLE_INDICATION_VALUE = {0x02, 0x00};
-
-    /**
-     * Value used to disable notifications or indicatinos
-     */
-    public static final byte[] DISABLE_NOTIFICATION_VALUE = {0x00, 0x00};
-
-    /**
-     * Descriptor read permission
-     */
-    public static final int PERMISSION_READ = 0x01;
-
-    /**
-     * Descriptor permission: Allow encrypted read operations
-     */
-    public static final int PERMISSION_READ_ENCRYPTED = 0x02;
-
-    /**
-     * Descriptor permission: Allow reading with person-in-the-middle protection
-     */
-    public static final int PERMISSION_READ_ENCRYPTED_MITM = 0x04;
-
-    /**
-     * Descriptor write permission
-     */
-    public static final int PERMISSION_WRITE = 0x10;
-
-    /**
-     * Descriptor permission: Allow encrypted writes
-     */
-    public static final int PERMISSION_WRITE_ENCRYPTED = 0x20;
-
-    /**
-     * Descriptor permission: Allow encrypted writes with person-in-the-middle
-     * protection
-     */
-    public static final int PERMISSION_WRITE_ENCRYPTED_MITM = 0x40;
-
-    /**
-     * Descriptor permission: Allow signed write operations
-     */
-    public static final int PERMISSION_WRITE_SIGNED = 0x80;
-
-    /**
-     * Descriptor permission: Allow signed write operations with
-     * person-in-the-middle protection
-     */
-    public static final int PERMISSION_WRITE_SIGNED_MITM = 0x100;
-
-    /**
-     * The UUID of this descriptor.
-     *
-     * @hide
-     */
-    protected UUID mUuid;
-
-    /**
-     * Instance ID for this descriptor.
-     *
-     * @hide
-     */
-    @UnsupportedAppUsage
-    protected int mInstance;
-
-    /**
-     * Permissions for this descriptor
-     *
-     * @hide
-     */
-    protected int mPermissions;
-
-    /**
-     * Back-reference to the characteristic this descriptor belongs to.
-     *
-     * @hide
-     */
-    @UnsupportedAppUsage
-    protected BluetoothGattCharacteristic mCharacteristic;
-
-    /**
-     * The value for this descriptor.
-     *
-     * @hide
-     */
-    protected byte[] mValue;
-
-    /**
-     * Create a new BluetoothGattDescriptor.
-     *
-     * @param uuid The UUID for this descriptor
-     * @param permissions Permissions for this descriptor
-     */
-    public BluetoothGattDescriptor(UUID uuid, int permissions) {
-        initDescriptor(null, uuid, 0, permissions);
-    }
-
-    /**
-     * Create a new BluetoothGattDescriptor.
-     *
-     * @param characteristic The characteristic this descriptor belongs to
-     * @param uuid The UUID for this descriptor
-     * @param permissions Permissions for this descriptor
-     */
-    /*package*/ BluetoothGattDescriptor(BluetoothGattCharacteristic characteristic, UUID uuid,
-            int instance, int permissions) {
-        initDescriptor(characteristic, uuid, instance, permissions);
-    }
-
-    /**
-     * @hide
-     */
-    public BluetoothGattDescriptor(UUID uuid, int instance, int permissions) {
-        initDescriptor(null, uuid, instance, permissions);
-    }
-
-    private void initDescriptor(BluetoothGattCharacteristic characteristic, UUID uuid,
-            int instance, int permissions) {
-        mCharacteristic = characteristic;
-        mUuid = uuid;
-        mInstance = instance;
-        mPermissions = permissions;
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeParcelable(new ParcelUuid(mUuid), 0);
-        out.writeInt(mInstance);
-        out.writeInt(mPermissions);
-    }
-
-    public static final @android.annotation.NonNull Parcelable.Creator<BluetoothGattDescriptor> CREATOR =
-            new Parcelable.Creator<BluetoothGattDescriptor>() {
-        public BluetoothGattDescriptor createFromParcel(Parcel in) {
-            return new BluetoothGattDescriptor(in);
-        }
-
-        public BluetoothGattDescriptor[] newArray(int size) {
-            return new BluetoothGattDescriptor[size];
-        }
-    };
-
-    private BluetoothGattDescriptor(Parcel in) {
-        mUuid = ((ParcelUuid) in.readParcelable(null)).getUuid();
-        mInstance = in.readInt();
-        mPermissions = in.readInt();
-    }
-
-    /**
-     * Returns the characteristic this descriptor belongs to.
-     *
-     * @return The characteristic.
-     */
-    public BluetoothGattCharacteristic getCharacteristic() {
-        return mCharacteristic;
-    }
-
-    /**
-     * Set the back-reference to the associated characteristic
-     *
-     * @hide
-     */
-    @UnsupportedAppUsage
-    /*package*/ void setCharacteristic(BluetoothGattCharacteristic characteristic) {
-        mCharacteristic = characteristic;
-    }
-
-    /**
-     * Returns the UUID of this descriptor.
-     *
-     * @return UUID of this descriptor
-     */
-    public UUID getUuid() {
-        return mUuid;
-    }
-
-    /**
-     * Returns the instance ID for this descriptor.
-     *
-     * <p>If a remote device offers multiple descriptors with the same UUID,
-     * the instance ID is used to distuinguish between descriptors.
-     *
-     * @return Instance ID of this descriptor
-     * @hide
-     */
-    public int getInstanceId() {
-        return mInstance;
-    }
-
-    /**
-     * Force the instance ID.
-     *
-     * @hide
-     */
-    public void setInstanceId(int instanceId) {
-        mInstance = instanceId;
-    }
-
-    /**
-     * Returns the permissions for this descriptor.
-     *
-     * @return Permissions of this descriptor
-     */
-    public int getPermissions() {
-        return mPermissions;
-    }
-
-    /**
-     * Returns the stored value for this descriptor
-     *
-     * <p>This function returns the stored value for this descriptor as
-     * retrieved by calling {@link BluetoothGatt#readDescriptor}. The cached
-     * value of the descriptor is updated as a result of a descriptor read
-     * operation.
-     *
-     * @return Cached value of the descriptor
-     *
-     * @deprecated  Use {@link BluetoothGatt#readDescriptor(BluetoothGattDescriptor)} instead
-     */
-    @Deprecated
-    public byte[] getValue() {
-        return mValue;
-    }
-
-    /**
-     * Updates the locally stored value of this descriptor.
-     *
-     * <p>This function modifies the locally stored cached value of this
-     * descriptor. To send the value to the remote device, call
-     * {@link BluetoothGatt#writeDescriptor} to send the value to the
-     * remote device.
-     *
-     * @param value New value for this descriptor
-     * @return true if the locally stored value has been set, false if the requested value could not
-     * be stored locally.
-     *
-     * @deprecated Pass the descriptor value directly into
-     * {@link BluetoothGatt#writeDescriptor(BluetoothGattDescriptor, byte[])}
-     */
-    @Deprecated
-    public boolean setValue(byte[] value) {
-        mValue = value;
-        return true;
-    }
-}
diff --git a/core/java/android/bluetooth/BluetoothGattIncludedService.java b/core/java/android/bluetooth/BluetoothGattIncludedService.java
deleted file mode 100644
index 5580619..0000000
--- a/core/java/android/bluetooth/BluetoothGattIncludedService.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.bluetooth;
-
-import android.os.Parcel;
-import android.os.ParcelUuid;
-import android.os.Parcelable;
-
-import java.util.UUID;
-
-/**
- * Represents a Bluetooth GATT Included Service
- *
- * @hide
- */
-public class BluetoothGattIncludedService implements Parcelable {
-
-    /**
-     * The UUID of this service.
-     */
-    protected UUID mUuid;
-
-    /**
-     * Instance ID for this service.
-     */
-    protected int mInstanceId;
-
-    /**
-     * Service type (Primary/Secondary).
-     */
-    protected int mServiceType;
-
-    /**
-     * Create a new BluetoothGattIncludedService
-     */
-    public BluetoothGattIncludedService(UUID uuid, int instanceId, int serviceType) {
-        mUuid = uuid;
-        mInstanceId = instanceId;
-        mServiceType = serviceType;
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeParcelable(new ParcelUuid(mUuid), 0);
-        out.writeInt(mInstanceId);
-        out.writeInt(mServiceType);
-    }
-
-    public static final @android.annotation.NonNull Parcelable.Creator<BluetoothGattIncludedService> CREATOR =
-            new Parcelable.Creator<BluetoothGattIncludedService>() {
-        public BluetoothGattIncludedService createFromParcel(Parcel in) {
-            return new BluetoothGattIncludedService(in);
-        }
-
-        public BluetoothGattIncludedService[] newArray(int size) {
-            return new BluetoothGattIncludedService[size];
-        }
-    };
-
-    private BluetoothGattIncludedService(Parcel in) {
-        mUuid = ((ParcelUuid) in.readParcelable(null)).getUuid();
-        mInstanceId = in.readInt();
-        mServiceType = in.readInt();
-    }
-
-    /**
-     * Returns the UUID of this service
-     *
-     * @return UUID of this service
-     */
-    public UUID getUuid() {
-        return mUuid;
-    }
-
-    /**
-     * Returns the instance ID for this service
-     *
-     * <p>If a remote device offers multiple services with the same UUID
-     * (ex. multiple battery services for different batteries), the instance
-     * ID is used to distuinguish services.
-     *
-     * @return Instance ID of this service
-     */
-    public int getInstanceId() {
-        return mInstanceId;
-    }
-
-    /**
-     * Get the type of this service (primary/secondary)
-     */
-    public int getType() {
-        return mServiceType;
-    }
-}
diff --git a/core/java/android/bluetooth/BluetoothGattServer.java b/core/java/android/bluetooth/BluetoothGattServer.java
deleted file mode 100644
index 08e0178..0000000
--- a/core/java/android/bluetooth/BluetoothGattServer.java
+++ /dev/null
@@ -1,954 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.RequiresNoPermission;
-import android.annotation.RequiresPermission;
-import android.annotation.SuppressLint;
-import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
-import android.bluetooth.annotations.RequiresLegacyBluetoothPermission;
-import android.content.AttributionSource;
-import android.os.ParcelUuid;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.UUID;
-
-/**
- * Public API for the Bluetooth GATT Profile server role.
- *
- * <p>This class provides Bluetooth GATT server role functionality,
- * allowing applications to create Bluetooth Smart services and
- * characteristics.
- *
- * <p>BluetoothGattServer is a proxy object for controlling the Bluetooth Service
- * via IPC.  Use {@link BluetoothManager#openGattServer} to get an instance
- * of this class.
- */
-public final class BluetoothGattServer implements BluetoothProfile {
-    private static final String TAG = "BluetoothGattServer";
-    private static final boolean DBG = true;
-    private static final boolean VDBG = false;
-
-    private final IBluetoothGatt mService;
-    private final BluetoothAdapter mAdapter;
-    private final AttributionSource mAttributionSource;
-
-    private BluetoothGattServerCallback mCallback;
-
-    private Object mServerIfLock = new Object();
-    private int mServerIf;
-    private int mTransport;
-    private BluetoothGattService mPendingService;
-    private List<BluetoothGattService> mServices;
-
-    private static final int CALLBACK_REG_TIMEOUT = 10000;
-
-    /**
-     * Bluetooth GATT interface callbacks
-     */
-    @SuppressLint("AndroidFrameworkBluetoothPermission")
-    private final IBluetoothGattServerCallback mBluetoothGattServerCallback =
-            new IBluetoothGattServerCallback.Stub() {
-                /**
-                 * Application interface registered - app is ready to go
-                 * @hide
-                 */
-                @Override
-                public void onServerRegistered(int status, int serverIf) {
-                    if (DBG) {
-                        Log.d(TAG, "onServerRegistered() - status=" + status
-                                + " serverIf=" + serverIf);
-                    }
-                    synchronized (mServerIfLock) {
-                        if (mCallback != null) {
-                            mServerIf = serverIf;
-                            mServerIfLock.notify();
-                        } else {
-                            // registration timeout
-                            Log.e(TAG, "onServerRegistered: mCallback is null");
-                        }
-                    }
-                }
-
-                /**
-                 * Server connection state changed
-                 * @hide
-                 */
-                @Override
-                public void onServerConnectionState(int status, int serverIf,
-                        boolean connected, String address) {
-                    if (DBG) {
-                        Log.d(TAG, "onServerConnectionState() - status=" + status
-                                + " serverIf=" + serverIf + " device=" + address);
-                    }
-                    try {
-                        mCallback.onConnectionStateChange(mAdapter.getRemoteDevice(address), status,
-                                connected ? BluetoothProfile.STATE_CONNECTED :
-                                        BluetoothProfile.STATE_DISCONNECTED);
-                    } catch (Exception ex) {
-                        Log.w(TAG, "Unhandled exception in callback", ex);
-                    }
-                }
-
-                /**
-                 * Service has been added
-                 * @hide
-                 */
-                @Override
-                public void onServiceAdded(int status, BluetoothGattService service) {
-                    if (DBG) {
-                        Log.d(TAG, "onServiceAdded() - handle=" + service.getInstanceId()
-                                + " uuid=" + service.getUuid() + " status=" + status);
-                    }
-
-                    if (mPendingService == null) {
-                        return;
-                    }
-
-                    BluetoothGattService tmp = mPendingService;
-                    mPendingService = null;
-
-                    // Rewrite newly assigned handles to existing service.
-                    tmp.setInstanceId(service.getInstanceId());
-                    List<BluetoothGattCharacteristic> temp_chars = tmp.getCharacteristics();
-                    List<BluetoothGattCharacteristic> svc_chars = service.getCharacteristics();
-                    for (int i = 0; i < svc_chars.size(); i++) {
-                        BluetoothGattCharacteristic temp_char = temp_chars.get(i);
-                        BluetoothGattCharacteristic svc_char = svc_chars.get(i);
-
-                        temp_char.setInstanceId(svc_char.getInstanceId());
-
-                        List<BluetoothGattDescriptor> temp_descs = temp_char.getDescriptors();
-                        List<BluetoothGattDescriptor> svc_descs = svc_char.getDescriptors();
-                        for (int j = 0; j < svc_descs.size(); j++) {
-                            temp_descs.get(j).setInstanceId(svc_descs.get(j).getInstanceId());
-                        }
-                    }
-
-                    mServices.add(tmp);
-
-                    try {
-                        mCallback.onServiceAdded((int) status, tmp);
-                    } catch (Exception ex) {
-                        Log.w(TAG, "Unhandled exception in callback", ex);
-                    }
-                }
-
-                /**
-                 * Remote client characteristic read request.
-                 * @hide
-                 */
-                @Override
-                public void onCharacteristicReadRequest(String address, int transId,
-                        int offset, boolean isLong, int handle) {
-                    if (VDBG) Log.d(TAG, "onCharacteristicReadRequest() - handle=" + handle);
-
-                    BluetoothDevice device = mAdapter.getRemoteDevice(address);
-                    BluetoothGattCharacteristic characteristic = getCharacteristicByHandle(handle);
-                    if (characteristic == null) {
-                        Log.w(TAG, "onCharacteristicReadRequest() no char for handle " + handle);
-                        return;
-                    }
-
-                    try {
-                        mCallback.onCharacteristicReadRequest(device, transId, offset,
-                                characteristic);
-                    } catch (Exception ex) {
-                        Log.w(TAG, "Unhandled exception in callback", ex);
-                    }
-                }
-
-                /**
-                 * Remote client descriptor read request.
-                 * @hide
-                 */
-                @Override
-                public void onDescriptorReadRequest(String address, int transId,
-                        int offset, boolean isLong, int handle) {
-                    if (VDBG) Log.d(TAG, "onCharacteristicReadRequest() - handle=" + handle);
-
-                    BluetoothDevice device = mAdapter.getRemoteDevice(address);
-                    BluetoothGattDescriptor descriptor = getDescriptorByHandle(handle);
-                    if (descriptor == null) {
-                        Log.w(TAG, "onDescriptorReadRequest() no desc for handle " + handle);
-                        return;
-                    }
-
-                    try {
-                        mCallback.onDescriptorReadRequest(device, transId, offset, descriptor);
-                    } catch (Exception ex) {
-                        Log.w(TAG, "Unhandled exception in callback", ex);
-                    }
-                }
-
-                /**
-                 * Remote client characteristic write request.
-                 * @hide
-                 */
-                @Override
-                public void onCharacteristicWriteRequest(String address, int transId,
-                        int offset, int length, boolean isPrep, boolean needRsp,
-                        int handle, byte[] value) {
-                    if (VDBG) Log.d(TAG, "onCharacteristicWriteRequest() - handle=" + handle);
-
-                    BluetoothDevice device = mAdapter.getRemoteDevice(address);
-                    BluetoothGattCharacteristic characteristic = getCharacteristicByHandle(handle);
-                    if (characteristic == null) {
-                        Log.w(TAG, "onCharacteristicWriteRequest() no char for handle " + handle);
-                        return;
-                    }
-
-                    try {
-                        mCallback.onCharacteristicWriteRequest(device, transId, characteristic,
-                                isPrep, needRsp, offset, value);
-                    } catch (Exception ex) {
-                        Log.w(TAG, "Unhandled exception in callback", ex);
-                    }
-
-                }
-
-                /**
-                 * Remote client descriptor write request.
-                 * @hide
-                 */
-                @Override
-                public void onDescriptorWriteRequest(String address, int transId, int offset,
-                        int length, boolean isPrep, boolean needRsp, int handle, byte[] value) {
-                    if (VDBG) Log.d(TAG, "onDescriptorWriteRequest() - handle=" + handle);
-
-                    BluetoothDevice device = mAdapter.getRemoteDevice(address);
-                    BluetoothGattDescriptor descriptor = getDescriptorByHandle(handle);
-                    if (descriptor == null) {
-                        Log.w(TAG, "onDescriptorWriteRequest() no desc for handle " + handle);
-                        return;
-                    }
-
-                    try {
-                        mCallback.onDescriptorWriteRequest(device, transId, descriptor,
-                                isPrep, needRsp, offset, value);
-                    } catch (Exception ex) {
-                        Log.w(TAG, "Unhandled exception in callback", ex);
-                    }
-                }
-
-                /**
-                 * Execute pending writes.
-                 * @hide
-                 */
-                @Override
-                public void onExecuteWrite(String address, int transId,
-                        boolean execWrite) {
-                    if (DBG) {
-                        Log.d(TAG, "onExecuteWrite() - "
-                                + "device=" + address + ", transId=" + transId
-                                + "execWrite=" + execWrite);
-                    }
-
-                    BluetoothDevice device = mAdapter.getRemoteDevice(address);
-                    if (device == null) return;
-
-                    try {
-                        mCallback.onExecuteWrite(device, transId, execWrite);
-                    } catch (Exception ex) {
-                        Log.w(TAG, "Unhandled exception in callback", ex);
-                    }
-                }
-
-                /**
-                 * A notification/indication has been sent.
-                 * @hide
-                 */
-                @Override
-                public void onNotificationSent(String address, int status) {
-                    if (VDBG) {
-                        Log.d(TAG, "onNotificationSent() - "
-                                + "device=" + address + ", status=" + status);
-                    }
-
-                    BluetoothDevice device = mAdapter.getRemoteDevice(address);
-                    if (device == null) return;
-
-                    try {
-                        mCallback.onNotificationSent(device, status);
-                    } catch (Exception ex) {
-                        Log.w(TAG, "Unhandled exception: " + ex);
-                    }
-                }
-
-                /**
-                 * The MTU for a connection has changed
-                 * @hide
-                 */
-                @Override
-                public void onMtuChanged(String address, int mtu) {
-                    if (DBG) {
-                        Log.d(TAG, "onMtuChanged() - "
-                                + "device=" + address + ", mtu=" + mtu);
-                    }
-
-                    BluetoothDevice device = mAdapter.getRemoteDevice(address);
-                    if (device == null) return;
-
-                    try {
-                        mCallback.onMtuChanged(device, mtu);
-                    } catch (Exception ex) {
-                        Log.w(TAG, "Unhandled exception: " + ex);
-                    }
-                }
-
-                /**
-                 * The PHY for a connection was updated
-                 * @hide
-                 */
-                @Override
-                public void onPhyUpdate(String address, int txPhy, int rxPhy, int status) {
-                    if (DBG) {
-                        Log.d(TAG,
-                                "onPhyUpdate() - " + "device=" + address + ", txPHy=" + txPhy
-                                        + ", rxPHy=" + rxPhy);
-                    }
-
-                    BluetoothDevice device = mAdapter.getRemoteDevice(address);
-                    if (device == null) return;
-
-                    try {
-                        mCallback.onPhyUpdate(device, txPhy, rxPhy, status);
-                    } catch (Exception ex) {
-                        Log.w(TAG, "Unhandled exception: " + ex);
-                    }
-                }
-
-                /**
-                 * The PHY for a connection was read
-                 * @hide
-                 */
-                @Override
-                public void onPhyRead(String address, int txPhy, int rxPhy, int status) {
-                    if (DBG) {
-                        Log.d(TAG,
-                                "onPhyUpdate() - " + "device=" + address + ", txPHy=" + txPhy
-                                        + ", rxPHy=" + rxPhy);
-                    }
-
-                    BluetoothDevice device = mAdapter.getRemoteDevice(address);
-                    if (device == null) return;
-
-                    try {
-                        mCallback.onPhyRead(device, txPhy, rxPhy, status);
-                    } catch (Exception ex) {
-                        Log.w(TAG, "Unhandled exception: " + ex);
-                    }
-                }
-
-                /**
-                 * Callback invoked when the given connection is updated
-                 * @hide
-                 */
-                @Override
-                public void onConnectionUpdated(String address, int interval, int latency,
-                        int timeout, int status) {
-                    if (DBG) {
-                        Log.d(TAG, "onConnectionUpdated() - Device=" + address
-                                + " interval=" + interval + " latency=" + latency
-                                + " timeout=" + timeout + " status=" + status);
-                    }
-                    BluetoothDevice device = mAdapter.getRemoteDevice(address);
-                    if (device == null) return;
-
-                    try {
-                        mCallback.onConnectionUpdated(device, interval, latency,
-                                timeout, status);
-                    } catch (Exception ex) {
-                        Log.w(TAG, "Unhandled exception: " + ex);
-                    }
-                }
-
-            };
-
-    /**
-     * Create a BluetoothGattServer proxy object.
-     */
-    /* package */ BluetoothGattServer(IBluetoothGatt iGatt, int transport,
-            BluetoothAdapter adapter) {
-        mService = iGatt;
-        mAdapter = adapter;
-        mAttributionSource = adapter.getAttributionSource();
-        mCallback = null;
-        mServerIf = 0;
-        mTransport = transport;
-        mServices = new ArrayList<BluetoothGattService>();
-    }
-
-    /**
-     * Returns a characteristic with given handle.
-     *
-     * @hide
-     */
-    /*package*/ BluetoothGattCharacteristic getCharacteristicByHandle(int handle) {
-        for (BluetoothGattService svc : mServices) {
-            for (BluetoothGattCharacteristic charac : svc.getCharacteristics()) {
-                if (charac.getInstanceId() == handle) {
-                    return charac;
-                }
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Returns a descriptor with given handle.
-     *
-     * @hide
-     */
-    /*package*/ BluetoothGattDescriptor getDescriptorByHandle(int handle) {
-        for (BluetoothGattService svc : mServices) {
-            for (BluetoothGattCharacteristic charac : svc.getCharacteristics()) {
-                for (BluetoothGattDescriptor desc : charac.getDescriptors()) {
-                    if (desc.getInstanceId() == handle) {
-                        return desc;
-                    }
-                }
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Close this GATT server instance.
-     *
-     * Application should call this method as early as possible after it is done with
-     * this GATT server.
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public void close() {
-        if (DBG) Log.d(TAG, "close()");
-        unregisterCallback();
-    }
-
-    /**
-     * Register an application callback to start using GattServer.
-     *
-     * <p>This is an asynchronous call. The callback is used to notify
-     * success or failure if the function returns true.
-     *
-     * @param callback GATT callback handler that will receive asynchronous callbacks.
-     * @return true, the callback will be called to notify success or failure, false on immediate
-     * error
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    /*package*/ boolean registerCallback(BluetoothGattServerCallback callback) {
-        return registerCallback(callback, false);
-    }
-
-    /**
-     * Register an application callback to start using GattServer.
-     *
-     * <p>This is an asynchronous call. The callback is used to notify
-     * success or failure if the function returns true.
-     *
-     * @param callback GATT callback handler that will receive asynchronous callbacks.
-     * @param eatt_support indicates if server can use eatt
-     * @return true, the callback will be called to notify success or failure, false on immediate
-     * error
-     * @hide
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    /*package*/ boolean registerCallback(BluetoothGattServerCallback callback,
-                                         boolean eatt_support) {
-        if (DBG) Log.d(TAG, "registerCallback()");
-        if (mService == null) {
-            Log.e(TAG, "GATT service not available");
-            return false;
-        }
-        UUID uuid = UUID.randomUUID();
-        if (DBG) Log.d(TAG, "registerCallback() - UUID=" + uuid);
-
-        synchronized (mServerIfLock) {
-            if (mCallback != null) {
-                Log.e(TAG, "App can register callback only once");
-                return false;
-            }
-
-            mCallback = callback;
-            try {
-                mService.registerServer(new ParcelUuid(uuid), mBluetoothGattServerCallback,
-                        eatt_support, mAttributionSource);
-            } catch (RemoteException e) {
-                Log.e(TAG, "", e);
-                mCallback = null;
-                return false;
-            }
-
-            try {
-                mServerIfLock.wait(CALLBACK_REG_TIMEOUT);
-            } catch (InterruptedException e) {
-                Log.e(TAG, "" + e);
-                mCallback = null;
-            }
-
-            if (mServerIf == 0) {
-                mCallback = null;
-                return false;
-            } else {
-                return true;
-            }
-        }
-    }
-
-    /**
-     * Unregister the current application and callbacks.
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    private void unregisterCallback() {
-        if (DBG) Log.d(TAG, "unregisterCallback() - mServerIf=" + mServerIf);
-        if (mService == null || mServerIf == 0) return;
-
-        try {
-            mCallback = null;
-            mService.unregisterServer(mServerIf, mAttributionSource);
-            mServerIf = 0;
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        }
-    }
-
-    /**
-     * Returns a service by UUID, instance and type.
-     *
-     * @hide
-     */
-    /*package*/ BluetoothGattService getService(UUID uuid, int instanceId, int type) {
-        for (BluetoothGattService svc : mServices) {
-            if (svc.getType() == type
-                    && svc.getInstanceId() == instanceId
-                    && svc.getUuid().equals(uuid)) {
-                return svc;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Initiate a connection to a Bluetooth GATT capable device.
-     *
-     * <p>The connection may not be established right away, but will be
-     * completed when the remote device is available. A
-     * {@link BluetoothGattServerCallback#onConnectionStateChange} callback will be
-     * invoked when the connection state changes as a result of this function.
-     *
-     * <p>The autoConnect parameter determines whether to actively connect to
-     * the remote device, or rather passively scan and finalize the connection
-     * when the remote device is in range/available. Generally, the first ever
-     * connection to a device should be direct (autoConnect set to false) and
-     * subsequent connections to known devices should be invoked with the
-     * autoConnect parameter set to true.
-     *
-     * @param autoConnect Whether to directly connect to the remote device (false) or to
-     * automatically connect as soon as the remote device becomes available (true).
-     * @return true, if the connection attempt was initiated successfully
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean connect(BluetoothDevice device, boolean autoConnect) {
-        if (DBG) {
-            Log.d(TAG,
-                    "connect() - device: " + device.getAddress() + ", auto: " + autoConnect);
-        }
-        if (mService == null || mServerIf == 0) return false;
-
-        try {
-            // autoConnect is inverse of "isDirect"
-            mService.serverConnect(
-                    mServerIf, device.getAddress(), !autoConnect, mTransport, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Disconnects an established connection, or cancels a connection attempt
-     * currently in progress.
-     *
-     * @param device Remote device
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public void cancelConnection(BluetoothDevice device) {
-        if (DBG) Log.d(TAG, "cancelConnection() - device: " + device.getAddress());
-        if (mService == null || mServerIf == 0) return;
-
-        try {
-            mService.serverDisconnect(mServerIf, device.getAddress(), mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        }
-    }
-
-    /**
-     * Set the preferred connection PHY for this app. Please note that this is just a
-     * recommendation, whether the PHY change will happen depends on other applications peferences,
-     * local and remote controller capabilities. Controller can override these settings. <p> {@link
-     * BluetoothGattServerCallback#onPhyUpdate} will be triggered as a result of this call, even if
-     * no PHY change happens. It is also triggered when remote device updates the PHY.
-     *
-     * @param device The remote device to send this response to
-     * @param txPhy preferred transmitter PHY. Bitwise OR of any of {@link
-     * BluetoothDevice#PHY_LE_1M_MASK}, {@link BluetoothDevice#PHY_LE_2M_MASK}, and {@link
-     * BluetoothDevice#PHY_LE_CODED_MASK}.
-     * @param rxPhy preferred receiver PHY. Bitwise OR of any of {@link
-     * BluetoothDevice#PHY_LE_1M_MASK}, {@link BluetoothDevice#PHY_LE_2M_MASK}, and {@link
-     * BluetoothDevice#PHY_LE_CODED_MASK}.
-     * @param phyOptions preferred coding to use when transmitting on the LE Coded PHY. Can be one
-     * of {@link BluetoothDevice#PHY_OPTION_NO_PREFERRED}, {@link BluetoothDevice#PHY_OPTION_S2} or
-     * {@link BluetoothDevice#PHY_OPTION_S8}
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public void setPreferredPhy(BluetoothDevice device, int txPhy, int rxPhy, int phyOptions) {
-        try {
-            mService.serverSetPreferredPhy(mServerIf, device.getAddress(), txPhy, rxPhy,
-                    phyOptions, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        }
-    }
-
-    /**
-     * Read the current transmitter PHY and receiver PHY of the connection. The values are returned
-     * in {@link BluetoothGattServerCallback#onPhyRead}
-     *
-     * @param device The remote device to send this response to
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public void readPhy(BluetoothDevice device) {
-        try {
-            mService.serverReadPhy(mServerIf, device.getAddress(), mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        }
-    }
-
-    /**
-     * Send a response to a read or write request to a remote device.
-     *
-     * <p>This function must be invoked in when a remote read/write request
-     * is received by one of these callback methods:
-     *
-     * <ul>
-     * <li>{@link BluetoothGattServerCallback#onCharacteristicReadRequest}
-     * <li>{@link BluetoothGattServerCallback#onCharacteristicWriteRequest}
-     * <li>{@link BluetoothGattServerCallback#onDescriptorReadRequest}
-     * <li>{@link BluetoothGattServerCallback#onDescriptorWriteRequest}
-     * </ul>
-     *
-     * @param device The remote device to send this response to
-     * @param requestId The ID of the request that was received with the callback
-     * @param status The status of the request to be sent to the remote devices
-     * @param offset Value offset for partial read/write response
-     * @param value The value of the attribute that was read/written (optional)
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean sendResponse(BluetoothDevice device, int requestId,
-            int status, int offset, byte[] value) {
-        if (VDBG) Log.d(TAG, "sendResponse() - device: " + device.getAddress());
-        if (mService == null || mServerIf == 0) return false;
-
-        try {
-            mService.sendResponse(mServerIf, device.getAddress(), requestId,
-                    status, offset, value, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * Send a notification or indication that a local characteristic has been
-     * updated.
-     *
-     * <p>A notification or indication is sent to the remote device to signal
-     * that the characteristic has been updated. This function should be invoked
-     * for every client that requests notifications/indications by writing
-     * to the "Client Configuration" descriptor for the given characteristic.
-     *
-     * @param device The remote device to receive the notification/indication
-     * @param characteristic The local characteristic that has been updated
-     * @param confirm true to request confirmation from the client (indication), false to send a
-     * notification
-     * @return true, if the notification has been triggered successfully
-     * @throws IllegalArgumentException
-     *
-     * @deprecated Use {@link BluetoothGattServer#notifyCharacteristicChanged(BluetoothDevice,
-     * BluetoothGattCharacteristic, boolean, byte[])}  as this is not memory safe.
-     */
-    @Deprecated
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean notifyCharacteristicChanged(BluetoothDevice device,
-            BluetoothGattCharacteristic characteristic, boolean confirm) {
-        return notifyCharacteristicChanged(device, characteristic, confirm,
-                characteristic.getValue()) == BluetoothStatusCodes.SUCCESS;
-    }
-
-    /** @hide */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(value = {
-            BluetoothStatusCodes.SUCCESS,
-            BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION,
-            BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_PRIVILEGED_PERMISSION,
-            BluetoothStatusCodes.ERROR_DEVICE_NOT_CONNECTED,
-            BluetoothStatusCodes.ERROR_PROFILE_SERVICE_NOT_BOUND,
-            BluetoothStatusCodes.ERROR_GATT_WRITE_NOT_ALLOWED,
-            BluetoothStatusCodes.ERROR_GATT_WRITE_REQUEST_BUSY,
-            BluetoothStatusCodes.ERROR_UNKNOWN
-    })
-    public @interface NotifyCharacteristicReturnValues{}
-
-    /**
-     * Send a notification or indication that a local characteristic has been
-     * updated.
-     *
-     * <p>A notification or indication is sent to the remote device to signal
-     * that the characteristic has been updated. This function should be invoked
-     * for every client that requests notifications/indications by writing
-     * to the "Client Configuration" descriptor for the given characteristic.
-     *
-     * @param device the remote device to receive the notification/indication
-     * @param characteristic the local characteristic that has been updated
-     * @param confirm {@code true} to request confirmation from the client (indication) or
-     * {@code false} to send a notification
-     * @param value the characteristic value
-     * @return whether the notification has been triggered successfully
-     * @throws IllegalArgumentException if the characteristic value or service is null
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @NotifyCharacteristicReturnValues
-    public int notifyCharacteristicChanged(@NonNull BluetoothDevice device,
-            @NonNull BluetoothGattCharacteristic characteristic, boolean confirm,
-            @NonNull byte[] value) {
-        if (VDBG) Log.d(TAG, "notifyCharacteristicChanged() - device: " + device.getAddress());
-        if (mService == null || mServerIf == 0) {
-            return BluetoothStatusCodes.ERROR_PROFILE_SERVICE_NOT_BOUND;
-        }
-
-        if (characteristic == null) {
-            throw new IllegalArgumentException("characteristic must not be null");
-        }
-        if (device == null) {
-            throw new IllegalArgumentException("device must not be null");
-        }
-        BluetoothGattService service = characteristic.getService();
-        if (service == null) {
-            throw new IllegalArgumentException("Characteristic must have a non-null service");
-        }
-        if (value == null) {
-            throw new IllegalArgumentException("Characteristic value must not be null");
-        }
-
-        try {
-            return mService.sendNotification(mServerIf, device.getAddress(),
-                    characteristic.getInstanceId(), confirm,
-                    value, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Add a service to the list of services to be hosted.
-     *
-     * <p>Once a service has been addded to the list, the service and its
-     * included characteristics will be provided by the local device.
-     *
-     * <p>If the local device has already exposed services when this function
-     * is called, a service update notification will be sent to all clients.
-     *
-     * <p>The {@link BluetoothGattServerCallback#onServiceAdded} callback will indicate
-     * whether this service has been added successfully. Do not add another service
-     * before this callback.
-     *
-     * @param service Service to be added to the list of services provided by this device.
-     * @return true, if the request to add service has been initiated
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean addService(BluetoothGattService service) {
-        if (DBG) Log.d(TAG, "addService() - service: " + service.getUuid());
-        if (mService == null || mServerIf == 0) return false;
-
-        mPendingService = service;
-
-        try {
-            mService.addService(mServerIf, service, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Removes a service from the list of services to be provided.
-     *
-     * @param service Service to be removed.
-     * @return true, if the service has been removed
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean removeService(BluetoothGattService service) {
-        if (DBG) Log.d(TAG, "removeService() - service: " + service.getUuid());
-        if (mService == null || mServerIf == 0) return false;
-
-        BluetoothGattService intService = getService(service.getUuid(),
-                service.getInstanceId(), service.getType());
-        if (intService == null) return false;
-
-        try {
-            mService.removeService(mServerIf, service.getInstanceId(), mAttributionSource);
-            mServices.remove(intService);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Remove all services from the list of provided services.
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public void clearServices() {
-        if (DBG) Log.d(TAG, "clearServices()");
-        if (mService == null || mServerIf == 0) return;
-
-        try {
-            mService.clearServices(mServerIf, mAttributionSource);
-            mServices.clear();
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        }
-    }
-
-    /**
-     * Returns a list of GATT services offered by this device.
-     *
-     * <p>An application must call {@link #addService} to add a serice to the
-     * list of services offered by this device.
-     *
-     * @return List of services. Returns an empty list if no services have been added yet.
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresNoPermission
-    public List<BluetoothGattService> getServices() {
-        return mServices;
-    }
-
-    /**
-     * Returns a {@link BluetoothGattService} from the list of services offered
-     * by this device.
-     *
-     * <p>If multiple instances of the same service (as identified by UUID)
-     * exist, the first instance of the service is returned.
-     *
-     * @param uuid UUID of the requested service
-     * @return BluetoothGattService if supported, or null if the requested service is not offered by
-     * this device.
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresNoPermission
-    public BluetoothGattService getService(UUID uuid) {
-        for (BluetoothGattService service : mServices) {
-            if (service.getUuid().equals(uuid)) {
-                return service;
-            }
-        }
-
-        return null;
-    }
-
-
-    /**
-     * Not supported - please use {@link BluetoothManager#getConnectedDevices(int)}
-     * with {@link BluetoothProfile#GATT} as argument
-     *
-     * @throws UnsupportedOperationException
-     */
-    @Override
-    @RequiresNoPermission
-    public int getConnectionState(BluetoothDevice device) {
-        throw new UnsupportedOperationException("Use BluetoothManager#getConnectionState instead.");
-    }
-
-    /**
-     * Not supported - please use {@link BluetoothManager#getConnectedDevices(int)}
-     * with {@link BluetoothProfile#GATT} as argument
-     *
-     * @throws UnsupportedOperationException
-     */
-    @Override
-    @RequiresNoPermission
-    public List<BluetoothDevice> getConnectedDevices() {
-        throw new UnsupportedOperationException(
-                "Use BluetoothManager#getConnectedDevices instead.");
-    }
-
-    /**
-     * Not supported - please use
-     * {@link BluetoothManager#getDevicesMatchingConnectionStates(int, int[])}
-     * with {@link BluetoothProfile#GATT} as first argument
-     *
-     * @throws UnsupportedOperationException
-     */
-    @Override
-    @RequiresNoPermission
-    public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
-        throw new UnsupportedOperationException(
-                "Use BluetoothManager#getDevicesMatchingConnectionStates instead.");
-    }
-}
diff --git a/core/java/android/bluetooth/BluetoothGattServerCallback.java b/core/java/android/bluetooth/BluetoothGattServerCallback.java
deleted file mode 100644
index 0ead5f5..0000000
--- a/core/java/android/bluetooth/BluetoothGattServerCallback.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-/**
- * This abstract class is used to implement {@link BluetoothGattServer} callbacks.
- */
-public abstract class BluetoothGattServerCallback {
-
-    /**
-     * Callback indicating when a remote device has been connected or disconnected.
-     *
-     * @param device Remote device that has been connected or disconnected.
-     * @param status Status of the connect or disconnect operation.
-     * @param newState Returns the new connection state. Can be one of {@link
-     * BluetoothProfile#STATE_DISCONNECTED} or {@link BluetoothProfile#STATE_CONNECTED}
-     */
-    public void onConnectionStateChange(BluetoothDevice device, int status,
-            int newState) {
-    }
-
-    /**
-     * Indicates whether a local service has been added successfully.
-     *
-     * @param status Returns {@link BluetoothGatt#GATT_SUCCESS} if the service was added
-     * successfully.
-     * @param service The service that has been added
-     */
-    public void onServiceAdded(int status, BluetoothGattService service) {
-    }
-
-    /**
-     * A remote client has requested to read a local characteristic.
-     *
-     * <p>An application must call {@link BluetoothGattServer#sendResponse}
-     * to complete the request.
-     *
-     * @param device The remote device that has requested the read operation
-     * @param requestId The Id of the request
-     * @param offset Offset into the value of the characteristic
-     * @param characteristic Characteristic to be read
-     */
-    public void onCharacteristicReadRequest(BluetoothDevice device, int requestId,
-            int offset, BluetoothGattCharacteristic characteristic) {
-    }
-
-    /**
-     * A remote client has requested to write to a local characteristic.
-     *
-     * <p>An application must call {@link BluetoothGattServer#sendResponse}
-     * to complete the request.
-     *
-     * @param device The remote device that has requested the write operation
-     * @param requestId The Id of the request
-     * @param characteristic Characteristic to be written to.
-     * @param preparedWrite true, if this write operation should be queued for later execution.
-     * @param responseNeeded true, if the remote device requires a response
-     * @param offset The offset given for the value
-     * @param value The value the client wants to assign to the characteristic
-     */
-    public void onCharacteristicWriteRequest(BluetoothDevice device, int requestId,
-            BluetoothGattCharacteristic characteristic,
-            boolean preparedWrite, boolean responseNeeded,
-            int offset, byte[] value) {
-    }
-
-    /**
-     * A remote client has requested to read a local descriptor.
-     *
-     * <p>An application must call {@link BluetoothGattServer#sendResponse}
-     * to complete the request.
-     *
-     * @param device The remote device that has requested the read operation
-     * @param requestId The Id of the request
-     * @param offset Offset into the value of the characteristic
-     * @param descriptor Descriptor to be read
-     */
-    public void onDescriptorReadRequest(BluetoothDevice device, int requestId,
-            int offset, BluetoothGattDescriptor descriptor) {
-    }
-
-    /**
-     * A remote client has requested to write to a local descriptor.
-     *
-     * <p>An application must call {@link BluetoothGattServer#sendResponse}
-     * to complete the request.
-     *
-     * @param device The remote device that has requested the write operation
-     * @param requestId The Id of the request
-     * @param descriptor Descriptor to be written to.
-     * @param preparedWrite true, if this write operation should be queued for later execution.
-     * @param responseNeeded true, if the remote device requires a response
-     * @param offset The offset given for the value
-     * @param value The value the client wants to assign to the descriptor
-     */
-    public void onDescriptorWriteRequest(BluetoothDevice device, int requestId,
-            BluetoothGattDescriptor descriptor,
-            boolean preparedWrite, boolean responseNeeded,
-            int offset, byte[] value) {
-    }
-
-    /**
-     * Execute all pending write operations for this device.
-     *
-     * <p>An application must call {@link BluetoothGattServer#sendResponse}
-     * to complete the request.
-     *
-     * @param device The remote device that has requested the write operations
-     * @param requestId The Id of the request
-     * @param execute Whether the pending writes should be executed (true) or cancelled (false)
-     */
-    public void onExecuteWrite(BluetoothDevice device, int requestId, boolean execute) {
-    }
-
-    /**
-     * Callback invoked when a notification or indication has been sent to
-     * a remote device.
-     *
-     * <p>When multiple notifications are to be sent, an application must
-     * wait for this callback to be received before sending additional
-     * notifications.
-     *
-     * @param device The remote device the notification has been sent to
-     * @param status {@link BluetoothGatt#GATT_SUCCESS} if the operation was successful
-     */
-    public void onNotificationSent(BluetoothDevice device, int status) {
-    }
-
-    /**
-     * Callback indicating the MTU for a given device connection has changed.
-     *
-     * <p>This callback will be invoked if a remote client has requested to change
-     * the MTU for a given connection.
-     *
-     * @param device The remote device that requested the MTU change
-     * @param mtu The new MTU size
-     */
-    public void onMtuChanged(BluetoothDevice device, int mtu) {
-    }
-
-    /**
-     * Callback triggered as result of {@link BluetoothGattServer#setPreferredPhy}, or as a result
-     * of remote device changing the PHY.
-     *
-     * @param device The remote device
-     * @param txPhy the transmitter PHY in use. One of {@link BluetoothDevice#PHY_LE_1M}, {@link
-     * BluetoothDevice#PHY_LE_2M}, and {@link BluetoothDevice#PHY_LE_CODED}
-     * @param rxPhy the receiver PHY in use. One of {@link BluetoothDevice#PHY_LE_1M}, {@link
-     * BluetoothDevice#PHY_LE_2M}, and {@link BluetoothDevice#PHY_LE_CODED}
-     * @param status Status of the PHY update operation. {@link BluetoothGatt#GATT_SUCCESS} if the
-     * operation succeeds.
-     */
-    public void onPhyUpdate(BluetoothDevice device, int txPhy, int rxPhy, int status) {
-    }
-
-    /**
-     * Callback triggered as result of {@link BluetoothGattServer#readPhy}
-     *
-     * @param device The remote device that requested the PHY read
-     * @param txPhy the transmitter PHY in use. One of {@link BluetoothDevice#PHY_LE_1M}, {@link
-     * BluetoothDevice#PHY_LE_2M}, and {@link BluetoothDevice#PHY_LE_CODED}
-     * @param rxPhy the receiver PHY in use. One of {@link BluetoothDevice#PHY_LE_1M}, {@link
-     * BluetoothDevice#PHY_LE_2M}, and {@link BluetoothDevice#PHY_LE_CODED}
-     * @param status Status of the PHY read operation. {@link BluetoothGatt#GATT_SUCCESS} if the
-     * operation succeeds.
-     */
-    public void onPhyRead(BluetoothDevice device, int txPhy, int rxPhy, int status) {
-    }
-
-    /**
-     * Callback indicating the connection parameters were updated.
-     *
-     * @param device The remote device involved
-     * @param interval Connection interval used on this connection, 1.25ms unit. Valid range is from
-     * 6 (7.5ms) to 3200 (4000ms).
-     * @param latency Worker latency for the connection in number of connection events. Valid range
-     * is from 0 to 499
-     * @param timeout Supervision timeout for this connection, in 10ms unit. Valid range is from 10
-     * (0.1s) to 3200 (32s)
-     * @param status {@link BluetoothGatt#GATT_SUCCESS} if the connection has been updated
-     * successfully
-     * @hide
-     */
-    public void onConnectionUpdated(BluetoothDevice device, int interval, int latency, int timeout,
-            int status) {
-    }
-
-}
diff --git a/core/java/android/bluetooth/BluetoothGattService.java b/core/java/android/bluetooth/BluetoothGattService.java
deleted file mode 100644
index f64d09f..0000000
--- a/core/java/android/bluetooth/BluetoothGattService.java
+++ /dev/null
@@ -1,395 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.bluetooth;
-
-import android.annotation.RequiresPermission;
-import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
-import android.bluetooth.annotations.RequiresLegacyBluetoothPermission;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.os.Build;
-import android.os.Parcel;
-import android.os.ParcelUuid;
-import android.os.Parcelable;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.UUID;
-
-/**
- * Represents a Bluetooth GATT Service
- *
- * <p> Gatt Service contains a collection of {@link BluetoothGattCharacteristic},
- * as well as referenced services.
- */
-public class BluetoothGattService implements Parcelable {
-
-    /**
-     * Primary service
-     */
-    public static final int SERVICE_TYPE_PRIMARY = 0;
-
-    /**
-     * Secondary service (included by primary services)
-     */
-    public static final int SERVICE_TYPE_SECONDARY = 1;
-
-
-    /**
-     * The remote device this service is associated with.
-     * This applies to client applications only.
-     *
-     * @hide
-     */
-    @UnsupportedAppUsage
-    protected BluetoothDevice mDevice;
-
-    /**
-     * The UUID of this service.
-     *
-     * @hide
-     */
-    protected UUID mUuid;
-
-    /**
-     * Instance ID for this service.
-     *
-     * @hide
-     */
-    protected int mInstanceId;
-
-    /**
-     * Handle counter override (for conformance testing).
-     *
-     * @hide
-     */
-    protected int mHandles = 0;
-
-    /**
-     * Service type (Primary/Secondary).
-     *
-     * @hide
-     */
-    protected int mServiceType;
-
-    /**
-     * List of characteristics included in this service.
-     */
-    protected List<BluetoothGattCharacteristic> mCharacteristics;
-
-    /**
-     * List of included services for this service.
-     */
-    protected List<BluetoothGattService> mIncludedServices;
-
-    /**
-     * Whether the service uuid should be advertised.
-     */
-    private boolean mAdvertisePreferred;
-
-    /**
-     * Create a new BluetoothGattService.
-     *
-     * @param uuid The UUID for this service
-     * @param serviceType The type of this service,
-     * {@link BluetoothGattService#SERVICE_TYPE_PRIMARY}
-     * or {@link BluetoothGattService#SERVICE_TYPE_SECONDARY}
-     */
-    public BluetoothGattService(UUID uuid, int serviceType) {
-        mDevice = null;
-        mUuid = uuid;
-        mInstanceId = 0;
-        mServiceType = serviceType;
-        mCharacteristics = new ArrayList<BluetoothGattCharacteristic>();
-        mIncludedServices = new ArrayList<BluetoothGattService>();
-    }
-
-    /**
-     * Create a new BluetoothGattService
-     *
-     * @hide
-     */
-    /*package*/ BluetoothGattService(BluetoothDevice device, UUID uuid,
-            int instanceId, int serviceType) {
-        mDevice = device;
-        mUuid = uuid;
-        mInstanceId = instanceId;
-        mServiceType = serviceType;
-        mCharacteristics = new ArrayList<BluetoothGattCharacteristic>();
-        mIncludedServices = new ArrayList<BluetoothGattService>();
-    }
-
-    /**
-     * Create a new BluetoothGattService
-     *
-     * @hide
-     */
-    public BluetoothGattService(UUID uuid, int instanceId, int serviceType) {
-        mDevice = null;
-        mUuid = uuid;
-        mInstanceId = instanceId;
-        mServiceType = serviceType;
-        mCharacteristics = new ArrayList<BluetoothGattCharacteristic>();
-        mIncludedServices = new ArrayList<BluetoothGattService>();
-    }
-
-    /**
-     * @hide
-     */
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeParcelable(new ParcelUuid(mUuid), 0);
-        out.writeInt(mInstanceId);
-        out.writeInt(mServiceType);
-        out.writeTypedList(mCharacteristics);
-
-        ArrayList<BluetoothGattIncludedService> includedServices =
-                new ArrayList<BluetoothGattIncludedService>(mIncludedServices.size());
-        for (BluetoothGattService s : mIncludedServices) {
-            includedServices.add(new BluetoothGattIncludedService(s.getUuid(),
-                    s.getInstanceId(), s.getType()));
-        }
-        out.writeTypedList(includedServices);
-    }
-
-    public static final @android.annotation.NonNull Parcelable.Creator<BluetoothGattService> CREATOR =
-            new Parcelable.Creator<BluetoothGattService>() {
-        public BluetoothGattService createFromParcel(Parcel in) {
-            return new BluetoothGattService(in);
-        }
-
-        public BluetoothGattService[] newArray(int size) {
-            return new BluetoothGattService[size];
-        }
-    };
-
-    private BluetoothGattService(Parcel in) {
-        mUuid = ((ParcelUuid) in.readParcelable(null)).getUuid();
-        mInstanceId = in.readInt();
-        mServiceType = in.readInt();
-
-        mCharacteristics = new ArrayList<BluetoothGattCharacteristic>();
-
-        ArrayList<BluetoothGattCharacteristic> chrcs =
-                in.createTypedArrayList(BluetoothGattCharacteristic.CREATOR);
-        if (chrcs != null) {
-            for (BluetoothGattCharacteristic chrc : chrcs) {
-                chrc.setService(this);
-                mCharacteristics.add(chrc);
-            }
-        }
-
-        mIncludedServices = new ArrayList<BluetoothGattService>();
-
-        ArrayList<BluetoothGattIncludedService> inclSvcs =
-                in.createTypedArrayList(BluetoothGattIncludedService.CREATOR);
-        if (chrcs != null) {
-            for (BluetoothGattIncludedService isvc : inclSvcs) {
-                mIncludedServices.add(new BluetoothGattService(null, isvc.getUuid(),
-                        isvc.getInstanceId(), isvc.getType()));
-            }
-        }
-    }
-
-    /**
-     * Returns the device associated with this service.
-     *
-     * @hide
-     */
-    /*package*/ BluetoothDevice getDevice() {
-        return mDevice;
-    }
-
-    /**
-     * Returns the device associated with this service.
-     *
-     * @hide
-     */
-    /*package*/ void setDevice(BluetoothDevice device) {
-        mDevice = device;
-    }
-
-    /**
-     * Add an included service to this service.
-     *
-     * @param service The service to be added
-     * @return true, if the included service was added to the service
-     */
-    @RequiresLegacyBluetoothPermission
-    public boolean addService(BluetoothGattService service) {
-        mIncludedServices.add(service);
-        return true;
-    }
-
-    /**
-     * Add a characteristic to this service.
-     *
-     * @param characteristic The characteristics to be added
-     * @return true, if the characteristic was added to the service
-     */
-    @RequiresLegacyBluetoothPermission
-    public boolean addCharacteristic(BluetoothGattCharacteristic characteristic) {
-        mCharacteristics.add(characteristic);
-        characteristic.setService(this);
-        return true;
-    }
-
-    /**
-     * Get characteristic by UUID and instanceId.
-     *
-     * @hide
-     */
-    /*package*/ BluetoothGattCharacteristic getCharacteristic(UUID uuid, int instanceId) {
-        for (BluetoothGattCharacteristic characteristic : mCharacteristics) {
-            if (uuid.equals(characteristic.getUuid())
-                    && characteristic.getInstanceId() == instanceId) {
-                return characteristic;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Force the instance ID.
-     *
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public void setInstanceId(int instanceId) {
-        mInstanceId = instanceId;
-    }
-
-    /**
-     * Get the handle count override (conformance testing.
-     *
-     * @hide
-     */
-    /*package*/ int getHandles() {
-        return mHandles;
-    }
-
-    /**
-     * Force the number of handles to reserve for this service.
-     * This is needed for conformance testing only.
-     *
-     * @hide
-     */
-    public void setHandles(int handles) {
-        mHandles = handles;
-    }
-
-    /**
-     * Add an included service to the internal map.
-     *
-     * @hide
-     */
-    public void addIncludedService(BluetoothGattService includedService) {
-        mIncludedServices.add(includedService);
-    }
-
-    /**
-     * Returns the UUID of this service
-     *
-     * @return UUID of this service
-     */
-    public UUID getUuid() {
-        return mUuid;
-    }
-
-    /**
-     * Returns the instance ID for this service
-     *
-     * <p>If a remote device offers multiple services with the same UUID
-     * (ex. multiple battery services for different batteries), the instance
-     * ID is used to distuinguish services.
-     *
-     * @return Instance ID of this service
-     */
-    public int getInstanceId() {
-        return mInstanceId;
-    }
-
-    /**
-     * Get the type of this service (primary/secondary)
-     */
-    public int getType() {
-        return mServiceType;
-    }
-
-    /**
-     * Get the list of included GATT services for this service.
-     *
-     * @return List of included services or empty list if no included services were discovered.
-     */
-    public List<BluetoothGattService> getIncludedServices() {
-        return mIncludedServices;
-    }
-
-    /**
-     * Returns a list of characteristics included in this service.
-     *
-     * @return Characteristics included in this service
-     */
-    public List<BluetoothGattCharacteristic> getCharacteristics() {
-        return mCharacteristics;
-    }
-
-    /**
-     * Returns a characteristic with a given UUID out of the list of
-     * characteristics offered by this service.
-     *
-     * <p>This is a convenience function to allow access to a given characteristic
-     * without enumerating over the list returned by {@link #getCharacteristics}
-     * manually.
-     *
-     * <p>If a remote service offers multiple characteristics with the same
-     * UUID, the first instance of a characteristic with the given UUID
-     * is returned.
-     *
-     * @return GATT characteristic object or null if no characteristic with the given UUID was
-     * found.
-     */
-    public BluetoothGattCharacteristic getCharacteristic(UUID uuid) {
-        for (BluetoothGattCharacteristic characteristic : mCharacteristics) {
-            if (uuid.equals(characteristic.getUuid())) {
-                return characteristic;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Returns whether the uuid of the service should be advertised.
-     *
-     * @hide
-     */
-    public boolean isAdvertisePreferred() {
-        return mAdvertisePreferred;
-    }
-
-    /**
-     * Set whether the service uuid should be advertised.
-     *
-     * @hide
-     */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    public void setAdvertisePreferred(boolean advertisePreferred) {
-        mAdvertisePreferred = advertisePreferred;
-    }
-}
diff --git a/core/java/android/bluetooth/BluetoothHeadset.java b/core/java/android/bluetooth/BluetoothHeadset.java
deleted file mode 100644
index 1b141c9..0000000
--- a/core/java/android/bluetooth/BluetoothHeadset.java
+++ /dev/null
@@ -1,1505 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-import static android.bluetooth.BluetoothUtils.getSyncTimeout;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.RequiresPermission;
-import android.annotation.SdkConstant;
-import android.annotation.SdkConstant.SdkConstantType;
-import android.annotation.SuppressLint;
-import android.annotation.SystemApi;
-import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
-import android.bluetooth.annotations.RequiresLegacyBluetoothAdminPermission;
-import android.bluetooth.annotations.RequiresLegacyBluetoothPermission;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.content.AttributionSource;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.os.Build;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.Message;
-import android.os.RemoteException;
-import android.util.CloseGuard;
-import android.util.Log;
-
-import com.android.modules.utils.SynchronousResultReceiver;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.TimeoutException;
-
-/**
- * Public API for controlling the Bluetooth Headset Service. This includes both
- * Bluetooth Headset and Handsfree (v1.5) profiles.
- *
- * <p>BluetoothHeadset is a proxy object for controlling the Bluetooth Headset
- * Service via IPC.
- *
- * <p> Use {@link BluetoothAdapter#getProfileProxy} to get
- * the BluetoothHeadset proxy object. Use
- * {@link BluetoothAdapter#closeProfileProxy} to close the service connection.
- *
- * <p> Android only supports one connected Bluetooth Headset at a time.
- * Each method is protected with its appropriate permission.
- */
-public final class BluetoothHeadset implements BluetoothProfile {
-    private static final String TAG = "BluetoothHeadset";
-    private static final boolean DBG = true;
-    private static final boolean VDBG = false;
-
-    /**
-     * Intent used to broadcast the change in connection state of the Headset
-     * profile.
-     *
-     * <p>This intent will have 3 extras:
-     * <ul>
-     * <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
-     * <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile. </li>
-     * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
-     * </ul>
-     * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
-     * {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTING},
-     * {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTING}.
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_CONNECTION_STATE_CHANGED =
-            "android.bluetooth.headset.profile.action.CONNECTION_STATE_CHANGED";
-
-    /**
-     * Intent used to broadcast the change in the Audio Connection state of the
-     * HFP profile.
-     *
-     * <p>This intent will have 3 extras:
-     * <ul>
-     * <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
-     * <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile. </li>
-     * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
-     * </ul>
-     * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
-     * {@link #STATE_AUDIO_CONNECTED}, {@link #STATE_AUDIO_DISCONNECTED},
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_AUDIO_STATE_CHANGED =
-            "android.bluetooth.headset.profile.action.AUDIO_STATE_CHANGED";
-
-    /**
-     * Intent used to broadcast the selection of a connected device as active.
-     *
-     * <p>This intent will have one extra:
-     * <ul>
-     * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. It can
-     * be null if no device is active. </li>
-     * </ul>
-     *
-     * @hide
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    @UnsupportedAppUsage(trackingBug = 171933273)
-    public static final String ACTION_ACTIVE_DEVICE_CHANGED =
-            "android.bluetooth.headset.profile.action.ACTIVE_DEVICE_CHANGED";
-
-    /**
-     * Intent used to broadcast that the headset has posted a
-     * vendor-specific event.
-     *
-     * <p>This intent will have 4 extras and 1 category.
-     * <ul>
-     * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote Bluetooth Device
-     * </li>
-     * <li> {@link #EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD} - The vendor
-     * specific command </li>
-     * <li> {@link #EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE} - The AT
-     * command type which can be one of  {@link #AT_CMD_TYPE_READ},
-     * {@link #AT_CMD_TYPE_TEST}, or {@link #AT_CMD_TYPE_SET},
-     * {@link #AT_CMD_TYPE_BASIC},{@link #AT_CMD_TYPE_ACTION}. </li>
-     * <li> {@link #EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_ARGS} - Command
-     * arguments. </li>
-     * </ul>
-     *
-     * <p> The category is the Company ID of the vendor defining the
-     * vendor-specific command. {@link BluetoothAssignedNumbers}
-     *
-     * For example, for Plantronics specific events
-     * Category will be {@link #VENDOR_SPECIFIC_HEADSET_EVENT_COMPANY_ID_CATEGORY}.55
-     *
-     * <p> For example, an AT+XEVENT=foo,3 will get translated into
-     * <ul>
-     * <li> EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD = +XEVENT </li>
-     * <li> EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE = AT_CMD_TYPE_SET </li>
-     * <li> EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_ARGS = foo, 3 </li>
-     * </ul>
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_VENDOR_SPECIFIC_HEADSET_EVENT =
-            "android.bluetooth.headset.action.VENDOR_SPECIFIC_HEADSET_EVENT";
-
-    /**
-     * A String extra field in {@link #ACTION_VENDOR_SPECIFIC_HEADSET_EVENT}
-     * intents that contains the name of the vendor-specific command.
-     */
-    public static final String EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD =
-            "android.bluetooth.headset.extra.VENDOR_SPECIFIC_HEADSET_EVENT_CMD";
-
-    /**
-     * An int extra field in {@link #ACTION_VENDOR_SPECIFIC_HEADSET_EVENT}
-     * intents that contains the AT command type of the vendor-specific command.
-     */
-    public static final String EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE =
-            "android.bluetooth.headset.extra.VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE";
-
-    /**
-     * AT command type READ used with
-     * {@link #EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE}
-     * For example, AT+VGM?. There are no arguments for this command type.
-     */
-    public static final int AT_CMD_TYPE_READ = 0;
-
-    /**
-     * AT command type TEST used with
-     * {@link #EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE}
-     * For example, AT+VGM=?. There are no arguments for this command type.
-     */
-    public static final int AT_CMD_TYPE_TEST = 1;
-
-    /**
-     * AT command type SET used with
-     * {@link #EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE}
-     * For example, AT+VGM=<args>.
-     */
-    public static final int AT_CMD_TYPE_SET = 2;
-
-    /**
-     * AT command type BASIC used with
-     * {@link #EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE}
-     * For example, ATD. Single character commands and everything following the
-     * character are arguments.
-     */
-    public static final int AT_CMD_TYPE_BASIC = 3;
-
-    /**
-     * AT command type ACTION used with
-     * {@link #EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE}
-     * For example, AT+CHUP. There are no arguments for action commands.
-     */
-    public static final int AT_CMD_TYPE_ACTION = 4;
-
-    /**
-     * A Parcelable String array extra field in
-     * {@link #ACTION_VENDOR_SPECIFIC_HEADSET_EVENT} intents that contains
-     * the arguments to the vendor-specific command.
-     */
-    public static final String EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_ARGS =
-            "android.bluetooth.headset.extra.VENDOR_SPECIFIC_HEADSET_EVENT_ARGS";
-
-    /**
-     * The intent category to be used with {@link #ACTION_VENDOR_SPECIFIC_HEADSET_EVENT}
-     * for the companyId
-     */
-    public static final String VENDOR_SPECIFIC_HEADSET_EVENT_COMPANY_ID_CATEGORY =
-            "android.bluetooth.headset.intent.category.companyid";
-
-    /**
-     * A vendor-specific command for unsolicited result code.
-     */
-    public static final String VENDOR_RESULT_CODE_COMMAND_ANDROID = "+ANDROID";
-
-    /**
-     * A vendor-specific AT command
-     *
-     * @hide
-     */
-    public static final String VENDOR_SPECIFIC_HEADSET_EVENT_XAPL = "+XAPL";
-
-    /**
-     * A vendor-specific AT command
-     *
-     * @hide
-     */
-    public static final String VENDOR_SPECIFIC_HEADSET_EVENT_IPHONEACCEV = "+IPHONEACCEV";
-
-    /**
-     * Battery level indicator associated with
-     * {@link #VENDOR_SPECIFIC_HEADSET_EVENT_IPHONEACCEV}
-     *
-     * @hide
-     */
-    public static final int VENDOR_SPECIFIC_HEADSET_EVENT_IPHONEACCEV_BATTERY_LEVEL = 1;
-
-    /**
-     * A vendor-specific AT command
-     *
-     * @hide
-     */
-    public static final String VENDOR_SPECIFIC_HEADSET_EVENT_XEVENT = "+XEVENT";
-
-    /**
-     * Battery level indicator associated with {@link #VENDOR_SPECIFIC_HEADSET_EVENT_XEVENT}
-     *
-     * @hide
-     */
-    public static final String VENDOR_SPECIFIC_HEADSET_EVENT_XEVENT_BATTERY_LEVEL = "BATTERY";
-
-    /**
-     * Headset state when SCO audio is not connected.
-     * This state can be one of
-     * {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} of
-     * {@link #ACTION_AUDIO_STATE_CHANGED} intent.
-     */
-    public static final int STATE_AUDIO_DISCONNECTED = 10;
-
-    /**
-     * Headset state when SCO audio is connecting.
-     * This state can be one of
-     * {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} of
-     * {@link #ACTION_AUDIO_STATE_CHANGED} intent.
-     */
-    public static final int STATE_AUDIO_CONNECTING = 11;
-
-    /**
-     * Headset state when SCO audio is connected.
-     * This state can be one of
-     * {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} of
-     * {@link #ACTION_AUDIO_STATE_CHANGED} intent.
-     */
-    public static final int STATE_AUDIO_CONNECTED = 12;
-
-    /**
-     * Intent used to broadcast the headset's indicator status
-     *
-     * <p>This intent will have 3 extras:
-     * <ul>
-     * <li> {@link #EXTRA_HF_INDICATORS_IND_ID} - The Assigned number of headset Indicator which
-     * is supported by the headset ( as indicated by AT+BIND command in the SLC
-     * sequence) or whose value is changed (indicated by AT+BIEV command) </li>
-     * <li> {@link #EXTRA_HF_INDICATORS_IND_VALUE} - Updated value of headset indicator. </li>
-     * <li> {@link BluetoothDevice#EXTRA_DEVICE} - Remote device. </li>
-     * </ul>
-     * <p>{@link #EXTRA_HF_INDICATORS_IND_ID} is defined by Bluetooth SIG and each of the indicators
-     * are given an assigned number. Below shows the assigned number of Indicator added so far
-     * - Enhanced Safety - 1, Valid Values: 0 - Disabled, 1 - Enabled
-     * - Battery Level - 2, Valid Values: 0~100 - Remaining level of Battery
-     *
-     * @hide
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_HF_INDICATORS_VALUE_CHANGED =
-            "android.bluetooth.headset.action.HF_INDICATORS_VALUE_CHANGED";
-
-    /**
-     * A int extra field in {@link #ACTION_HF_INDICATORS_VALUE_CHANGED}
-     * intents that contains the assigned number of the headset indicator as defined by
-     * Bluetooth SIG that is being sent. Value range is 0-65535 as defined in HFP 1.7
-     *
-     * @hide
-     */
-    public static final String EXTRA_HF_INDICATORS_IND_ID =
-            "android.bluetooth.headset.extra.HF_INDICATORS_IND_ID";
-
-    /**
-     * A int extra field in {@link #ACTION_HF_INDICATORS_VALUE_CHANGED}
-     * intents that contains the value of the Headset indicator that is being sent.
-     *
-     * @hide
-     */
-    public static final String EXTRA_HF_INDICATORS_IND_VALUE =
-            "android.bluetooth.headset.extra.HF_INDICATORS_IND_VALUE";
-
-    private static final int MESSAGE_HEADSET_SERVICE_CONNECTED = 100;
-    private static final int MESSAGE_HEADSET_SERVICE_DISCONNECTED = 101;
-
-    private final CloseGuard mCloseGuard = new CloseGuard();
-
-    private Context mContext;
-    private ServiceListener mServiceListener;
-    private volatile IBluetoothHeadset mService;
-    private final BluetoothAdapter mAdapter;
-    private final AttributionSource mAttributionSource;
-
-    @SuppressLint("AndroidFrameworkBluetoothPermission")
-    private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
-            new IBluetoothStateChangeCallback.Stub() {
-                public void onBluetoothStateChange(boolean up) {
-                    if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
-                    if (!up) {
-                        doUnbind();
-                    } else {
-                        doBind();
-                    }
-                }
-            };
-
-    /**
-     * Create a BluetoothHeadset proxy object.
-     */
-    /* package */ BluetoothHeadset(Context context, ServiceListener l, BluetoothAdapter adapter) {
-        mContext = context;
-        mServiceListener = l;
-        mAdapter = adapter;
-        mAttributionSource = adapter.getAttributionSource();
-
-        // Preserve legacy compatibility where apps were depending on
-        // registerStateChangeCallback() performing a permissions check which
-        // has been relaxed in modern platform versions
-        if (context.getApplicationInfo().targetSdkVersion <= Build.VERSION_CODES.R
-                && context.checkSelfPermission(android.Manifest.permission.BLUETOOTH)
-                        != PackageManager.PERMISSION_GRANTED) {
-            throw new SecurityException("Need BLUETOOTH permission");
-        }
-
-        IBluetoothManager mgr = mAdapter.getBluetoothManager();
-        if (mgr != null) {
-            try {
-                mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
-            } catch (RemoteException e) {
-                Log.e(TAG, "", e);
-            }
-        }
-
-        doBind();
-        mCloseGuard.open("close");
-    }
-
-    private boolean doBind() {
-        synchronized (mConnection) {
-            if (mService == null) {
-                if (VDBG) Log.d(TAG, "Binding service...");
-                try {
-                    return mAdapter.getBluetoothManager().bindBluetoothProfileService(
-                            BluetoothProfile.HEADSET, mConnection);
-                } catch (RemoteException e) {
-                    Log.e(TAG, "Unable to bind HeadsetService", e);
-                }
-            }
-        }
-        return false;
-    }
-
-    private void doUnbind() {
-        synchronized (mConnection) {
-            if (mService != null) {
-                if (VDBG) Log.d(TAG, "Unbinding service...");
-                try {
-                    mAdapter.getBluetoothManager().unbindBluetoothProfileService(
-                            BluetoothProfile.HEADSET, mConnection);
-                } catch (RemoteException e) {
-                    Log.e(TAG, "Unable to unbind HeadsetService", e);
-                } finally {
-                    mService = null;
-                }
-            }
-        }
-    }
-
-    /**
-     * Close the connection to the backing service.
-     * Other public functions of BluetoothHeadset will return default error
-     * results once close() has been called. Multiple invocations of close()
-     * are ok.
-     */
-    @UnsupportedAppUsage
-    /*package*/ void close() {
-        if (VDBG) log("close()");
-
-        IBluetoothManager mgr = mAdapter.getBluetoothManager();
-        if (mgr != null) {
-            try {
-                mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
-            } catch (RemoteException re) {
-                Log.e(TAG, "", re);
-            }
-        }
-        mServiceListener = null;
-        doUnbind();
-        mCloseGuard.close();
-    }
-
-    /** {@hide} */
-    @Override
-    protected void finalize() throws Throwable {
-        mCloseGuard.warnIfOpen();
-        close();
-    }
-
-    /**
-     * Initiate connection to a profile of the remote bluetooth device.
-     *
-     * <p> Currently, the system supports only 1 connection to the
-     * headset/handsfree profile. The API will automatically disconnect connected
-     * devices before connecting.
-     *
-     * <p> This API returns false in scenarios like the profile on the
-     * device is already connected or Bluetooth is not turned on.
-     * When this API returns true, it is guaranteed that
-     * connection state intent for the profile will be broadcasted with
-     * the state. Users can get the connection state of the profile
-     * from this intent.
-     *
-     * @param device Remote Bluetooth Device
-     * @return false on immediate error, true otherwise
-     * @hide
-     */
-    @SystemApi
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.MODIFY_PHONE_STATE,
-    })
-    public boolean connect(BluetoothDevice device) {
-        if (DBG) log("connect(" + device + ")");
-        final IBluetoothHeadset service = mService;
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.connectWithAttribution(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Initiate disconnection from a profile
-     *
-     * <p> This API will return false in scenarios like the profile on the
-     * Bluetooth device is not in connected state etc. When this API returns,
-     * true, it is guaranteed that the connection state change
-     * intent will be broadcasted with the state. Users can get the
-     * disconnection state of the profile from this intent.
-     *
-     * <p> If the disconnection is initiated by a remote device, the state
-     * will transition from {@link #STATE_CONNECTED} to
-     * {@link #STATE_DISCONNECTED}. If the disconnect is initiated by the
-     * host (local) device the state will transition from
-     * {@link #STATE_CONNECTED} to state {@link #STATE_DISCONNECTING} to
-     * state {@link #STATE_DISCONNECTED}. The transition to
-     * {@link #STATE_DISCONNECTING} can be used to distinguish between the
-     * two scenarios.
-     *
-     * @param device Remote Bluetooth Device
-     * @return false on immediate error, true otherwise
-     * @hide
-     */
-    @SystemApi
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean disconnect(BluetoothDevice device) {
-        if (DBG) log("disconnect(" + device + ")");
-        final IBluetoothHeadset service = mService;
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.disconnectWithAttribution(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public List<BluetoothDevice> getConnectedDevices() {
-        if (VDBG) log("getConnectedDevices()");
-        final IBluetoothHeadset service = mService;
-        final List<BluetoothDevice> defaultValue = new ArrayList<BluetoothDevice>();
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<List<BluetoothDevice>> recv =
-                        new SynchronousResultReceiver();
-                service.getConnectedDevicesWithAttribution(mAttributionSource, recv);
-                return Attributable.setAttributionSource(
-                        recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
-                        mAttributionSource);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
-        if (VDBG) log("getDevicesMatchingStates()");
-        final IBluetoothHeadset service = mService;
-        final List<BluetoothDevice> defaultValue = new ArrayList<BluetoothDevice>();
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<List<BluetoothDevice>> recv =
-                        new SynchronousResultReceiver();
-                service.getDevicesMatchingConnectionStates(states, mAttributionSource, recv);
-                return Attributable.setAttributionSource(
-                        recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
-                        mAttributionSource);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public int getConnectionState(BluetoothDevice device) {
-        if (VDBG) log("getConnectionState(" + device + ")");
-        final IBluetoothHeadset service = mService;
-        final int defaultValue = BluetoothProfile.STATE_DISCONNECTED;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
-                service.getConnectionStateWithAttribution(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Set priority of the profile
-     *
-     * <p> The device should already be paired.
-     * Priority can be one of {@link BluetoothProfile#PRIORITY_ON} or
-     * {@link BluetoothProfile#PRIORITY_OFF}
-     *
-     * @param device Paired bluetooth device
-     * @param priority
-     * @return true if priority is set, false on error
-     * @hide
-     * @deprecated Replaced with {@link #setConnectionPolicy(BluetoothDevice, int)}
-     * @removed
-     */
-    @Deprecated
-    @SystemApi
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.MODIFY_PHONE_STATE,
-    })
-    public boolean setPriority(BluetoothDevice device, int priority) {
-        if (DBG) log("setPriority(" + device + ", " + priority + ")");
-        return setConnectionPolicy(device, BluetoothAdapter.priorityToConnectionPolicy(priority));
-    }
-
-    /**
-     * Set connection policy of the profile
-     *
-     * <p> The device should already be paired.
-     * Connection policy can be one of {@link #CONNECTION_POLICY_ALLOWED},
-     * {@link #CONNECTION_POLICY_FORBIDDEN}, {@link #CONNECTION_POLICY_UNKNOWN}
-     *
-     * @param device Paired bluetooth device
-     * @param connectionPolicy is the connection policy to set to for this profile
-     * @return true if connectionPolicy is set, false on error
-     * @hide
-     */
-    @SystemApi
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-            android.Manifest.permission.MODIFY_PHONE_STATE,
-    })
-    public boolean setConnectionPolicy(@NonNull BluetoothDevice device,
-            @ConnectionPolicy int connectionPolicy) {
-        if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
-        final IBluetoothHeadset service = mService;
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)
-                && (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_FORBIDDEN
-                    || connectionPolicy == BluetoothProfile.CONNECTION_POLICY_ALLOWED)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.setConnectionPolicy(device, connectionPolicy, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Get the priority of the profile.
-     *
-     * <p> The priority can be any of:
-     * {@link #PRIORITY_AUTO_CONNECT}, {@link #PRIORITY_OFF},
-     * {@link #PRIORITY_ON}, {@link #PRIORITY_UNDEFINED}
-     *
-     * @param device Bluetooth device
-     * @return priority of the device
-     * @hide
-     */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public int getPriority(BluetoothDevice device) {
-        if (VDBG) log("getPriority(" + device + ")");
-        return BluetoothAdapter.connectionPolicyToPriority(getConnectionPolicy(device));
-    }
-
-    /**
-     * Get the connection policy of the profile.
-     *
-     * <p> The connection policy can be any of:
-     * {@link #CONNECTION_POLICY_ALLOWED}, {@link #CONNECTION_POLICY_FORBIDDEN},
-     * {@link #CONNECTION_POLICY_UNKNOWN}
-     *
-     * @param device Bluetooth device
-     * @return connection policy of the device
-     * @hide
-     */
-    @SystemApi
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public @ConnectionPolicy int getConnectionPolicy(@NonNull BluetoothDevice device) {
-        if (VDBG) log("getConnectionPolicy(" + device + ")");
-        final IBluetoothHeadset service = mService;
-        final int defaultValue = BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
-                service.getConnectionPolicy(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Checks whether the headset supports some form of noise reduction
-     *
-     * @param device Bluetooth device
-     * @return true if echo cancellation and/or noise reduction is supported, false otherwise
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean isNoiseReductionSupported(@NonNull BluetoothDevice device) {
-        if (DBG) log("isNoiseReductionSupported()");
-        final IBluetoothHeadset service = mService;
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.isNoiseReductionSupported(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Checks whether the headset supports voice recognition
-     *
-     * @param device Bluetooth device
-     * @return true if voice recognition is supported, false otherwise
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean isVoiceRecognitionSupported(@NonNull BluetoothDevice device) {
-        if (DBG) log("isVoiceRecognitionSupported()");
-        final IBluetoothHeadset service = mService;
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.isVoiceRecognitionSupported(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Start Bluetooth voice recognition. This methods sends the voice
-     * recognition AT command to the headset and establishes the
-     * audio connection.
-     *
-     * <p> Users can listen to {@link #ACTION_AUDIO_STATE_CHANGED}.
-     * If this function returns true, this intent will be broadcasted with
-     * {@link #EXTRA_STATE} set to {@link #STATE_AUDIO_CONNECTING}.
-     *
-     * <p> {@link #EXTRA_STATE} will transition from
-     * {@link #STATE_AUDIO_CONNECTING} to {@link #STATE_AUDIO_CONNECTED} when
-     * audio connection is established and to {@link #STATE_AUDIO_DISCONNECTED}
-     * in case of failure to establish the audio connection.
-     *
-     * @param device Bluetooth headset
-     * @return false if there is no headset connected, or the connected headset doesn't support
-     * voice recognition, or voice recognition is already started, or audio channel is occupied,
-     * or on error, true otherwise
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.MODIFY_PHONE_STATE,
-    })
-    public boolean startVoiceRecognition(BluetoothDevice device) {
-        if (DBG) log("startVoiceRecognition()");
-        final IBluetoothHeadset service = mService;
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.startVoiceRecognition(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Stop Bluetooth Voice Recognition mode, and shut down the
-     * Bluetooth audio path.
-     *
-     * <p> Users can listen to {@link #ACTION_AUDIO_STATE_CHANGED}.
-     * If this function returns true, this intent will be broadcasted with
-     * {@link #EXTRA_STATE} set to {@link #STATE_AUDIO_DISCONNECTED}.
-     *
-     * @param device Bluetooth headset
-     * @return false if there is no headset connected, or voice recognition has not started,
-     * or voice recognition has ended on this headset, or on error, true otherwise
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean stopVoiceRecognition(BluetoothDevice device) {
-        if (DBG) log("stopVoiceRecognition()");
-        final IBluetoothHeadset service = mService;
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.stopVoiceRecognition(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Check if Bluetooth SCO audio is connected.
-     *
-     * @param device Bluetooth headset
-     * @return true if SCO is connected, false otherwise or on error
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean isAudioConnected(BluetoothDevice device) {
-        if (VDBG) log("isAudioConnected()");
-        final IBluetoothHeadset service = mService;
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.isAudioConnected(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Indicates if current platform supports voice dialing over bluetooth SCO.
-     *
-     * @return true if voice dialing over bluetooth is supported, false otherwise.
-     * @hide
-     */
-    public static boolean isBluetoothVoiceDialingEnabled(Context context) {
-        return context.getResources().getBoolean(
-                com.android.internal.R.bool.config_bluetooth_sco_off_call);
-    }
-
-    /**
-     * Get the current audio state of the Headset.
-     * Note: This is an internal function and shouldn't be exposed
-     *
-     * @hide
-     */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public int getAudioState(BluetoothDevice device) {
-        if (VDBG) log("getAudioState");
-        final IBluetoothHeadset service = mService;
-        final int defaultValue = BluetoothHeadset.STATE_AUDIO_DISCONNECTED;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (!isDisabled()) {
-            try {
-                final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
-                service.getAudioState(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Sets whether audio routing is allowed. When set to {@code false}, the AG will not route any
-     * audio to the HF unless explicitly told to.
-     * This method should be used in cases where the SCO channel is shared between multiple profiles
-     * and must be delegated by a source knowledgeable
-     * Note: This is an internal function and shouldn't be exposed
-     *
-     * @param allowed {@code true} if the profile can reroute audio, {@code false} otherwise.
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public void setAudioRouteAllowed(boolean allowed) {
-        if (VDBG) log("setAudioRouteAllowed");
-        final IBluetoothHeadset service = mService;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver recv = new SynchronousResultReceiver();
-                service.setAudioRouteAllowed(allowed, mAttributionSource, recv);
-                recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(null);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-    }
-
-    /**
-     * Returns whether audio routing is allowed. see {@link #setAudioRouteAllowed(boolean)}.
-     * Note: This is an internal function and shouldn't be exposed
-     *
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean getAudioRouteAllowed() {
-        if (VDBG) log("getAudioRouteAllowed");
-        final IBluetoothHeadset service = mService;
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.getAudioRouteAllowed(mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Force SCO audio to be opened regardless any other restrictions
-     *
-     * @param forced Whether or not SCO audio connection should be forced: True to force SCO audio
-     * False to use SCO audio in normal manner
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public void setForceScoAudio(boolean forced) {
-        if (VDBG) log("setForceScoAudio " + String.valueOf(forced));
-        final IBluetoothHeadset service = mService;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver recv = new SynchronousResultReceiver();
-                service.setForceScoAudio(forced, mAttributionSource, recv);
-                recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(null);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-    }
-
-    /**
-     * Check if at least one headset's SCO audio is connected or connecting
-     *
-     * @return true if at least one device's SCO audio is connected or connecting, false otherwise
-     * or on error
-     * @hide
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean isAudioOn() {
-        if (VDBG) log("isAudioOn()");
-        final IBluetoothHeadset service = mService;
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.isAudioOn(mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Initiates a connection of headset audio to the current active device
-     *
-     * <p> Users can listen to {@link #ACTION_AUDIO_STATE_CHANGED}.
-     * If this function returns true, this intent will be broadcasted with
-     * {@link #EXTRA_STATE} set to {@link #STATE_AUDIO_CONNECTING}.
-     *
-     * <p> {@link #EXTRA_STATE} will transition from
-     * {@link #STATE_AUDIO_CONNECTING} to {@link #STATE_AUDIO_CONNECTED} when
-     * audio connection is established and to {@link #STATE_AUDIO_DISCONNECTED}
-     * in case of failure to establish the audio connection.
-     *
-     * Note that this intent will not be sent if {@link BluetoothHeadset#isAudioOn()} is true
-     * before calling this method
-     *
-     * @return false if there was some error such as there is no active headset
-     * @hide
-     */
-    @UnsupportedAppUsage
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean connectAudio() {
-        if (VDBG) log("connectAudio()");
-        final IBluetoothHeadset service = mService;
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.connectAudio(mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Initiates a disconnection of HFP SCO audio.
-     * Tear down voice recognition or virtual voice call if any.
-     *
-     * <p> Users can listen to {@link #ACTION_AUDIO_STATE_CHANGED}.
-     * If this function returns true, this intent will be broadcasted with
-     * {@link #EXTRA_STATE} set to {@link #STATE_AUDIO_DISCONNECTED}.
-     *
-     * @return false if audio is not connected, or on error, true otherwise
-     * @hide
-     */
-    @UnsupportedAppUsage
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean disconnectAudio() {
-        if (VDBG) log("disconnectAudio()");
-        final IBluetoothHeadset service = mService;
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.disconnectAudio(mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Initiates a SCO channel connection as a virtual voice call to the current active device
-     * Active handsfree device will be notified of incoming call and connected call.
-     *
-     * <p> Users can listen to {@link #ACTION_AUDIO_STATE_CHANGED}.
-     * If this function returns true, this intent will be broadcasted with
-     * {@link #EXTRA_STATE} set to {@link #STATE_AUDIO_CONNECTING}.
-     *
-     * <p> {@link #EXTRA_STATE} will transition from
-     * {@link #STATE_AUDIO_CONNECTING} to {@link #STATE_AUDIO_CONNECTED} when
-     * audio connection is established and to {@link #STATE_AUDIO_DISCONNECTED}
-     * in case of failure to establish the audio connection.
-     *
-     * @return true if successful, false if one of the following case applies
-     *  - SCO audio is not idle (connecting or connected)
-     *  - virtual call has already started
-     *  - there is no active device
-     *  - a Telecom managed call is going on
-     *  - binder is dead or Bluetooth is disabled or other error
-     * @hide
-     */
-    @SystemApi
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.MODIFY_PHONE_STATE,
-    })
-    public boolean startScoUsingVirtualVoiceCall() {
-        if (DBG) log("startScoUsingVirtualVoiceCall()");
-        final IBluetoothHeadset service = mService;
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.startScoUsingVirtualVoiceCall(mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Terminates an ongoing SCO connection and the associated virtual call.
-     *
-     * <p> Users can listen to {@link #ACTION_AUDIO_STATE_CHANGED}.
-     * If this function returns true, this intent will be broadcasted with
-     * {@link #EXTRA_STATE} set to {@link #STATE_AUDIO_DISCONNECTED}.
-     *
-     * @return true if successful, false if one of the following case applies
-     *  - virtual voice call is not started or has ended
-     *  - binder is dead or Bluetooth is disabled or other error
-     * @hide
-     */
-    @SystemApi
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.MODIFY_PHONE_STATE,
-    })
-    public boolean stopScoUsingVirtualVoiceCall() {
-        if (DBG) log("stopScoUsingVirtualVoiceCall()");
-        final IBluetoothHeadset service = mService;
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.stopScoUsingVirtualVoiceCall(mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Notify Headset of phone state change.
-     * This is a backdoor for phone app to call BluetoothHeadset since
-     * there is currently not a good way to get precise call state change outside
-     * of phone app.
-     *
-     * @hide
-     */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.MODIFY_PHONE_STATE,
-    })
-    public void phoneStateChanged(int numActive, int numHeld, int callState, String number,
-            int type, String name) {
-        final IBluetoothHeadset service = mService;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                service.phoneStateChanged(numActive, numHeld, callState, number, type, name,
-                        mAttributionSource);
-            } catch (RemoteException  e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-    }
-
-    /**
-     * Send Headset of CLCC response
-     *
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.MODIFY_PHONE_STATE,
-    })
-    public void clccResponse(int index, int direction, int status, int mode, boolean mpty,
-            String number, int type) {
-        final IBluetoothHeadset service = mService;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver recv = new SynchronousResultReceiver();
-                service.clccResponse(index, direction, status, mode, mpty, number, type,
-                        mAttributionSource, recv);
-                recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(null);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-    }
-
-    /**
-     * Sends a vendor-specific unsolicited result code to the headset.
-     *
-     * <p>The actual string to be sent is <code>command + ": " + arg</code>. For example, if {@code
-     * command} is {@link #VENDOR_RESULT_CODE_COMMAND_ANDROID} and {@code arg} is {@code "0"}, the
-     * string <code>"+ANDROID: 0"</code> will be sent.
-     *
-     * <p>Currently only {@link #VENDOR_RESULT_CODE_COMMAND_ANDROID} is allowed as {@code command}.
-     *
-     * @param device Bluetooth headset.
-     * @param command A vendor-specific command.
-     * @param arg The argument that will be attached to the command.
-     * @return {@code false} if there is no headset connected, or if the command is not an allowed
-     * vendor-specific unsolicited result code, or on error. {@code true} otherwise.
-     * @throws IllegalArgumentException if {@code command} is {@code null}.
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean sendVendorSpecificResultCode(BluetoothDevice device, String command,
-            String arg) {
-        if (DBG) {
-            log("sendVendorSpecificResultCode()");
-        }
-        if (command == null) {
-            throw new IllegalArgumentException("command is null");
-        }
-        final IBluetoothHeadset service = mService;
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.sendVendorSpecificResultCode(device, command, arg,
-                        mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Select a connected device as active.
-     *
-     * The active device selection is per profile. An active device's
-     * purpose is profile-specific. For example, in HFP and HSP profiles,
-     * it is the device used for phone call audio. If a remote device is not
-     * connected, it cannot be selected as active.
-     *
-     * <p> This API returns false in scenarios like the profile on the
-     * device is not connected or Bluetooth is not turned on.
-     * When this API returns true, it is guaranteed that the
-     * {@link #ACTION_ACTIVE_DEVICE_CHANGED} intent will be broadcasted
-     * with the active device.
-     *
-     * @param device Remote Bluetooth Device, could be null if phone call audio should not be
-     * streamed to a headset
-     * @return false on immediate error, true otherwise
-     * @hide
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.MODIFY_PHONE_STATE,
-    })
-    @UnsupportedAppUsage(trackingBug = 171933273)
-    public boolean setActiveDevice(@Nullable BluetoothDevice device) {
-        if (DBG) {
-            Log.d(TAG, "setActiveDevice: " + device);
-        }
-        final IBluetoothHeadset service = mService;
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && (device == null || isValidDevice(device))) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.setActiveDevice(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Get the connected device that is active.
-     *
-     * @return the connected device that is active or null if no device
-     * is active.
-     * @hide
-     */
-    @UnsupportedAppUsage(trackingBug = 171933273)
-    @Nullable
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public BluetoothDevice getActiveDevice() {
-        if (VDBG) Log.d(TAG, "getActiveDevice");
-        final IBluetoothHeadset service = mService;
-        final BluetoothDevice defaultValue = null;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<BluetoothDevice> recv =
-                        new SynchronousResultReceiver();
-                service.getActiveDevice(mAttributionSource, recv);
-                return Attributable.setAttributionSource(
-                        recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
-                        mAttributionSource);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Check if in-band ringing is currently enabled. In-band ringing could be disabled during an
-     * active connection.
-     *
-     * @return true if in-band ringing is enabled, false if in-band ringing is disabled
-     * @hide
-     */
-    @SystemApi
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)
-    public boolean isInbandRingingEnabled() {
-        if (DBG) log("isInbandRingingEnabled()");
-        final IBluetoothHeadset service = mService;
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.isInbandRingingEnabled(mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Check if in-band ringing is supported for this platform.
-     *
-     * @return true if in-band ringing is supported, false if in-band ringing is not supported
-     * @hide
-     */
-    public static boolean isInbandRingingSupported(Context context) {
-        return context.getResources().getBoolean(
-                com.android.internal.R.bool.config_bluetooth_hfp_inband_ringing_support);
-    }
-
-    @SuppressLint("AndroidFrameworkBluetoothPermission")
-    private final IBluetoothProfileServiceConnection mConnection =
-            new IBluetoothProfileServiceConnection.Stub() {
-        @Override
-        public void onServiceConnected(ComponentName className, IBinder service) {
-            if (DBG) Log.d(TAG, "Proxy object connected");
-            mService = IBluetoothHeadset.Stub.asInterface(service);
-            mHandler.sendMessage(mHandler.obtainMessage(
-                    MESSAGE_HEADSET_SERVICE_CONNECTED));
-        }
-
-        @Override
-        public void onServiceDisconnected(ComponentName className) {
-            if (DBG) Log.d(TAG, "Proxy object disconnected");
-            doUnbind();
-            mHandler.sendMessage(mHandler.obtainMessage(
-                    MESSAGE_HEADSET_SERVICE_DISCONNECTED));
-        }
-    };
-
-    @UnsupportedAppUsage
-    private boolean isEnabled() {
-        return mAdapter.getState() == BluetoothAdapter.STATE_ON;
-    }
-
-    private boolean isDisabled() {
-        return mAdapter.getState() == BluetoothAdapter.STATE_OFF;
-    }
-
-    private static boolean isValidDevice(BluetoothDevice device) {
-        return device != null && BluetoothAdapter.checkBluetoothAddress(device.getAddress());
-    }
-
-    private static void log(String msg) {
-        Log.d(TAG, msg);
-    }
-
-    @SuppressLint("AndroidFrameworkBluetoothPermission")
-    private final Handler mHandler = new Handler(Looper.getMainLooper()) {
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case MESSAGE_HEADSET_SERVICE_CONNECTED: {
-                    if (mServiceListener != null) {
-                        mServiceListener.onServiceConnected(BluetoothProfile.HEADSET,
-                                BluetoothHeadset.this);
-                    }
-                    break;
-                }
-                case MESSAGE_HEADSET_SERVICE_DISCONNECTED: {
-                    if (mServiceListener != null) {
-                        mServiceListener.onServiceDisconnected(BluetoothProfile.HEADSET);
-                    }
-                    break;
-                }
-            }
-        }
-    };
-}
diff --git a/core/java/android/bluetooth/BluetoothHeadsetClient.java b/core/java/android/bluetooth/BluetoothHeadsetClient.java
deleted file mode 100644
index 7d7a7f7..0000000
--- a/core/java/android/bluetooth/BluetoothHeadsetClient.java
+++ /dev/null
@@ -1,1356 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-import static android.bluetooth.BluetoothUtils.getSyncTimeout;
-
-import android.annotation.NonNull;
-import android.annotation.RequiresPermission;
-import android.annotation.SdkConstant;
-import android.annotation.SdkConstant.SdkConstantType;
-import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
-import android.bluetooth.annotations.RequiresLegacyBluetoothPermission;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.content.AttributionSource;
-import android.content.Context;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.util.Log;
-
-import com.android.modules.utils.SynchronousResultReceiver;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.TimeoutException;
-
-/**
- * Public API to control Hands Free Profile (HFP role only).
- * <p>
- * This class defines methods that shall be used by application to manage profile
- * connection, calls states and calls actions.
- * <p>
- *
- * @hide
- */
-public final class BluetoothHeadsetClient implements BluetoothProfile {
-    private static final String TAG = "BluetoothHeadsetClient";
-    private static final boolean DBG = true;
-    private static final boolean VDBG = false;
-
-    /**
-     * Intent sent whenever connection to remote changes.
-     *
-     * <p>It includes two extras:
-     * <code>BluetoothProfile.EXTRA_PREVIOUS_STATE</code>
-     * and <code>BluetoothProfile.EXTRA_STATE</code>, which
-     * are mandatory.
-     * <p>There are also non mandatory feature extras:
-     * {@link #EXTRA_AG_FEATURE_3WAY_CALLING},
-     * {@link #EXTRA_AG_FEATURE_VOICE_RECOGNITION},
-     * {@link #EXTRA_AG_FEATURE_ATTACH_NUMBER_TO_VT},
-     * {@link #EXTRA_AG_FEATURE_REJECT_CALL},
-     * {@link #EXTRA_AG_FEATURE_ECC},
-     * {@link #EXTRA_AG_FEATURE_RESPONSE_AND_HOLD},
-     * {@link #EXTRA_AG_FEATURE_ACCEPT_HELD_OR_WAITING_CALL},
-     * {@link #EXTRA_AG_FEATURE_RELEASE_HELD_OR_WAITING_CALL},
-     * {@link #EXTRA_AG_FEATURE_RELEASE_AND_ACCEPT},
-     * {@link #EXTRA_AG_FEATURE_MERGE},
-     * {@link #EXTRA_AG_FEATURE_MERGE_AND_DETACH},
-     * sent as boolean values only when <code>EXTRA_STATE</code>
-     * is set to <code>STATE_CONNECTED</code>.</p>
-     *
-     * <p>Note that features supported by AG are being sent as
-     * booleans with value <code>true</code>,
-     * and not supported ones are <strong>not</strong> being sent at all.</p>
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_CONNECTION_STATE_CHANGED =
-            "android.bluetooth.headsetclient.profile.action.CONNECTION_STATE_CHANGED";
-
-    /**
-     * Intent sent whenever audio state changes.
-     *
-     * <p>It includes two mandatory extras:
-     * {@link BluetoothProfile#EXTRA_STATE},
-     * {@link BluetoothProfile#EXTRA_PREVIOUS_STATE},
-     * with possible values:
-     * {@link #STATE_AUDIO_CONNECTING},
-     * {@link #STATE_AUDIO_CONNECTED},
-     * {@link #STATE_AUDIO_DISCONNECTED}</p>
-     * <p>When <code>EXTRA_STATE</code> is set
-     * to </code>STATE_AUDIO_CONNECTED</code>,
-     * it also includes {@link #EXTRA_AUDIO_WBS}
-     * indicating wide band speech support.</p>
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_AUDIO_STATE_CHANGED =
-            "android.bluetooth.headsetclient.profile.action.AUDIO_STATE_CHANGED";
-
-    /**
-     * Intent sending updates of the Audio Gateway state.
-     * Each extra is being sent only when value it
-     * represents has been changed recently on AG.
-     * <p>It can contain one or more of the following extras:
-     * {@link #EXTRA_NETWORK_STATUS},
-     * {@link #EXTRA_NETWORK_SIGNAL_STRENGTH},
-     * {@link #EXTRA_NETWORK_ROAMING},
-     * {@link #EXTRA_BATTERY_LEVEL},
-     * {@link #EXTRA_OPERATOR_NAME},
-     * {@link #EXTRA_VOICE_RECOGNITION},
-     * {@link #EXTRA_IN_BAND_RING}</p>
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_AG_EVENT =
-            "android.bluetooth.headsetclient.profile.action.AG_EVENT";
-
-    /**
-     * Intent sent whenever state of a call changes.
-     *
-     * <p>It includes:
-     * {@link #EXTRA_CALL},
-     * with value of {@link BluetoothHeadsetClientCall} instance,
-     * representing actual call state.</p>
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_CALL_CHANGED =
-            "android.bluetooth.headsetclient.profile.action.AG_CALL_CHANGED";
-
-    /**
-     * Intent that notifies about the result of the last issued action.
-     * Please note that not every action results in explicit action result code being sent.
-     * Instead other notifications about new Audio Gateway state might be sent,
-     * like <code>ACTION_AG_EVENT</code> with <code>EXTRA_VOICE_RECOGNITION</code> value
-     * when for example user started voice recognition from HF unit.
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_RESULT =
-            "android.bluetooth.headsetclient.profile.action.RESULT";
-
-    /**
-     * Intent that notifies about vendor specific event arrival. Events not defined in
-     * HFP spec will be matched with supported vendor event list and this intent will
-     * be broadcasted upon a match. Supported vendor events are of format of
-     * of "+eventCode" or "+eventCode=xxxx" or "+eventCode:=xxxx".
-     * Vendor event can be a response to an vendor specific command or unsolicited.
-     *
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_VENDOR_SPECIFIC_HEADSETCLIENT_EVENT =
-            "android.bluetooth.headsetclient.profile.action.VENDOR_SPECIFIC_EVENT";
-
-    /**
-     * Intent that notifies about the number attached to the last voice tag
-     * recorded on AG.
-     *
-     * <p>It contains:
-     * {@link #EXTRA_NUMBER},
-     * with a <code>String</code> value representing phone number.</p>
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_LAST_VTAG =
-            "android.bluetooth.headsetclient.profile.action.LAST_VTAG";
-
-    public static final int STATE_AUDIO_DISCONNECTED = 0;
-    public static final int STATE_AUDIO_CONNECTING = 1;
-    public static final int STATE_AUDIO_CONNECTED = 2;
-
-    /**
-     * Extra with information if connected audio is WBS.
-     * <p>Possible values: <code>true</code>,
-     * <code>false</code>.</p>
-     */
-    public static final String EXTRA_AUDIO_WBS =
-            "android.bluetooth.headsetclient.extra.AUDIO_WBS";
-
-    /**
-     * Extra for AG_EVENT indicates network status.
-     * <p>Value: 0 - network unavailable,
-     * 1 - network available </p>
-     */
-    public static final String EXTRA_NETWORK_STATUS =
-            "android.bluetooth.headsetclient.extra.NETWORK_STATUS";
-    /**
-     * Extra for AG_EVENT intent indicates network signal strength.
-     * <p>Value: <code>Integer</code> representing signal strength.</p>
-     */
-    public static final String EXTRA_NETWORK_SIGNAL_STRENGTH =
-            "android.bluetooth.headsetclient.extra.NETWORK_SIGNAL_STRENGTH";
-    /**
-     * Extra for AG_EVENT intent indicates roaming state.
-     * <p>Value: 0 - no roaming
-     * 1 - active roaming</p>
-     */
-    public static final String EXTRA_NETWORK_ROAMING =
-            "android.bluetooth.headsetclient.extra.NETWORK_ROAMING";
-    /**
-     * Extra for AG_EVENT intent indicates the battery level.
-     * <p>Value: <code>Integer</code> representing signal strength.</p>
-     */
-    public static final String EXTRA_BATTERY_LEVEL =
-            "android.bluetooth.headsetclient.extra.BATTERY_LEVEL";
-    /**
-     * Extra for AG_EVENT intent indicates operator name.
-     * <p>Value: <code>String</code> representing operator name.</p>
-     */
-    public static final String EXTRA_OPERATOR_NAME =
-            "android.bluetooth.headsetclient.extra.OPERATOR_NAME";
-    /**
-     * Extra for AG_EVENT intent indicates voice recognition state.
-     * <p>Value:
-     * 0 - voice recognition stopped,
-     * 1 - voice recognition started.</p>
-     */
-    public static final String EXTRA_VOICE_RECOGNITION =
-            "android.bluetooth.headsetclient.extra.VOICE_RECOGNITION";
-    /**
-     * Extra for AG_EVENT intent indicates in band ring state.
-     * <p>Value:
-     * 0 - in band ring tone not supported, or
-     * 1 - in band ring tone supported.</p>
-     */
-    public static final String EXTRA_IN_BAND_RING =
-            "android.bluetooth.headsetclient.extra.IN_BAND_RING";
-
-    /**
-     * Extra for AG_EVENT intent indicates subscriber info.
-     * <p>Value: <code>String</code> containing subscriber information.</p>
-     */
-    public static final String EXTRA_SUBSCRIBER_INFO =
-            "android.bluetooth.headsetclient.extra.SUBSCRIBER_INFO";
-
-    /**
-     * Extra for AG_CALL_CHANGED intent indicates the
-     * {@link BluetoothHeadsetClientCall} object that has changed.
-     */
-    public static final String EXTRA_CALL =
-            "android.bluetooth.headsetclient.extra.CALL";
-
-    /**
-     * Extra for ACTION_LAST_VTAG intent.
-     * <p>Value: <code>String</code> representing phone number
-     * corresponding to last voice tag recorded on AG</p>
-     */
-    public static final String EXTRA_NUMBER =
-            "android.bluetooth.headsetclient.extra.NUMBER";
-
-    /**
-     * Extra for ACTION_RESULT intent that shows the result code of
-     * last issued action.
-     * <p>Possible results:
-     * {@link #ACTION_RESULT_OK},
-     * {@link #ACTION_RESULT_ERROR},
-     * {@link #ACTION_RESULT_ERROR_NO_CARRIER},
-     * {@link #ACTION_RESULT_ERROR_BUSY},
-     * {@link #ACTION_RESULT_ERROR_NO_ANSWER},
-     * {@link #ACTION_RESULT_ERROR_DELAYED},
-     * {@link #ACTION_RESULT_ERROR_BLACKLISTED},
-     * {@link #ACTION_RESULT_ERROR_CME}</p>
-     */
-    public static final String EXTRA_RESULT_CODE =
-            "android.bluetooth.headsetclient.extra.RESULT_CODE";
-
-    /**
-     * Extra for ACTION_RESULT intent that shows the extended result code of
-     * last issued action.
-     * <p>Value: <code>Integer</code> - error code.</p>
-     */
-    public static final String EXTRA_CME_CODE =
-            "android.bluetooth.headsetclient.extra.CME_CODE";
-
-    /**
-     * Extra for VENDOR_SPECIFIC_HEADSETCLIENT_EVENT intent that
-     * indicates vendor ID.
-     */
-    public static final String EXTRA_VENDOR_ID =
-            "android.bluetooth.headsetclient.extra.VENDOR_ID";
-
-     /**
-     * Extra for VENDOR_SPECIFIC_HEADSETCLIENT_EVENT intent that
-     * indicates vendor event code.
-     */
-    public static final String EXTRA_VENDOR_EVENT_CODE =
-            "android.bluetooth.headsetclient.extra.VENDOR_EVENT_CODE";
-
-     /**
-     * Extra for VENDOR_SPECIFIC_HEADSETCLIENT_EVENT intent that
-     * contains full vendor event including event code and full arguments.
-     */
-    public static final String EXTRA_VENDOR_EVENT_FULL_ARGS =
-            "android.bluetooth.headsetclient.extra.VENDOR_EVENT_FULL_ARGS";
-
-
-    /* Extras for AG_FEATURES, extras type is boolean */
-    // TODO verify if all of those are actually useful
-    /**
-     * AG feature: three way calling.
-     */
-    public static final String EXTRA_AG_FEATURE_3WAY_CALLING =
-            "android.bluetooth.headsetclient.extra.EXTRA_AG_FEATURE_3WAY_CALLING";
-    /**
-     * AG feature: voice recognition.
-     */
-    public static final String EXTRA_AG_FEATURE_VOICE_RECOGNITION =
-            "android.bluetooth.headsetclient.extra.EXTRA_AG_FEATURE_VOICE_RECOGNITION";
-    /**
-     * AG feature: fetching phone number for voice tagging procedure.
-     */
-    public static final String EXTRA_AG_FEATURE_ATTACH_NUMBER_TO_VT =
-            "android.bluetooth.headsetclient.extra.EXTRA_AG_FEATURE_ATTACH_NUMBER_TO_VT";
-    /**
-     * AG feature: ability to reject incoming call.
-     */
-    public static final String EXTRA_AG_FEATURE_REJECT_CALL =
-            "android.bluetooth.headsetclient.extra.EXTRA_AG_FEATURE_REJECT_CALL";
-    /**
-     * AG feature: enhanced call handling (terminate specific call, private consultation).
-     */
-    public static final String EXTRA_AG_FEATURE_ECC =
-            "android.bluetooth.headsetclient.extra.EXTRA_AG_FEATURE_ECC";
-    /**
-     * AG feature: response and hold.
-     */
-    public static final String EXTRA_AG_FEATURE_RESPONSE_AND_HOLD =
-            "android.bluetooth.headsetclient.extra.EXTRA_AG_FEATURE_RESPONSE_AND_HOLD";
-    /**
-     * AG call handling feature: accept held or waiting call in three way calling scenarios.
-     */
-    public static final String EXTRA_AG_FEATURE_ACCEPT_HELD_OR_WAITING_CALL =
-            "android.bluetooth.headsetclient.extra.EXTRA_AG_FEATURE_ACCEPT_HELD_OR_WAITING_CALL";
-    /**
-     * AG call handling feature: release held or waiting call in three way calling scenarios.
-     */
-    public static final String EXTRA_AG_FEATURE_RELEASE_HELD_OR_WAITING_CALL =
-            "android.bluetooth.headsetclient.extra.EXTRA_AG_FEATURE_RELEASE_HELD_OR_WAITING_CALL";
-    /**
-     * AG call handling feature: release active call and accept held or waiting call in three way
-     * calling scenarios.
-     */
-    public static final String EXTRA_AG_FEATURE_RELEASE_AND_ACCEPT =
-            "android.bluetooth.headsetclient.extra.EXTRA_AG_FEATURE_RELEASE_AND_ACCEPT";
-    /**
-     * AG call handling feature: merge two calls, held and active - multi party conference mode.
-     */
-    public static final String EXTRA_AG_FEATURE_MERGE =
-            "android.bluetooth.headsetclient.extra.EXTRA_AG_FEATURE_MERGE";
-    /**
-     * AG call handling feature: merge calls and disconnect from multi party
-     * conversation leaving peers connected to each other.
-     * Note that this feature needs to be supported by mobile network operator
-     * as it requires connection and billing transfer.
-     */
-    public static final String EXTRA_AG_FEATURE_MERGE_AND_DETACH =
-            "android.bluetooth.headsetclient.extra.EXTRA_AG_FEATURE_MERGE_AND_DETACH";
-
-    /* Action result codes */
-    public static final int ACTION_RESULT_OK = 0;
-    public static final int ACTION_RESULT_ERROR = 1;
-    public static final int ACTION_RESULT_ERROR_NO_CARRIER = 2;
-    public static final int ACTION_RESULT_ERROR_BUSY = 3;
-    public static final int ACTION_RESULT_ERROR_NO_ANSWER = 4;
-    public static final int ACTION_RESULT_ERROR_DELAYED = 5;
-    public static final int ACTION_RESULT_ERROR_BLACKLISTED = 6;
-    public static final int ACTION_RESULT_ERROR_CME = 7;
-
-    /* Detailed CME error codes */
-    public static final int CME_PHONE_FAILURE = 0;
-    public static final int CME_NO_CONNECTION_TO_PHONE = 1;
-    public static final int CME_OPERATION_NOT_ALLOWED = 3;
-    public static final int CME_OPERATION_NOT_SUPPORTED = 4;
-    public static final int CME_PHSIM_PIN_REQUIRED = 5;
-    public static final int CME_PHFSIM_PIN_REQUIRED = 6;
-    public static final int CME_PHFSIM_PUK_REQUIRED = 7;
-    public static final int CME_SIM_NOT_INSERTED = 10;
-    public static final int CME_SIM_PIN_REQUIRED = 11;
-    public static final int CME_SIM_PUK_REQUIRED = 12;
-    public static final int CME_SIM_FAILURE = 13;
-    public static final int CME_SIM_BUSY = 14;
-    public static final int CME_SIM_WRONG = 15;
-    public static final int CME_INCORRECT_PASSWORD = 16;
-    public static final int CME_SIM_PIN2_REQUIRED = 17;
-    public static final int CME_SIM_PUK2_REQUIRED = 18;
-    public static final int CME_MEMORY_FULL = 20;
-    public static final int CME_INVALID_INDEX = 21;
-    public static final int CME_NOT_FOUND = 22;
-    public static final int CME_MEMORY_FAILURE = 23;
-    public static final int CME_TEXT_STRING_TOO_LONG = 24;
-    public static final int CME_INVALID_CHARACTER_IN_TEXT_STRING = 25;
-    public static final int CME_DIAL_STRING_TOO_LONG = 26;
-    public static final int CME_INVALID_CHARACTER_IN_DIAL_STRING = 27;
-    public static final int CME_NO_NETWORK_SERVICE = 30;
-    public static final int CME_NETWORK_TIMEOUT = 31;
-    public static final int CME_EMERGENCY_SERVICE_ONLY = 32;
-    public static final int CME_NO_SIMULTANOUS_VOIP_CS_CALLS = 33;
-    public static final int CME_NOT_SUPPORTED_FOR_VOIP = 34;
-    public static final int CME_SIP_RESPONSE_CODE = 35;
-    public static final int CME_NETWORK_PERSONALIZATION_PIN_REQUIRED = 40;
-    public static final int CME_NETWORK_PERSONALIZATION_PUK_REQUIRED = 41;
-    public static final int CME_NETWORK_SUBSET_PERSONALIZATION_PIN_REQUIRED = 42;
-    public static final int CME_NETWORK_SUBSET_PERSONALIZATION_PUK_REQUIRED = 43;
-    public static final int CME_SERVICE_PROVIDER_PERSONALIZATION_PIN_REQUIRED = 44;
-    public static final int CME_SERVICE_PROVIDER_PERSONALIZATION_PUK_REQUIRED = 45;
-    public static final int CME_CORPORATE_PERSONALIZATION_PIN_REQUIRED = 46;
-    public static final int CME_CORPORATE_PERSONALIZATION_PUK_REQUIRED = 47;
-    public static final int CME_HIDDEN_KEY_REQUIRED = 48;
-    public static final int CME_EAP_NOT_SUPPORTED = 49;
-    public static final int CME_INCORRECT_PARAMETERS = 50;
-
-    /* Action policy for other calls when accepting call */
-    public static final int CALL_ACCEPT_NONE = 0;
-    public static final int CALL_ACCEPT_HOLD = 1;
-    public static final int CALL_ACCEPT_TERMINATE = 2;
-
-    private final BluetoothAdapter mAdapter;
-    private final AttributionSource mAttributionSource;
-    private final BluetoothProfileConnector<IBluetoothHeadsetClient> mProfileConnector =
-            new BluetoothProfileConnector(this, BluetoothProfile.HEADSET_CLIENT,
-                    "BluetoothHeadsetClient", IBluetoothHeadsetClient.class.getName()) {
-                @Override
-                public IBluetoothHeadsetClient getServiceInterface(IBinder service) {
-                    return IBluetoothHeadsetClient.Stub.asInterface(service);
-                }
-    };
-
-    /**
-     * Create a BluetoothHeadsetClient proxy object.
-     */
-    /* package */ BluetoothHeadsetClient(Context context, ServiceListener listener,
-            BluetoothAdapter adapter) {
-        mAdapter = adapter;
-        mAttributionSource = adapter.getAttributionSource();
-        mProfileConnector.connect(context, listener);
-    }
-
-    /**
-     * Close the connection to the backing service.
-     * Other public functions of BluetoothHeadsetClient will return default error
-     * results once close() has been called. Multiple invocations of close()
-     * are ok.
-     */
-    /*package*/ void close() {
-        if (VDBG) log("close()");
-        mProfileConnector.disconnect();
-    }
-
-    private IBluetoothHeadsetClient getService() {
-        return mProfileConnector.getService();
-    }
-
-    /**
-     * Connects to remote device.
-     *
-     * Currently, the system supports only 1 connection. So, in case of the
-     * second connection, this implementation will disconnect already connected
-     * device automatically and will process the new one.
-     *
-     * @param device a remote device we want connect to
-     * @return <code>true</code> if command has been issued successfully; <code>false</code>
-     * otherwise; upon completion HFP sends {@link #ACTION_CONNECTION_STATE_CHANGED} intent.
-     *
-     * @hide
-     */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean connect(BluetoothDevice device) {
-        if (DBG) log("connect(" + device + ")");
-        final IBluetoothHeadsetClient service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.connect(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Disconnects remote device
-     *
-     * @param device a remote device we want disconnect
-     * @return <code>true</code> if command has been issued successfully; <code>false</code>
-     * otherwise; upon completion HFP sends {@link #ACTION_CONNECTION_STATE_CHANGED} intent.
-     *
-     * @hide
-     */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean disconnect(BluetoothDevice device) {
-        if (DBG) log("disconnect(" + device + ")");
-        final IBluetoothHeadsetClient service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.disconnect(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Return the list of connected remote devices
-     *
-     * @return list of connected devices; empty list if nothing is connected.
-     */
-    @Override
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public List<BluetoothDevice> getConnectedDevices() {
-        if (VDBG) log("getConnectedDevices()");
-        final IBluetoothHeadsetClient service = getService();
-        final List<BluetoothDevice> defaultValue = new ArrayList<BluetoothDevice>();
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<List<BluetoothDevice>> recv =
-                        new SynchronousResultReceiver();
-                service.getConnectedDevices(mAttributionSource, recv);
-                return Attributable.setAttributionSource(
-                        recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
-                        mAttributionSource);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Returns list of remote devices in a particular state
-     *
-     * @param states collection of states
-     * @return list of devices that state matches the states listed in <code>states</code>; empty
-     * list if nothing matches the <code>states</code>
-     */
-    @Override
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
-        if (VDBG) log("getDevicesMatchingStates()");
-        final IBluetoothHeadsetClient service = getService();
-        final List<BluetoothDevice> defaultValue = new ArrayList<BluetoothDevice>();
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<List<BluetoothDevice>> recv =
-                        new SynchronousResultReceiver();
-                service.getDevicesMatchingConnectionStates(states, mAttributionSource, recv);
-                return Attributable.setAttributionSource(
-                        recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
-                        mAttributionSource);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Returns state of the <code>device</code>
-     *
-     * @param device a remote device
-     * @return the state of connection of the device
-     */
-    @Override
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public int getConnectionState(BluetoothDevice device) {
-        if (VDBG) log("getConnectionState(" + device + ")");
-        final IBluetoothHeadsetClient service = getService();
-        final int defaultValue = BluetoothProfile.STATE_DISCONNECTED;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
-                service.getConnectionState(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Set priority of the profile
-     *
-     * <p> The device should already be paired.
-     * Priority can be one of {@link #PRIORITY_ON} or {@link #PRIORITY_OFF}
-     *
-     * @param device Paired bluetooth device
-     * @param priority
-     * @return true if priority is set, false on error
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean setPriority(BluetoothDevice device, int priority) {
-        if (DBG) log("setPriority(" + device + ", " + priority + ")");
-        return setConnectionPolicy(device, BluetoothAdapter.priorityToConnectionPolicy(priority));
-    }
-
-    /**
-     * Set connection policy of the profile
-     *
-     * <p> The device should already be paired.
-     * Connection policy can be one of {@link #CONNECTION_POLICY_ALLOWED},
-     * {@link #CONNECTION_POLICY_FORBIDDEN}, {@link #CONNECTION_POLICY_UNKNOWN}
-     *
-     * @param device Paired bluetooth device
-     * @param connectionPolicy is the connection policy to set to for this profile
-     * @return true if connectionPolicy is set, false on error
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean setConnectionPolicy(@NonNull BluetoothDevice device,
-            @ConnectionPolicy int connectionPolicy) {
-        if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
-        final IBluetoothHeadsetClient service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)
-                && (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_FORBIDDEN
-                    || connectionPolicy == BluetoothProfile.CONNECTION_POLICY_ALLOWED)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.setConnectionPolicy(device, connectionPolicy, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Get the priority of the profile.
-     *
-     * <p> The priority can be any of:
-     * {@link #PRIORITY_OFF}, {@link #PRIORITY_ON}, {@link #PRIORITY_UNDEFINED}
-     *
-     * @param device Bluetooth device
-     * @return priority of the device
-     * @hide
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public int getPriority(BluetoothDevice device) {
-        if (VDBG) log("getPriority(" + device + ")");
-        return BluetoothAdapter.connectionPolicyToPriority(getConnectionPolicy(device));
-    }
-
-    /**
-     * Get the connection policy of the profile.
-     *
-     * <p> The connection policy can be any of:
-     * {@link #CONNECTION_POLICY_ALLOWED}, {@link #CONNECTION_POLICY_FORBIDDEN},
-     * {@link #CONNECTION_POLICY_UNKNOWN}
-     *
-     * @param device Bluetooth device
-     * @return connection policy of the device
-     * @hide
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public @ConnectionPolicy int getConnectionPolicy(@NonNull BluetoothDevice device) {
-        if (VDBG) log("getConnectionPolicy(" + device + ")");
-        final IBluetoothHeadsetClient service = getService();
-        final @ConnectionPolicy int defaultValue = BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
-                service.getConnectionPolicy(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Starts voice recognition.
-     *
-     * @param device remote device
-     * @return <code>true</code> if command has been issued successfully; <code>false</code>
-     * otherwise; upon completion HFP sends {@link #ACTION_AG_EVENT} intent.
-     *
-     * <p>Feature required for successful execution is being reported by: {@link
-     * #EXTRA_AG_FEATURE_VOICE_RECOGNITION}. This method invocation will fail silently when feature
-     * is not supported.</p>
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean startVoiceRecognition(BluetoothDevice device) {
-        if (DBG) log("startVoiceRecognition()");
-        final IBluetoothHeadsetClient service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.startVoiceRecognition(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Send vendor specific AT command.
-     *
-     * @param device remote device
-     * @param vendorId vendor number by Bluetooth SIG
-     * @param atCommand command to be sent. It start with + prefix and only one command at one time.
-     * @return <code>true</code> if command has been issued successfully; <code>false</code>
-     * otherwise.
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean sendVendorAtCommand(BluetoothDevice device, int vendorId, String atCommand) {
-        if (DBG) log("sendVendorSpecificCommand()");
-        final IBluetoothHeadsetClient service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.sendVendorAtCommand(device, vendorId, atCommand, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Stops voice recognition.
-     *
-     * @param device remote device
-     * @return <code>true</code> if command has been issued successfully; <code>false</code>
-     * otherwise; upon completion HFP sends {@link #ACTION_AG_EVENT} intent.
-     *
-     * <p>Feature required for successful execution is being reported by: {@link
-     * #EXTRA_AG_FEATURE_VOICE_RECOGNITION}. This method invocation will fail silently when feature
-     * is not supported.</p>
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean stopVoiceRecognition(BluetoothDevice device) {
-        if (DBG) log("stopVoiceRecognition()");
-        final IBluetoothHeadsetClient service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.stopVoiceRecognition(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Returns list of all calls in any state.
-     *
-     * @param device remote device
-     * @return list of calls; empty list if none call exists
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public List<BluetoothHeadsetClientCall> getCurrentCalls(BluetoothDevice device) {
-        if (DBG) log("getCurrentCalls()");
-        final IBluetoothHeadsetClient service = getService();
-        final List<BluetoothHeadsetClientCall> defaultValue = null;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<List<BluetoothHeadsetClientCall>> recv =
-                        new SynchronousResultReceiver();
-                service.getCurrentCalls(device, mAttributionSource, recv);
-                return Attributable.setAttributionSource(
-                        recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
-                        mAttributionSource);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Returns list of current values of AG indicators.
-     *
-     * @param device remote device
-     * @return bundle of AG  indicators; null if device is not in CONNECTED state
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public Bundle getCurrentAgEvents(BluetoothDevice device) {
-        if (DBG) log("getCurrentAgEvents()");
-        final IBluetoothHeadsetClient service = getService();
-        final Bundle defaultValue = null;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Bundle> recv = new SynchronousResultReceiver();
-                service.getCurrentAgEvents(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Accepts a call
-     *
-     * @param device remote device
-     * @param flag action policy while accepting a call. Possible values {@link #CALL_ACCEPT_NONE},
-     * {@link #CALL_ACCEPT_HOLD}, {@link #CALL_ACCEPT_TERMINATE}
-     * @return <code>true</code> if command has been issued successfully; <code>false</code>
-     * otherwise; upon completion HFP sends {@link #ACTION_CALL_CHANGED} intent.
-     */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean acceptCall(BluetoothDevice device, int flag) {
-        if (DBG) log("acceptCall()");
-        final IBluetoothHeadsetClient service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.acceptCall(device, flag, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Holds a call.
-     *
-     * @param device remote device
-     * @return <code>true</code> if command has been issued successfully; <code>false</code>
-     * otherwise; upon completion HFP sends {@link #ACTION_CALL_CHANGED} intent.
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean holdCall(BluetoothDevice device) {
-        if (DBG) log("holdCall()");
-        final IBluetoothHeadsetClient service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.holdCall(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Rejects a call.
-     *
-     * @param device remote device
-     * @return <code>true</code> if command has been issued successfully; <code>false</code>
-     * otherwise; upon completion HFP sends {@link #ACTION_CALL_CHANGED} intent.
-     *
-     * <p>Feature required for successful execution is being reported by: {@link
-     * #EXTRA_AG_FEATURE_REJECT_CALL}. This method invocation will fail silently when feature is not
-     * supported.</p>
-     */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean rejectCall(BluetoothDevice device) {
-        if (DBG) log("rejectCall()");
-        final IBluetoothHeadsetClient service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.rejectCall(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Terminates a specified call.
-     *
-     * Works only when Extended Call Control is supported by Audio Gateway.
-     *
-     * @param device remote device
-     * @param call Handle of call obtained in {@link #dial(BluetoothDevice, String)} or obtained via
-     * {@link #ACTION_CALL_CHANGED}. {@code call} may be null in which case we will hangup all active
-     * calls.
-     * @return <code>true</code> if command has been issued successfully; <code>false</code>
-     * otherwise; upon completion HFP sends {@link #ACTION_CALL_CHANGED} intent.
-     *
-     * <p>Feature required for successful execution is being reported by: {@link
-     * #EXTRA_AG_FEATURE_ECC}. This method invocation will fail silently when feature is not
-     * supported.</p>
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean terminateCall(BluetoothDevice device, BluetoothHeadsetClientCall call) {
-        if (DBG) log("terminateCall()");
-        final IBluetoothHeadsetClient service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.terminateCall(device, call, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Enters private mode with a specified call.
-     *
-     * Works only when Extended Call Control is supported by Audio Gateway.
-     *
-     * @param device remote device
-     * @param index index of the call to connect in private mode
-     * @return <code>true</code> if command has been issued successfully; <code>false</code>
-     * otherwise; upon completion HFP sends {@link #ACTION_CALL_CHANGED} intent.
-     *
-     * <p>Feature required for successful execution is being reported by: {@link
-     * #EXTRA_AG_FEATURE_ECC}. This method invocation will fail silently when feature is not
-     * supported.</p>
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean enterPrivateMode(BluetoothDevice device, int index) {
-        if (DBG) log("enterPrivateMode()");
-        final IBluetoothHeadsetClient service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.enterPrivateMode(device, index, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Performs explicit call transfer.
-     *
-     * That means connect other calls and disconnect.
-     *
-     * @param device remote device
-     * @return <code>true</code> if command has been issued successfully; <code>false</code>
-     * otherwise; upon completion HFP sends {@link #ACTION_CALL_CHANGED} intent.
-     *
-     * <p>Feature required for successful execution is being reported by: {@link
-     * #EXTRA_AG_FEATURE_MERGE_AND_DETACH}. This method invocation will fail silently when feature
-     * is not supported.</p>
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean explicitCallTransfer(BluetoothDevice device) {
-        if (DBG) log("explicitCallTransfer()");
-        final IBluetoothHeadsetClient service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.explicitCallTransfer(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Places a call with specified number.
-     *
-     * @param device remote device
-     * @param number valid phone number
-     * @return <code>{@link BluetoothHeadsetClientCall} call</code> if command has been issued
-     * successfully; <code>{@link null}</code> otherwise; upon completion HFP sends {@link
-     * #ACTION_CALL_CHANGED} intent in case of success; {@link #ACTION_RESULT} is sent otherwise;
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public BluetoothHeadsetClientCall dial(BluetoothDevice device, String number) {
-        if (DBG) log("dial()");
-        final IBluetoothHeadsetClient service = getService();
-        final BluetoothHeadsetClientCall defaultValue = null;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<BluetoothHeadsetClientCall> recv =
-                        new SynchronousResultReceiver();
-                service.dial(device, number, mAttributionSource, recv);
-                return Attributable.setAttributionSource(
-                        recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
-                        mAttributionSource);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Sends DTMF code.
-     *
-     * Possible code values : 0,1,2,3,4,5,6,7,8,9,A,B,C,D,*,#
-     *
-     * @param device remote device
-     * @param code ASCII code
-     * @return <code>true</code> if command has been issued successfully; <code>false</code>
-     * otherwise; upon completion HFP sends {@link #ACTION_RESULT} intent;
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean sendDTMF(BluetoothDevice device, byte code) {
-        if (DBG) log("sendDTMF()");
-        final IBluetoothHeadsetClient service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.sendDTMF(device, code, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Get a number corresponding to last voice tag recorded on AG.
-     *
-     * @param device remote device
-     * @return <code>true</code> if command has been issued successfully; <code>false</code>
-     * otherwise; upon completion HFP sends {@link #ACTION_LAST_VTAG} or {@link #ACTION_RESULT}
-     * intent;
-     *
-     * <p>Feature required for successful execution is being reported by: {@link
-     * #EXTRA_AG_FEATURE_ATTACH_NUMBER_TO_VT}. This method invocation will fail silently when
-     * feature is not supported.</p>
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean getLastVoiceTagNumber(BluetoothDevice device) {
-        if (DBG) log("getLastVoiceTagNumber()");
-        final IBluetoothHeadsetClient service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.getLastVoiceTagNumber(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Returns current audio state of Audio Gateway.
-     *
-     * Note: This is an internal function and shouldn't be exposed
-     */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public int getAudioState(BluetoothDevice device) {
-        if (VDBG) log("getAudioState");
-        final IBluetoothHeadsetClient service = getService();
-        final int defaultValue = BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
-                service.getAudioState(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        } else {
-            return defaultValue;
-        }
-        return BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED;
-    }
-
-    /**
-     * Sets whether audio routing is allowed.
-     *
-     * @param device remote device
-     * @param allowed if routing is allowed to the device Note: This is an internal function and
-     * shouldn't be exposed
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public void setAudioRouteAllowed(BluetoothDevice device, boolean allowed) {
-        if (VDBG) log("setAudioRouteAllowed");
-        final IBluetoothHeadsetClient service = getService();
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver recv = new SynchronousResultReceiver();
-                service.setAudioRouteAllowed(device, allowed, mAttributionSource, recv);
-                recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(null);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-    }
-
-    /**
-     * Returns whether audio routing is allowed.
-     *
-     * @param device remote device
-     * @return whether the command succeeded Note: This is an internal function and shouldn't be
-     * exposed
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean getAudioRouteAllowed(BluetoothDevice device) {
-        if (VDBG) log("getAudioRouteAllowed");
-        final IBluetoothHeadsetClient service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.getAudioRouteAllowed(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Initiates a connection of audio channel.
-     *
-     * It setup SCO channel with remote connected Handsfree AG device.
-     *
-     * @param device remote device
-     * @return <code>true</code> if command has been issued successfully; <code>false</code>
-     * otherwise; upon completion HFP sends {@link #ACTION_AUDIO_STATE_CHANGED} intent;
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean connectAudio(BluetoothDevice device) {
-        if (VDBG) log("connectAudio");
-        final IBluetoothHeadsetClient service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.connectAudio(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Disconnects audio channel.
-     *
-     * It tears down the SCO channel from remote AG device.
-     *
-     * @param device remote device
-     * @return <code>true</code> if command has been issued successfully; <code>false</code>
-     * otherwise; upon completion HFP sends {@link #ACTION_AUDIO_STATE_CHANGED} intent;
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean disconnectAudio(BluetoothDevice device) {
-        if (VDBG) log("disconnectAudio");
-        final IBluetoothHeadsetClient service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.disconnectAudio(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Get Audio Gateway features
-     *
-     * @param device remote device
-     * @return bundle of AG features; null if no service or AG not connected
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public Bundle getCurrentAgFeatures(BluetoothDevice device) {
-        if (VDBG) log("getCurrentAgFeatures");
-        final IBluetoothHeadsetClient service = getService();
-        final Bundle defaultValue = null;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<Bundle> recv = new SynchronousResultReceiver();
-                service.getCurrentAgFeatures(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    private boolean isEnabled() {
-        return mAdapter.getState() == BluetoothAdapter.STATE_ON;
-    }
-
-    private static boolean isValidDevice(BluetoothDevice device) {
-        return device != null && BluetoothAdapter.checkBluetoothAddress(device.getAddress());
-    }
-
-    private static void log(String msg) {
-        Log.d(TAG, msg);
-    }
-}
diff --git a/core/java/android/bluetooth/BluetoothHeadsetClientCall.java b/core/java/android/bluetooth/BluetoothHeadsetClientCall.java
deleted file mode 100644
index 032b507..0000000
--- a/core/java/android/bluetooth/BluetoothHeadsetClientCall.java
+++ /dev/null
@@ -1,323 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-import android.annotation.NonNull;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.content.AttributionSource;
-import android.os.Build;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.SystemClock;
-
-import java.util.UUID;
-
-/**
- * This class represents a single call, its state and properties.
- * It implements {@link Parcelable} for inter-process message passing.
- *
- * @hide
- */
-public final class BluetoothHeadsetClientCall implements Parcelable, Attributable {
-
-    /* Call state */
-    /**
-     * Call is active.
-     */
-    public static final int CALL_STATE_ACTIVE = 0;
-    /**
-     * Call is in held state.
-     */
-    public static final int CALL_STATE_HELD = 1;
-    /**
-     * Outgoing call that is being dialed right now.
-     */
-    public static final int CALL_STATE_DIALING = 2;
-    /**
-     * Outgoing call that remote party has already been alerted about.
-     */
-    public static final int CALL_STATE_ALERTING = 3;
-    /**
-     * Incoming call that can be accepted or rejected.
-     */
-    public static final int CALL_STATE_INCOMING = 4;
-    /**
-     * Waiting call state when there is already an active call.
-     */
-    public static final int CALL_STATE_WAITING = 5;
-    /**
-     * Call that has been held by response and hold
-     * (see Bluetooth specification for further references).
-     */
-    public static final int CALL_STATE_HELD_BY_RESPONSE_AND_HOLD = 6;
-    /**
-     * Call that has been already terminated and should not be referenced as a valid call.
-     */
-    public static final int CALL_STATE_TERMINATED = 7;
-
-    private final BluetoothDevice mDevice;
-    private final int mId;
-    private int mState;
-    private String mNumber;
-    private boolean mMultiParty;
-    private final boolean mOutgoing;
-    private final UUID mUUID;
-    private final long mCreationElapsedMilli;
-    private final boolean mInBandRing;
-
-    /**
-     * Creates BluetoothHeadsetClientCall instance.
-     */
-    public BluetoothHeadsetClientCall(BluetoothDevice device, int id, int state, String number,
-            boolean multiParty, boolean outgoing, boolean inBandRing) {
-        this(device, id, UUID.randomUUID(), state, number, multiParty, outgoing, inBandRing);
-    }
-
-    public BluetoothHeadsetClientCall(BluetoothDevice device, int id, UUID uuid, int state,
-            String number, boolean multiParty, boolean outgoing, boolean inBandRing) {
-        mDevice = device;
-        mId = id;
-        mUUID = uuid;
-        mState = state;
-        mNumber = number != null ? number : "";
-        mMultiParty = multiParty;
-        mOutgoing = outgoing;
-        mInBandRing = inBandRing;
-        mCreationElapsedMilli = SystemClock.elapsedRealtime();
-    }
-
-    /** {@hide} */
-    public void setAttributionSource(@NonNull AttributionSource attributionSource) {
-        Attributable.setAttributionSource(mDevice, attributionSource);
-    }
-
-    /**
-     * Sets call's state.
-     *
-     * <p>Note: This is an internal function and shouldn't be exposed</p>
-     *
-     * @param state new call state.
-     */
-    public void setState(int state) {
-        mState = state;
-    }
-
-    /**
-     * Sets call's number.
-     *
-     * <p>Note: This is an internal function and shouldn't be exposed</p>
-     *
-     * @param number String representing phone number.
-     */
-    public void setNumber(String number) {
-        mNumber = number;
-    }
-
-    /**
-     * Sets this call as multi party call.
-     *
-     * <p>Note: This is an internal function and shouldn't be exposed</p>
-     *
-     * @param multiParty if <code>true</code> sets this call as a part of multi party conference.
-     */
-    public void setMultiParty(boolean multiParty) {
-        mMultiParty = multiParty;
-    }
-
-    /**
-     * Gets call's device.
-     *
-     * @return call device.
-     */
-    public BluetoothDevice getDevice() {
-        return mDevice;
-    }
-
-    /**
-     * Gets call's Id.
-     *
-     * @return call id.
-     */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    public int getId() {
-        return mId;
-    }
-
-    /**
-     * Gets call's UUID.
-     *
-     * @return call uuid
-     * @hide
-     */
-    public UUID getUUID() {
-        return mUUID;
-    }
-
-    /**
-     * Gets call's current state.
-     *
-     * @return state of this particular phone call.
-     */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    public int getState() {
-        return mState;
-    }
-
-    /**
-     * Gets call's number.
-     *
-     * @return string representing phone number.
-     */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    public String getNumber() {
-        return mNumber;
-    }
-
-    /**
-     * Gets call's creation time in millis since epoch.
-     *
-     * @return long representing the creation time.
-     */
-    public long getCreationElapsedMilli() {
-        return mCreationElapsedMilli;
-    }
-
-    /**
-     * Checks if call is an active call in a conference mode (aka multi party).
-     *
-     * @return <code>true</code> if call is a multi party call, <code>false</code> otherwise.
-     */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    public boolean isMultiParty() {
-        return mMultiParty;
-    }
-
-    /**
-     * Checks if this call is an outgoing call.
-     *
-     * @return <code>true</code> if its outgoing call, <code>false</code> otherwise.
-     */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    public boolean isOutgoing() {
-        return mOutgoing;
-    }
-
-    /**
-     * Checks if the ringtone will be generated by the connected phone
-     *
-     * @return <code>true</code> if in band ring is enabled, <code>false</code> otherwise.
-     */
-    public boolean isInBandRing() {
-        return mInBandRing;
-    }
-
-
-    @Override
-    public String toString() {
-        return toString(false);
-    }
-
-    /**
-     * Generate a log string for this call
-     * @param loggable whether device address should be logged
-     * @return log string
-     */
-    public String toString(boolean loggable) {
-        StringBuilder builder = new StringBuilder("BluetoothHeadsetClientCall{mDevice: ");
-        builder.append(loggable ? mDevice : mDevice.hashCode());
-        builder.append(", mId: ");
-        builder.append(mId);
-        builder.append(", mUUID: ");
-        builder.append(mUUID);
-        builder.append(", mState: ");
-        switch (mState) {
-            case CALL_STATE_ACTIVE:
-                builder.append("ACTIVE");
-                break;
-            case CALL_STATE_HELD:
-                builder.append("HELD");
-                break;
-            case CALL_STATE_DIALING:
-                builder.append("DIALING");
-                break;
-            case CALL_STATE_ALERTING:
-                builder.append("ALERTING");
-                break;
-            case CALL_STATE_INCOMING:
-                builder.append("INCOMING");
-                break;
-            case CALL_STATE_WAITING:
-                builder.append("WAITING");
-                break;
-            case CALL_STATE_HELD_BY_RESPONSE_AND_HOLD:
-                builder.append("HELD_BY_RESPONSE_AND_HOLD");
-                break;
-            case CALL_STATE_TERMINATED:
-                builder.append("TERMINATED");
-                break;
-            default:
-                builder.append(mState);
-                break;
-        }
-        builder.append(", mNumber: ");
-        builder.append(loggable ? mNumber : mNumber.hashCode());
-        builder.append(", mMultiParty: ");
-        builder.append(mMultiParty);
-        builder.append(", mOutgoing: ");
-        builder.append(mOutgoing);
-        builder.append(", mInBandRing: ");
-        builder.append(mInBandRing);
-        builder.append("}");
-        return builder.toString();
-    }
-
-    /**
-     * {@link Parcelable.Creator} interface implementation.
-     */
-    public static final @android.annotation.NonNull Parcelable.Creator<BluetoothHeadsetClientCall> CREATOR =
-            new Parcelable.Creator<BluetoothHeadsetClientCall>() {
-                @Override
-                public BluetoothHeadsetClientCall createFromParcel(Parcel in) {
-                    return new BluetoothHeadsetClientCall((BluetoothDevice) in.readParcelable(null),
-                            in.readInt(), UUID.fromString(in.readString()), in.readInt(),
-                            in.readString(), in.readInt() == 1, in.readInt() == 1,
-                            in.readInt() == 1);
-                }
-
-                @Override
-                public BluetoothHeadsetClientCall[] newArray(int size) {
-                    return new BluetoothHeadsetClientCall[size];
-                }
-            };
-
-    @Override
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeParcelable(mDevice, 0);
-        out.writeInt(mId);
-        out.writeString(mUUID.toString());
-        out.writeInt(mState);
-        out.writeString(mNumber);
-        out.writeInt(mMultiParty ? 1 : 0);
-        out.writeInt(mOutgoing ? 1 : 0);
-        out.writeInt(mInBandRing ? 1 : 0);
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-}
diff --git a/core/java/android/bluetooth/BluetoothHealth.java b/core/java/android/bluetooth/BluetoothHealth.java
deleted file mode 100644
index 65f68a9..0000000
--- a/core/java/android/bluetooth/BluetoothHealth.java
+++ /dev/null
@@ -1,386 +0,0 @@
-/*
- * Copyright (C) 2011 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.bluetooth;
-
-import android.annotation.RequiresPermission;
-import android.annotation.SuppressLint;
-import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
-import android.bluetooth.annotations.RequiresLegacyBluetoothPermission;
-import android.os.ParcelFileDescriptor;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Public API for Bluetooth Health Profile.
- *
- * <p>BluetoothHealth is a proxy object for controlling the Bluetooth
- * Service via IPC.
- *
- * <p> How to connect to a health device which is acting in the source role.
- * <li> Use {@link BluetoothAdapter#getProfileProxy} to get
- * the BluetoothHealth proxy object. </li>
- * <li> Create an {@link BluetoothHealth} callback and call
- * {@link #registerSinkAppConfiguration} to register an application
- * configuration </li>
- * <li> Pair with the remote device. This currently needs to be done manually
- * from Bluetooth Settings </li>
- * <li> Connect to a health device using {@link #connectChannelToSource}. Some
- * devices will connect the channel automatically. The {@link BluetoothHealth}
- * callback will inform the application of channel state change. </li>
- * <li> Use the file descriptor provided with a connected channel to read and
- * write data to the health channel. </li>
- * <li> The received data needs to be interpreted using a health manager which
- * implements the IEEE 11073-xxxxx specifications.
- * <li> When done, close the health channel by calling {@link #disconnectChannel}
- * and unregister the application configuration calling
- * {@link #unregisterAppConfiguration}
- *
- * @deprecated Health Device Profile (HDP) and MCAP protocol are no longer used. New apps
- * should use Bluetooth Low Energy based solutions such as {@link BluetoothGatt},
- * {@link BluetoothAdapter#listenUsingL2capChannel()(int)}, or
- * {@link BluetoothDevice#createL2capChannel(int)}
- */
-@Deprecated
-public final class BluetoothHealth implements BluetoothProfile {
-    private static final String TAG = "BluetoothHealth";
-    /**
-     * Health Profile Source Role - the health device.
-     *
-     * @deprecated Health Device Profile (HDP) and MCAP protocol are no longer used. New
-     * apps should use Bluetooth Low Energy based solutions such as {@link BluetoothGatt},
-     * {@link BluetoothAdapter#listenUsingL2capChannel()(int)}, or
-     * {@link BluetoothDevice#createL2capChannel(int)}
-     */
-    @Deprecated
-    public static final int SOURCE_ROLE = 1 << 0;
-
-    /**
-     * Health Profile Sink Role the device talking to the health device.
-     *
-     * @deprecated Health Device Profile (HDP) and MCAP protocol are no longer used. New
-     * apps should use Bluetooth Low Energy based solutions such as {@link BluetoothGatt},
-     * {@link BluetoothAdapter#listenUsingL2capChannel()(int)}, or
-     * {@link BluetoothDevice#createL2capChannel(int)}
-     */
-    @Deprecated
-    public static final int SINK_ROLE = 1 << 1;
-
-    /**
-     * Health Profile - Channel Type used - Reliable
-     *
-     * @deprecated Health Device Profile (HDP) and MCAP protocol are no longer used. New
-     * apps should use Bluetooth Low Energy based solutions such as {@link BluetoothGatt},
-     * {@link BluetoothAdapter#listenUsingL2capChannel()(int)}, or
-     * {@link BluetoothDevice#createL2capChannel(int)}
-     */
-    @Deprecated
-    public static final int CHANNEL_TYPE_RELIABLE = 10;
-
-    /**
-     * Health Profile - Channel Type used - Streaming
-     *
-     * @deprecated Health Device Profile (HDP) and MCAP protocol are no longer used. New
-     * apps should use Bluetooth Low Energy based solutions such as {@link BluetoothGatt},
-     * {@link BluetoothAdapter#listenUsingL2capChannel()(int)}, or
-     * {@link BluetoothDevice#createL2capChannel(int)}
-     */
-    @Deprecated
-    public static final int CHANNEL_TYPE_STREAMING = 11;
-
-    /**
-     * Hide auto-created default constructor
-     * @hide
-     */
-    BluetoothHealth() {}
-
-    /**
-     * Register an application configuration that acts as a Health SINK.
-     * This is the configuration that will be used to communicate with health devices
-     * which will act as the {@link #SOURCE_ROLE}. This is an asynchronous call and so
-     * the callback is used to notify success or failure if the function returns true.
-     *
-     * @param name The friendly name associated with the application or configuration.
-     * @param dataType The dataType of the Source role of Health Profile to which the sink wants to
-     * connect to.
-     * @param callback A callback to indicate success or failure of the registration and all
-     * operations done on this application configuration.
-     * @return If true, callback will be called.
-     *
-     * @deprecated Health Device Profile (HDP) and MCAP protocol are no longer used. New
-     * apps should use Bluetooth Low Energy based solutions such as {@link BluetoothGatt},
-     * {@link BluetoothAdapter#listenUsingL2capChannel()(int)}, or
-     * {@link BluetoothDevice#createL2capChannel(int)}
-     */
-    @Deprecated
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SuppressLint("AndroidFrameworkRequiresPermission")
-    public boolean registerSinkAppConfiguration(String name, int dataType,
-            BluetoothHealthCallback callback) {
-        Log.e(TAG, "registerSinkAppConfiguration(): BluetoothHealth is deprecated");
-        return false;
-    }
-
-    /**
-     * Unregister an application configuration that has been registered using
-     * {@link #registerSinkAppConfiguration}
-     *
-     * @param config The health app configuration
-     * @return Success or failure.
-     *
-     * @deprecated Health Device Profile (HDP) and MCAP protocol are no longer used. New
-     * apps should use Bluetooth Low Energy based solutions such as {@link BluetoothGatt},
-     * {@link BluetoothAdapter#listenUsingL2capChannel()(int)}, or
-     * {@link BluetoothDevice#createL2capChannel(int)}
-     */
-    @Deprecated
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SuppressLint("AndroidFrameworkRequiresPermission")
-    public boolean unregisterAppConfiguration(BluetoothHealthAppConfiguration config) {
-        Log.e(TAG, "unregisterAppConfiguration(): BluetoothHealth is deprecated");
-        return false;
-    }
-
-    /**
-     * Connect to a health device which has the {@link #SOURCE_ROLE}.
-     * This is an asynchronous call. If this function returns true, the callback
-     * associated with the application configuration will be called.
-     *
-     * @param device The remote Bluetooth device.
-     * @param config The application configuration which has been registered using {@link
-     * #registerSinkAppConfiguration(String, int, BluetoothHealthCallback) }
-     * @return If true, the callback associated with the application config will be called.
-     *
-     * @deprecated Health Device Profile (HDP) and MCAP protocol are no longer used. New
-     * apps should use Bluetooth Low Energy based solutions such as {@link BluetoothGatt},
-     * {@link BluetoothAdapter#listenUsingL2capChannel()(int)}, or
-     * {@link BluetoothDevice#createL2capChannel(int)}
-     */
-    @Deprecated
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SuppressLint("AndroidFrameworkRequiresPermission")
-    public boolean connectChannelToSource(BluetoothDevice device,
-            BluetoothHealthAppConfiguration config) {
-        Log.e(TAG, "connectChannelToSource(): BluetoothHealth is deprecated");
-        return false;
-    }
-
-    /**
-     * Disconnect a connected health channel.
-     * This is an asynchronous call. If this function returns true, the callback
-     * associated with the application configuration will be called.
-     *
-     * @param device The remote Bluetooth device.
-     * @param config The application configuration which has been registered using {@link
-     * #registerSinkAppConfiguration(String, int, BluetoothHealthCallback) }
-     * @param channelId The channel id associated with the channel
-     * @return If true, the callback associated with the application config will be called.
-     *
-     * @deprecated Health Device Profile (HDP) and MCAP protocol are no longer used. New
-     * apps should use Bluetooth Low Energy based solutions such as {@link BluetoothGatt},
-     * {@link BluetoothAdapter#listenUsingL2capChannel()(int)}, or
-     * {@link BluetoothDevice#createL2capChannel(int)}
-     */
-    @Deprecated
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SuppressLint("AndroidFrameworkRequiresPermission")
-    public boolean disconnectChannel(BluetoothDevice device,
-            BluetoothHealthAppConfiguration config, int channelId) {
-        Log.e(TAG, "disconnectChannel(): BluetoothHealth is deprecated");
-        return false;
-    }
-
-    /**
-     * Get the file descriptor of the main channel associated with the remote device
-     * and application configuration.
-     *
-     * <p> Its the responsibility of the caller to close the ParcelFileDescriptor
-     * when done.
-     *
-     * @param device The remote Bluetooth health device
-     * @param config The application configuration
-     * @return null on failure, ParcelFileDescriptor on success.
-     *
-     * @deprecated Health Device Profile (HDP) and MCAP protocol are no longer used. New
-     * apps should use Bluetooth Low Energy based solutions such as {@link BluetoothGatt},
-     * {@link BluetoothAdapter#listenUsingL2capChannel()(int)}, or
-     * {@link BluetoothDevice#createL2capChannel(int)}
-     */
-    @Deprecated
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SuppressLint("AndroidFrameworkRequiresPermission")
-    public ParcelFileDescriptor getMainChannelFd(BluetoothDevice device,
-            BluetoothHealthAppConfiguration config) {
-        Log.e(TAG, "getMainChannelFd(): BluetoothHealth is deprecated");
-        return null;
-    }
-
-    /**
-     * Get the current connection state of the profile.
-     *
-     * This is not specific to any application configuration but represents the connection
-     * state of the local Bluetooth adapter with the remote device. This can be used
-     * by applications like status bar which would just like to know the state of the
-     * local adapter.
-     *
-     * @param device Remote bluetooth device.
-     * @return State of the profile connection. One of {@link #STATE_CONNECTED}, {@link
-     * #STATE_CONNECTING}, {@link #STATE_DISCONNECTED}, {@link #STATE_DISCONNECTING}
-     */
-    @Override
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SuppressLint("AndroidFrameworkRequiresPermission")
-    public int getConnectionState(BluetoothDevice device) {
-        Log.e(TAG, "getConnectionState(): BluetoothHealth is deprecated");
-        return STATE_DISCONNECTED;
-    }
-
-    /**
-     * Get connected devices for the health profile.
-     *
-     * <p> Return the set of devices which are in state {@link #STATE_CONNECTED}
-     *
-     * This is not specific to any application configuration but represents the connection
-     * state of the local Bluetooth adapter for this profile. This can be used
-     * by applications like status bar which would just like to know the state of the
-     * local adapter.
-     *
-     * @return List of devices. The list will be empty on error.
-     */
-    @Override
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SuppressLint("AndroidFrameworkRequiresPermission")
-    public List<BluetoothDevice> getConnectedDevices() {
-        Log.e(TAG, "getConnectedDevices(): BluetoothHealth is deprecated");
-        return new ArrayList<>();
-    }
-
-    /**
-     * Get a list of devices that match any of the given connection
-     * states.
-     *
-     * <p> If none of the devices match any of the given states,
-     * an empty list will be returned.
-     *
-     * <p>This is not specific to any application configuration but represents the connection
-     * state of the local Bluetooth adapter for this profile. This can be used
-     * by applications like status bar which would just like to know the state of the
-     * local adapter.
-     *
-     * @param states Array of states. States can be one of {@link #STATE_CONNECTED}, {@link
-     * #STATE_CONNECTING}, {@link #STATE_DISCONNECTED}, {@link #STATE_DISCONNECTING},
-     * @return List of devices. The list will be empty on error.
-     */
-    @Override
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SuppressLint("AndroidFrameworkRequiresPermission")
-    public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
-        Log.e(TAG, "getDevicesMatchingConnectionStates(): BluetoothHealth is deprecated");
-        return new ArrayList<>();
-    }
-
-    /** Health Channel Connection State - Disconnected
-     *
-     * @deprecated Health Device Profile (HDP) and MCAP protocol are no longer used. New
-     * apps should use Bluetooth Low Energy based solutions such as {@link BluetoothGatt},
-     * {@link BluetoothAdapter#listenUsingL2capChannel()(int)}, or
-     * {@link BluetoothDevice#createL2capChannel(int)}
-     */
-    @Deprecated
-    public static final int STATE_CHANNEL_DISCONNECTED = 0;
-    /** Health Channel Connection State - Connecting
-     *
-     * @deprecated Health Device Profile (HDP) and MCAP protocol are no longer used. New
-     * apps should use Bluetooth Low Energy based solutions such as {@link BluetoothGatt},
-     * {@link BluetoothAdapter#listenUsingL2capChannel()(int)}, or
-     * {@link BluetoothDevice#createL2capChannel(int)}
-     */
-    @Deprecated
-    public static final int STATE_CHANNEL_CONNECTING = 1;
-    /** Health Channel Connection State - Connected
-     *
-     * @deprecated Health Device Profile (HDP) and MCAP protocol are no longer used. New
-     * apps should use Bluetooth Low Energy based solutions such as {@link BluetoothGatt},
-     * {@link BluetoothAdapter#listenUsingL2capChannel()(int)}, or
-     * {@link BluetoothDevice#createL2capChannel(int)}
-     */
-    @Deprecated
-    public static final int STATE_CHANNEL_CONNECTED = 2;
-    /** Health Channel Connection State - Disconnecting
-     *
-     * @deprecated Health Device Profile (HDP) and MCAP protocol are no longer used. New
-     * apps should use Bluetooth Low Energy based solutions such as {@link BluetoothGatt},
-     * {@link BluetoothAdapter#listenUsingL2capChannel()(int)}, or
-     * {@link BluetoothDevice#createL2capChannel(int)}
-     */
-    @Deprecated
-    public static final int STATE_CHANNEL_DISCONNECTING = 3;
-
-    /** Health App Configuration registration success
-     *
-     * @deprecated Health Device Profile (HDP) and MCAP protocol are no longer used. New
-     * apps should use Bluetooth Low Energy based solutions such as {@link BluetoothGatt},
-     * {@link BluetoothAdapter#listenUsingL2capChannel()(int)}, or
-     * {@link BluetoothDevice#createL2capChannel(int)}
-     */
-    @Deprecated
-    public static final int APP_CONFIG_REGISTRATION_SUCCESS = 0;
-    /** Health App Configuration registration failure
-     *
-     * @deprecated Health Device Profile (HDP) and MCAP protocol are no longer used. New
-     * apps should use Bluetooth Low Energy based solutions such as {@link BluetoothGatt},
-     * {@link BluetoothAdapter#listenUsingL2capChannel()(int)}, or
-     * {@link BluetoothDevice#createL2capChannel(int)}
-     */
-    @Deprecated
-    public static final int APP_CONFIG_REGISTRATION_FAILURE = 1;
-    /** Health App Configuration un-registration success
-     *
-     * @deprecated Health Device Profile (HDP) and MCAP protocol are no longer used. New
-     * apps should use Bluetooth Low Energy based solutions such as {@link BluetoothGatt},
-     * {@link BluetoothAdapter#listenUsingL2capChannel()(int)}, or
-     * {@link BluetoothDevice#createL2capChannel(int)}
-     */
-    @Deprecated
-    public static final int APP_CONFIG_UNREGISTRATION_SUCCESS = 2;
-    /** Health App Configuration un-registration failure
-     *
-     * @deprecated Health Device Profile (HDP) and MCAP protocol are no longer used. New
-     * apps should use Bluetooth Low Energy based solutions such as {@link BluetoothGatt},
-     * {@link BluetoothAdapter#listenUsingL2capChannel()(int)}, or
-     * {@link BluetoothDevice#createL2capChannel(int)}
-     */
-    @Deprecated
-    public static final int APP_CONFIG_UNREGISTRATION_FAILURE = 3;
-}
diff --git a/core/java/android/bluetooth/BluetoothHealthAppConfiguration.java b/core/java/android/bluetooth/BluetoothHealthAppConfiguration.java
deleted file mode 100644
index 2f66df2..0000000
--- a/core/java/android/bluetooth/BluetoothHealthAppConfiguration.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2011 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.bluetooth;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * The Bluetooth Health Application Configuration that is used in conjunction with
- * the {@link BluetoothHealth} class. This class represents an application configuration
- * that the Bluetooth Health third party application will register to communicate with the
- * remote Bluetooth health device.
- *
- * @deprecated Health Device Profile (HDP) and MCAP protocol are no longer used. New
- * apps should use Bluetooth Low Energy based solutions such as {@link BluetoothGatt},
- * {@link BluetoothAdapter#listenUsingL2capChannel()(int)}, or
- * {@link BluetoothDevice#createL2capChannel(int)}
- */
-@Deprecated
-public final class BluetoothHealthAppConfiguration implements Parcelable {
-
-    /**
-     * Hide auto-created default constructor
-     * @hide
-     */
-    BluetoothHealthAppConfiguration() {}
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    /**
-     * Return the data type associated with this application configuration.
-     *
-     * @return dataType
-     *
-     * @deprecated Health Device Profile (HDP) and MCAP protocol are no longer used. New
-     * apps should use Bluetooth Low Energy based solutions such as {@link BluetoothGatt},
-     * {@link BluetoothAdapter#listenUsingL2capChannel()(int)}, or
-     * {@link BluetoothDevice#createL2capChannel(int)}
-     */
-    @Deprecated
-    public int getDataType() {
-        return 0;
-    }
-
-    /**
-     * Return the name of the application configuration.
-     *
-     * @return String name
-     *
-     * @deprecated Health Device Profile (HDP) and MCAP protocol are no longer used. New
-     * apps should use Bluetooth Low Energy based solutions such as {@link BluetoothGatt},
-     * {@link BluetoothAdapter#listenUsingL2capChannel()(int)}, or
-     * {@link BluetoothDevice#createL2capChannel(int)}
-     */
-    @Deprecated
-    public String getName() {
-        return null;
-    }
-
-    /**
-     * Return the role associated with this application configuration.
-     *
-     * @return One of {@link BluetoothHealth#SOURCE_ROLE} or {@link BluetoothHealth#SINK_ROLE}
-     *
-     * @deprecated Health Device Profile (HDP) and MCAP protocol are no longer used. New
-     * apps should use Bluetooth Low Energy based solutions such as {@link BluetoothGatt},
-     * {@link BluetoothAdapter#listenUsingL2capChannel()(int)}, or
-     * {@link BluetoothDevice#createL2capChannel(int)}
-     */
-    @Deprecated
-    public int getRole() {
-        return 0;
-    }
-
-    /**
-     * @deprecated Health Device Profile (HDP) and MCAP protocol are no longer used. New
-     * apps should use Bluetooth Low Energy based solutions such as {@link BluetoothGatt},
-     * {@link BluetoothAdapter#listenUsingL2capChannel()(int)}, or
-     * {@link BluetoothDevice#createL2capChannel(int)}
-     */
-    @Deprecated
-    public static final @android.annotation.NonNull Parcelable.Creator<BluetoothHealthAppConfiguration> CREATOR =
-            new Parcelable.Creator<BluetoothHealthAppConfiguration>() {
-                @Override
-                public BluetoothHealthAppConfiguration createFromParcel(Parcel in) {
-                    return new BluetoothHealthAppConfiguration();
-                }
-
-                @Override
-                public BluetoothHealthAppConfiguration[] newArray(int size) {
-                    return new BluetoothHealthAppConfiguration[size];
-                }
-            };
-
-    @Override
-    public void writeToParcel(Parcel out, int flags) {}
-}
diff --git a/core/java/android/bluetooth/BluetoothHealthCallback.java b/core/java/android/bluetooth/BluetoothHealthCallback.java
deleted file mode 100644
index 4769212..0000000
--- a/core/java/android/bluetooth/BluetoothHealthCallback.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2011 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.bluetooth;
-
-import android.annotation.BinderThread;
-import android.os.ParcelFileDescriptor;
-import android.util.Log;
-
-/**
- * This abstract class is used to implement {@link BluetoothHealth} callbacks.
- *
- * @deprecated Health Device Profile (HDP) and MCAP protocol are no longer used. New
- * apps should use Bluetooth Low Energy based solutions such as {@link BluetoothGatt},
- * {@link BluetoothAdapter#listenUsingL2capChannel()(int)}, or
- * {@link BluetoothDevice#createL2capChannel(int)}
- */
-@Deprecated
-public abstract class BluetoothHealthCallback {
-    private static final String TAG = "BluetoothHealthCallback";
-
-    /**
-     * Callback to inform change in registration state of the health
-     * application.
-     * <p> This callback is called on the binder thread (not on the UI thread)
-     *
-     * @param config Bluetooth Health app configuration
-     * @param status Success or failure of the registration or unregistration calls. Can be one of
-     * {@link BluetoothHealth#APP_CONFIG_REGISTRATION_SUCCESS} or {@link
-     * BluetoothHealth#APP_CONFIG_REGISTRATION_FAILURE} or
-     * {@link BluetoothHealth#APP_CONFIG_UNREGISTRATION_SUCCESS}
-     * or {@link BluetoothHealth#APP_CONFIG_UNREGISTRATION_FAILURE}
-     *
-     * @deprecated Health Device Profile (HDP) and MCAP protocol are no longer used. New
-     * apps should use Bluetooth Low Energy based solutions such as {@link BluetoothGatt},
-     * {@link BluetoothAdapter#listenUsingL2capChannel()(int)}, or
-     * {@link BluetoothDevice#createL2capChannel(int)}
-     */
-    @BinderThread
-    @Deprecated
-    public void onHealthAppConfigurationStatusChange(BluetoothHealthAppConfiguration config,
-            int status) {
-        Log.d(TAG, "onHealthAppConfigurationStatusChange: " + config + "Status: " + status);
-    }
-
-    /**
-     * Callback to inform change in channel state.
-     * <p> Its the responsibility of the implementor of this callback to close the
-     * parcel file descriptor when done. This callback is called on the Binder
-     * thread (not the UI thread)
-     *
-     * @param config The Health app configutation
-     * @param device The Bluetooth Device
-     * @param prevState The previous state of the channel
-     * @param newState The new state of the channel.
-     * @param fd The Parcel File Descriptor when the channel state is connected.
-     * @param channelId The id associated with the channel. This id will be used in future calls
-     * like when disconnecting the channel.
-     *
-     * @deprecated Health Device Profile (HDP) and MCAP protocol are no longer used. New
-     * apps should use Bluetooth Low Energy based solutions such as {@link BluetoothGatt},
-     * {@link BluetoothAdapter#listenUsingL2capChannel()(int)}, or
-     * {@link BluetoothDevice#createL2capChannel(int)}
-     */
-    @BinderThread
-    @Deprecated
-    public void onHealthChannelStateChange(BluetoothHealthAppConfiguration config,
-            BluetoothDevice device, int prevState, int newState, ParcelFileDescriptor fd,
-            int channelId) {
-        Log.d(TAG, "onHealthChannelStateChange: " + config + "Device: " + device
-                + "prevState:" + prevState + "newState:" + newState + "ParcelFd:" + fd
-                + "ChannelId:" + channelId);
-    }
-}
diff --git a/core/java/android/bluetooth/BluetoothHearingAid.java b/core/java/android/bluetooth/BluetoothHearingAid.java
deleted file mode 100644
index 339a75f..0000000
--- a/core/java/android/bluetooth/BluetoothHearingAid.java
+++ /dev/null
@@ -1,691 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-import static android.bluetooth.BluetoothUtils.getSyncTimeout;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.RequiresPermission;
-import android.annotation.SdkConstant;
-import android.annotation.SdkConstant.SdkConstantType;
-import android.annotation.SystemApi;
-import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
-import android.bluetooth.annotations.RequiresLegacyBluetoothAdminPermission;
-import android.bluetooth.annotations.RequiresLegacyBluetoothPermission;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.content.AttributionSource;
-import android.content.Context;
-import android.os.Build;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.util.Log;
-
-import com.android.modules.utils.SynchronousResultReceiver;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.TimeoutException;
-
-/**
- * This class provides the public APIs to control the Hearing Aid profile.
- *
- * <p>BluetoothHearingAid is a proxy object for controlling the Bluetooth Hearing Aid
- * Service via IPC. Use {@link BluetoothAdapter#getProfileProxy} to get
- * the BluetoothHearingAid proxy object.
- *
- * <p> Android only supports one set of connected Bluetooth Hearing Aid device at a time. Each
- * method is protected with its appropriate permission.
- */
-public final class BluetoothHearingAid implements BluetoothProfile {
-    private static final String TAG = "BluetoothHearingAid";
-    private static final boolean DBG = true;
-    private static final boolean VDBG = false;
-
-    /**
-     * Intent used to broadcast the change in connection state of the Hearing Aid
-     * profile. Please note that in the binaural case, there will be two different LE devices for
-     * the left and right side and each device will have their own connection state changes.S
-     *
-     * <p>This intent will have 3 extras:
-     * <ul>
-     * <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
-     * <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li>
-     * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
-     * </ul>
-     *
-     * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
-     * {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTING},
-     * {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTING}.
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_CONNECTION_STATE_CHANGED =
-            "android.bluetooth.hearingaid.profile.action.CONNECTION_STATE_CHANGED";
-
-    /**
-     * Intent used to broadcast the selection of a connected device as active.
-     *
-     * <p>This intent will have one extra:
-     * <ul>
-     * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. It can
-     * be null if no device is active. </li>
-     * </ul>
-     *
-     * @hide
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_ACTIVE_DEVICE_CHANGED =
-            "android.bluetooth.hearingaid.profile.action.ACTIVE_DEVICE_CHANGED";
-
-    /**
-     * This device represents Left Hearing Aid.
-     *
-     * @hide
-     */
-    public static final int SIDE_LEFT = IBluetoothHearingAid.SIDE_LEFT;
-
-    /**
-     * This device represents Right Hearing Aid.
-     *
-     * @hide
-     */
-    public static final int SIDE_RIGHT = IBluetoothHearingAid.SIDE_RIGHT;
-
-    /**
-     * This device is Monaural.
-     *
-     * @hide
-     */
-    public static final int MODE_MONAURAL = IBluetoothHearingAid.MODE_MONAURAL;
-
-    /**
-     * This device is Binaural (should receive only left or right audio).
-     *
-     * @hide
-     */
-    public static final int MODE_BINAURAL = IBluetoothHearingAid.MODE_BINAURAL;
-
-    /**
-     * Indicates the HiSyncID could not be read and is unavailable.
-     *
-     * @hide
-     */
-    public static final long HI_SYNC_ID_INVALID = IBluetoothHearingAid.HI_SYNC_ID_INVALID;
-
-    private final BluetoothAdapter mAdapter;
-    private final AttributionSource mAttributionSource;
-    private final BluetoothProfileConnector<IBluetoothHearingAid> mProfileConnector =
-            new BluetoothProfileConnector(this, BluetoothProfile.HEARING_AID,
-                    "BluetoothHearingAid", IBluetoothHearingAid.class.getName()) {
-                @Override
-                public IBluetoothHearingAid getServiceInterface(IBinder service) {
-                    return IBluetoothHearingAid.Stub.asInterface(service);
-                }
-    };
-
-    /**
-     * Create a BluetoothHearingAid proxy object for interacting with the local
-     * Bluetooth Hearing Aid service.
-     */
-    /* package */ BluetoothHearingAid(Context context, ServiceListener listener,
-            BluetoothAdapter adapter) {
-        mAdapter = adapter;
-        mAttributionSource = adapter.getAttributionSource();
-        mProfileConnector.connect(context, listener);
-    }
-
-    /*package*/ void close() {
-        mProfileConnector.disconnect();
-    }
-
-    private IBluetoothHearingAid getService() {
-        return mProfileConnector.getService();
-    }
-
-    /**
-     * Initiate connection to a profile of the remote bluetooth device.
-     *
-     * <p> This API returns false in scenarios like the profile on the
-     * device is already connected or Bluetooth is not turned on.
-     * When this API returns true, it is guaranteed that
-     * connection state intent for the profile will be broadcasted with
-     * the state. Users can get the connection state of the profile
-     * from this intent.
-     *
-     * @param device Remote Bluetooth Device
-     * @return false on immediate error, true otherwise
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public boolean connect(BluetoothDevice device) {
-        if (DBG) log("connect(" + device + ")");
-        final IBluetoothHearingAid service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.connect(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Initiate disconnection from a profile
-     *
-     * <p> This API will return false in scenarios like the profile on the
-     * Bluetooth device is not in connected state etc. When this API returns,
-     * true, it is guaranteed that the connection state change
-     * intent will be broadcasted with the state. Users can get the
-     * disconnection state of the profile from this intent.
-     *
-     * <p> If the disconnection is initiated by a remote device, the state
-     * will transition from {@link #STATE_CONNECTED} to
-     * {@link #STATE_DISCONNECTED}. If the disconnect is initiated by the
-     * host (local) device the state will transition from
-     * {@link #STATE_CONNECTED} to state {@link #STATE_DISCONNECTING} to
-     * state {@link #STATE_DISCONNECTED}. The transition to
-     * {@link #STATE_DISCONNECTING} can be used to distinguish between the
-     * two scenarios.
-     *
-     * @param device Remote Bluetooth Device
-     * @return false on immediate error, true otherwise
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public boolean disconnect(BluetoothDevice device) {
-        if (DBG) log("disconnect(" + device + ")");
-        final IBluetoothHearingAid service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.disconnect(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public @NonNull List<BluetoothDevice> getConnectedDevices() {
-        if (VDBG) log("getConnectedDevices()");
-        final IBluetoothHearingAid service = getService();
-        final List<BluetoothDevice> defaultValue = new ArrayList<BluetoothDevice>();
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<List<BluetoothDevice>> recv =
-                        new SynchronousResultReceiver();
-                service.getConnectedDevices(mAttributionSource, recv);
-                return Attributable.setAttributionSource(
-                        recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
-                        mAttributionSource);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public @NonNull List<BluetoothDevice> getDevicesMatchingConnectionStates(
-    @NonNull int[] states) {
-        if (VDBG) log("getDevicesMatchingStates()");
-        final IBluetoothHearingAid service = getService();
-        final List<BluetoothDevice> defaultValue = new ArrayList<BluetoothDevice>();
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<List<BluetoothDevice>> recv =
-                        new SynchronousResultReceiver();
-                service.getDevicesMatchingConnectionStates(states, mAttributionSource, recv);
-                return Attributable.setAttributionSource(
-                        recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
-                        mAttributionSource);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public @BluetoothProfile.BtProfileState int getConnectionState(
-    @NonNull BluetoothDevice device) {
-        if (VDBG) log("getState(" + device + ")");
-        final IBluetoothHearingAid service = getService();
-        final int defaultValue = BluetoothProfile.STATE_DISCONNECTED;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
-                service.getConnectionState(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Select a connected device as active.
-     *
-     * The active device selection is per profile. An active device's
-     * purpose is profile-specific. For example, Hearing Aid audio
-     * streaming is to the active Hearing Aid device. If a remote device
-     * is not connected, it cannot be selected as active.
-     *
-     * <p> This API returns false in scenarios like the profile on the
-     * device is not connected or Bluetooth is not turned on.
-     * When this API returns true, it is guaranteed that the
-     * {@link #ACTION_ACTIVE_DEVICE_CHANGED} intent will be broadcasted
-     * with the active device.
-     *
-     * @param device the remote Bluetooth device. Could be null to clear
-     * the active device and stop streaming audio to a Bluetooth device.
-     * @return false on immediate error, true otherwise
-     * @hide
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    public boolean setActiveDevice(@Nullable BluetoothDevice device) {
-        if (DBG) log("setActiveDevice(" + device + ")");
-        final IBluetoothHearingAid service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && ((device == null) || isValidDevice(device))) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.setActiveDevice(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Get the connected physical Hearing Aid devices that are active
-     *
-     * @return the list of active devices. The first element is the left active
-     * device; the second element is the right active device. If either or both side
-     * is not active, it will be null on that position. Returns empty list on error.
-     * @hide
-     */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public @NonNull List<BluetoothDevice> getActiveDevices() {
-        if (VDBG) log("getActiveDevices()");
-        final IBluetoothHearingAid service = getService();
-        final List<BluetoothDevice> defaultValue = new ArrayList<>();
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<List<BluetoothDevice>> recv =
-                        new SynchronousResultReceiver();
-                service.getActiveDevices(mAttributionSource, recv);
-                return Attributable.setAttributionSource(
-                        recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
-                        mAttributionSource);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Set priority of the profile
-     *
-     * <p> The device should already be paired.
-     * Priority can be one of {@link #PRIORITY_ON} or {@link #PRIORITY_OFF},
-     *
-     * @param device Paired bluetooth device
-     * @param priority
-     * @return true if priority is set, false on error
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public boolean setPriority(BluetoothDevice device, int priority) {
-        if (DBG) log("setPriority(" + device + ", " + priority + ")");
-        return setConnectionPolicy(device, BluetoothAdapter.priorityToConnectionPolicy(priority));
-    }
-
-    /**
-     * Set connection policy of the profile
-     *
-     * <p> The device should already be paired.
-     * Connection policy can be one of {@link #CONNECTION_POLICY_ALLOWED},
-     * {@link #CONNECTION_POLICY_FORBIDDEN}, {@link #CONNECTION_POLICY_UNKNOWN}
-     *
-     * @param device Paired bluetooth device
-     * @param connectionPolicy is the connection policy to set to for this profile
-     * @return true if connectionPolicy is set, false on error
-     * @hide
-     */
-    @SystemApi
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public boolean setConnectionPolicy(@NonNull BluetoothDevice device,
-            @ConnectionPolicy int connectionPolicy) {
-        if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
-        verifyDeviceNotNull(device, "setConnectionPolicy");
-        final IBluetoothHearingAid service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)
-                    && (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_FORBIDDEN
-                        || connectionPolicy == BluetoothProfile.CONNECTION_POLICY_ALLOWED)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.setConnectionPolicy(device, connectionPolicy, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Get the priority of the profile.
-     *
-     * <p> The priority can be any of:
-     * {@link #PRIORITY_OFF}, {@link #PRIORITY_ON}, {@link #PRIORITY_UNDEFINED}
-     *
-     * @param device Bluetooth device
-     * @return priority of the device
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public int getPriority(BluetoothDevice device) {
-        if (VDBG) log("getPriority(" + device + ")");
-        return BluetoothAdapter.connectionPolicyToPriority(getConnectionPolicy(device));
-    }
-
-    /**
-     * Get the connection policy of the profile.
-     *
-     * <p> The connection policy can be any of:
-     * {@link #CONNECTION_POLICY_ALLOWED}, {@link #CONNECTION_POLICY_FORBIDDEN},
-     * {@link #CONNECTION_POLICY_UNKNOWN}
-     *
-     * @param device Bluetooth device
-     * @return connection policy of the device
-     * @hide
-     */
-    @SystemApi
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public @ConnectionPolicy int getConnectionPolicy(@NonNull BluetoothDevice device) {
-        if (VDBG) log("getConnectionPolicy(" + device + ")");
-        verifyDeviceNotNull(device, "getConnectionPolicy");
-        final IBluetoothHearingAid service = getService();
-        final int defaultValue = BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
-                service.getConnectionPolicy(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Helper for converting a state to a string.
-     *
-     * For debug use only - strings are not internationalized.
-     *
-     * @hide
-     */
-    public static String stateToString(int state) {
-        switch (state) {
-            case STATE_DISCONNECTED:
-                return "disconnected";
-            case STATE_CONNECTING:
-                return "connecting";
-            case STATE_CONNECTED:
-                return "connected";
-            case STATE_DISCONNECTING:
-                return "disconnecting";
-            default:
-                return "<unknown state " + state + ">";
-        }
-    }
-
-    /**
-     * Tells remote device to set an absolute volume.
-     *
-     * @param volume Absolute volume to be set on remote
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public void setVolume(int volume) {
-        if (DBG) Log.d(TAG, "setVolume(" + volume + ")");
-        final IBluetoothHearingAid service = getService();
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver recv = new SynchronousResultReceiver();
-                service.setVolume(volume, mAttributionSource, recv);
-                recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(null);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-    }
-
-    /**
-     * Get the HiSyncId (unique hearing aid device identifier) of the device.
-     *
-     * <a href=https://source.android.com/devices/bluetooth/asha#hisyncid>HiSyncId documentation
-     * can be found here</a>
-     *
-     * @param device Bluetooth device
-     * @return the HiSyncId of the device
-     * @hide
-     */
-    @SystemApi
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public long getHiSyncId(@NonNull BluetoothDevice device) {
-        if (VDBG) log("getHiSyncId(" + device + ")");
-        verifyDeviceNotNull(device, "getConnectionPolicy");
-        final IBluetoothHearingAid service = getService();
-        final long defaultValue = HI_SYNC_ID_INVALID;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Long> recv = new SynchronousResultReceiver();
-                service.getHiSyncId(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Get the side of the device.
-     *
-     * @param device Bluetooth device.
-     * @return SIDE_LEFT or SIDE_RIGHT
-     * @hide
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public int getDeviceSide(BluetoothDevice device) {
-        if (VDBG) log("getDeviceSide(" + device + ")");
-        final IBluetoothHearingAid service = getService();
-        final int defaultValue = SIDE_LEFT;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
-                service.getDeviceSide(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Get the mode of the device.
-     *
-     * @param device Bluetooth device
-     * @return MODE_MONAURAL or MODE_BINAURAL
-     * @hide
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public int getDeviceMode(BluetoothDevice device) {
-        if (VDBG) log("getDeviceMode(" + device + ")");
-        final IBluetoothHearingAid service = getService();
-        final int defaultValue = MODE_MONAURAL;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
-                service.getDeviceMode(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    private boolean isEnabled() {
-        if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true;
-        return false;
-    }
-
-    private void verifyDeviceNotNull(BluetoothDevice device, String methodName) {
-        if (device == null) {
-            Log.e(TAG, methodName + ": device param is null");
-            throw new IllegalArgumentException("Device cannot be null");
-        }
-    }
-
-    private boolean isValidDevice(BluetoothDevice device) {
-        if (device == null) return false;
-
-        if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
-        return false;
-    }
-
-    private static void log(String msg) {
-        Log.d(TAG, msg);
-    }
-}
diff --git a/core/java/android/bluetooth/BluetoothHidDevice.java b/core/java/android/bluetooth/BluetoothHidDevice.java
deleted file mode 100644
index 44a355b..0000000
--- a/core/java/android/bluetooth/BluetoothHidDevice.java
+++ /dev/null
@@ -1,848 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-import static android.bluetooth.BluetoothUtils.getSyncTimeout;
-
-import android.Manifest;
-import android.annotation.NonNull;
-import android.annotation.RequiresPermission;
-import android.annotation.SdkConstant;
-import android.annotation.SdkConstant.SdkConstantType;
-import android.annotation.SystemApi;
-import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
-import android.bluetooth.annotations.RequiresLegacyBluetoothPermission;
-import android.content.AttributionSource;
-import android.content.Context;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.util.Log;
-
-import com.android.modules.utils.SynchronousResultReceiver;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.Executor;
-import java.util.concurrent.TimeoutException;
-
-/**
- * Provides the public APIs to control the Bluetooth HID Device profile.
- *
- * <p>BluetoothHidDevice is a proxy object for controlling the Bluetooth HID Device Service via IPC.
- * Use {@link BluetoothAdapter#getProfileProxy} to get the BluetoothHidDevice proxy object.
- */
-public final class BluetoothHidDevice implements BluetoothProfile {
-    private static final String TAG = BluetoothHidDevice.class.getSimpleName();
-    private static final boolean DBG = false;
-
-    /**
-     * Intent used to broadcast the change in connection state of the Input Host profile.
-     *
-     * <p>This intent will have 3 extras:
-     *
-     * <ul>
-     *   <li>{@link #EXTRA_STATE} - The current state of the profile.
-     *   <li>{@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.
-     *   <li>{@link BluetoothDevice#EXTRA_DEVICE} - The remote device.
-     * </ul>
-     *
-     * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of {@link
-     * #STATE_DISCONNECTED}, {@link #STATE_CONNECTING}, {@link #STATE_CONNECTED}, {@link
-     * #STATE_DISCONNECTING}.
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_CONNECTION_STATE_CHANGED =
-            "android.bluetooth.hiddevice.profile.action.CONNECTION_STATE_CHANGED";
-
-    /**
-     * Constant representing unspecified HID device subclass.
-     *
-     * @see #registerApp (BluetoothHidDeviceAppQosSettings, BluetoothHidDeviceAppQosSettings,
-     *     BluetoothHidDeviceAppQosSettings, Executor, Callback)
-     */
-    public static final byte SUBCLASS1_NONE = (byte) 0x00;
-    /**
-     * Constant representing keyboard subclass.
-     *
-     * @see #registerApp (BluetoothHidDeviceAppQosSettings, BluetoothHidDeviceAppQosSettings,
-     *     BluetoothHidDeviceAppQosSettings, Executor, Callback)
-     */
-    public static final byte SUBCLASS1_KEYBOARD = (byte) 0x40;
-    /**
-     * Constant representing mouse subclass.
-     *
-     * @see #registerApp (BluetoothHidDeviceAppQosSettings, BluetoothHidDeviceAppQosSettings,
-     *     BluetoothHidDeviceAppQosSettings, Executor, Callback)
-     */
-    public static final byte SUBCLASS1_MOUSE = (byte) 0x80;
-    /**
-     * Constant representing combo keyboard and mouse subclass.
-     *
-     * @see #registerApp (BluetoothHidDeviceAppQosSettings, BluetoothHidDeviceAppQosSettings,
-     *     BluetoothHidDeviceAppQosSettings, Executor, Callback)
-     */
-    public static final byte SUBCLASS1_COMBO = (byte) 0xC0;
-
-    /**
-     * Constant representing uncategorized HID device subclass.
-     *
-     * @see #registerApp (BluetoothHidDeviceAppQosSettings, BluetoothHidDeviceAppQosSettings,
-     *     BluetoothHidDeviceAppQosSettings, Executor, Callback)
-     */
-    public static final byte SUBCLASS2_UNCATEGORIZED = (byte) 0x00;
-    /**
-     * Constant representing joystick subclass.
-     *
-     * @see #registerApp (BluetoothHidDeviceAppQosSettings, BluetoothHidDeviceAppQosSettings,
-     *     BluetoothHidDeviceAppQosSettings, Executor, Callback)
-     */
-    public static final byte SUBCLASS2_JOYSTICK = (byte) 0x01;
-    /**
-     * Constant representing gamepad subclass.
-     *
-     * @see #registerApp (BluetoothHidDeviceAppQosSettings, BluetoothHidDeviceAppQosSettings,
-     *     BluetoothHidDeviceAppQosSettings, Executor, Callback)
-     */
-    public static final byte SUBCLASS2_GAMEPAD = (byte) 0x02;
-    /**
-     * Constant representing remote control subclass.
-     *
-     * @see #registerApp (BluetoothHidDeviceAppQosSettings, BluetoothHidDeviceAppQosSettings,
-     *     BluetoothHidDeviceAppQosSettings, Executor, Callback)
-     */
-    public static final byte SUBCLASS2_REMOTE_CONTROL = (byte) 0x03;
-    /**
-     * Constant representing sensing device subclass.
-     *
-     * @see #registerApp (BluetoothHidDeviceAppQosSettings, BluetoothHidDeviceAppQosSettings,
-     *     BluetoothHidDeviceAppQosSettings, Executor, Callback)
-     */
-    public static final byte SUBCLASS2_SENSING_DEVICE = (byte) 0x04;
-    /**
-     * Constant representing digitizer tablet subclass.
-     *
-     * @see #registerApp (BluetoothHidDeviceAppQosSettings, BluetoothHidDeviceAppQosSettings,
-     *     BluetoothHidDeviceAppQosSettings, Executor, Callback)
-     */
-    public static final byte SUBCLASS2_DIGITIZER_TABLET = (byte) 0x05;
-    /**
-     * Constant representing card reader subclass.
-     *
-     * @see #registerApp (BluetoothHidDeviceAppQosSettings, BluetoothHidDeviceAppQosSettings,
-     *     BluetoothHidDeviceAppQosSettings, Executor, Callback)
-     */
-    public static final byte SUBCLASS2_CARD_READER = (byte) 0x06;
-
-    /**
-     * Constant representing HID Input Report type.
-     *
-     * @see Callback#onGetReport(BluetoothDevice, byte, byte, int)
-     * @see Callback#onSetReport(BluetoothDevice, byte, byte, byte[])
-     * @see Callback#onInterruptData(BluetoothDevice, byte, byte[])
-     */
-    public static final byte REPORT_TYPE_INPUT = (byte) 1;
-    /**
-     * Constant representing HID Output Report type.
-     *
-     * @see Callback#onGetReport(BluetoothDevice, byte, byte, int)
-     * @see Callback#onSetReport(BluetoothDevice, byte, byte, byte[])
-     * @see Callback#onInterruptData(BluetoothDevice, byte, byte[])
-     */
-    public static final byte REPORT_TYPE_OUTPUT = (byte) 2;
-    /**
-     * Constant representing HID Feature Report type.
-     *
-     * @see Callback#onGetReport(BluetoothDevice, byte, byte, int)
-     * @see Callback#onSetReport(BluetoothDevice, byte, byte, byte[])
-     * @see Callback#onInterruptData(BluetoothDevice, byte, byte[])
-     */
-    public static final byte REPORT_TYPE_FEATURE = (byte) 3;
-
-    /**
-     * Constant representing success response for Set Report.
-     *
-     * @see Callback#onSetReport(BluetoothDevice, byte, byte, byte[])
-     */
-    public static final byte ERROR_RSP_SUCCESS = (byte) 0;
-    /**
-     * Constant representing error response for Set Report due to "not ready".
-     *
-     * @see Callback#onSetReport(BluetoothDevice, byte, byte, byte[])
-     */
-    public static final byte ERROR_RSP_NOT_READY = (byte) 1;
-    /**
-     * Constant representing error response for Set Report due to "invalid report ID".
-     *
-     * @see Callback#onSetReport(BluetoothDevice, byte, byte, byte[])
-     */
-    public static final byte ERROR_RSP_INVALID_RPT_ID = (byte) 2;
-    /**
-     * Constant representing error response for Set Report due to "unsupported request".
-     *
-     * @see Callback#onSetReport(BluetoothDevice, byte, byte, byte[])
-     */
-    public static final byte ERROR_RSP_UNSUPPORTED_REQ = (byte) 3;
-    /**
-     * Constant representing error response for Set Report due to "invalid parameter".
-     *
-     * @see Callback#onSetReport(BluetoothDevice, byte, byte, byte[])
-     */
-    public static final byte ERROR_RSP_INVALID_PARAM = (byte) 4;
-    /**
-     * Constant representing error response for Set Report with unknown reason.
-     *
-     * @see Callback#onSetReport(BluetoothDevice, byte, byte, byte[])
-     */
-    public static final byte ERROR_RSP_UNKNOWN = (byte) 14;
-
-    /**
-     * Constant representing boot protocol mode used set by host. Default is always {@link
-     * #PROTOCOL_REPORT_MODE} unless notified otherwise.
-     *
-     * @see Callback#onSetProtocol(BluetoothDevice, byte)
-     */
-    public static final byte PROTOCOL_BOOT_MODE = (byte) 0;
-    /**
-     * Constant representing report protocol mode used set by host. Default is always {@link
-     * #PROTOCOL_REPORT_MODE} unless notified otherwise.
-     *
-     * @see Callback#onSetProtocol(BluetoothDevice, byte)
-     */
-    public static final byte PROTOCOL_REPORT_MODE = (byte) 1;
-
-    /**
-     * The template class that applications use to call callback functions on events from the HID
-     * host. Callback functions are wrapped in this class and registered to the Android system
-     * during app registration.
-     */
-    public abstract static class Callback {
-
-        private static final String TAG = "BluetoothHidDevCallback";
-
-        /**
-         * Callback called when application registration state changes. Usually it's called due to
-         * either {@link BluetoothHidDevice#registerApp (String, String, String, byte, byte[],
-         * Executor, Callback)} or {@link BluetoothHidDevice#unregisterApp()} , but can be also
-         * unsolicited in case e.g. Bluetooth was turned off in which case application is
-         * unregistered automatically.
-         *
-         * @param pluggedDevice {@link BluetoothDevice} object which represents host that currently
-         *     has Virtual Cable established with device. Only valid when application is registered,
-         *     can be <code>null</code>.
-         * @param registered <code>true</code> if application is registered, <code>false</code>
-         *     otherwise.
-         */
-        public void onAppStatusChanged(BluetoothDevice pluggedDevice, boolean registered) {
-            Log.d(
-                    TAG,
-                    "onAppStatusChanged: pluggedDevice="
-                            + pluggedDevice
-                            + " registered="
-                            + registered);
-        }
-
-        /**
-         * Callback called when connection state with remote host was changed. Application can
-         * assume than Virtual Cable is established when called with {@link
-         * BluetoothProfile#STATE_CONNECTED} <code>state</code>.
-         *
-         * @param device {@link BluetoothDevice} object representing host device which connection
-         *     state was changed.
-         * @param state Connection state as defined in {@link BluetoothProfile}.
-         */
-        public void onConnectionStateChanged(BluetoothDevice device, int state) {
-            Log.d(TAG, "onConnectionStateChanged: device=" + device + " state=" + state);
-        }
-
-        /**
-         * Callback called when GET_REPORT is received from remote host. Should be replied by
-         * application using {@link BluetoothHidDevice#replyReport(BluetoothDevice, byte, byte,
-         * byte[])}.
-         *
-         * @param type Requested Report Type.
-         * @param id Requested Report Id, can be 0 if no Report Id are defined in descriptor.
-         * @param bufferSize Requested buffer size, application shall respond with at least given
-         *     number of bytes.
-         */
-        public void onGetReport(BluetoothDevice device, byte type, byte id, int bufferSize) {
-            Log.d(
-                    TAG,
-                    "onGetReport: device="
-                            + device
-                            + " type="
-                            + type
-                            + " id="
-                            + id
-                            + " bufferSize="
-                            + bufferSize);
-        }
-
-        /**
-         * Callback called when SET_REPORT is received from remote host. In case received data are
-         * invalid, application shall respond with {@link
-         * BluetoothHidDevice#reportError(BluetoothDevice, byte)}.
-         *
-         * @param type Report Type.
-         * @param id Report Id.
-         * @param data Report data.
-         */
-        public void onSetReport(BluetoothDevice device, byte type, byte id, byte[] data) {
-            Log.d(TAG, "onSetReport: device=" + device + " type=" + type + " id=" + id);
-        }
-
-        /**
-         * Callback called when SET_PROTOCOL is received from remote host. Application shall use
-         * this information to send only reports valid for given protocol mode. By default, {@link
-         * BluetoothHidDevice#PROTOCOL_REPORT_MODE} shall be assumed.
-         *
-         * @param protocol Protocol Mode.
-         */
-        public void onSetProtocol(BluetoothDevice device, byte protocol) {
-            Log.d(TAG, "onSetProtocol: device=" + device + " protocol=" + protocol);
-        }
-
-        /**
-         * Callback called when report data is received over interrupt channel. Report Type is
-         * assumed to be {@link BluetoothHidDevice#REPORT_TYPE_OUTPUT}.
-         *
-         * @param reportId Report Id.
-         * @param data Report data.
-         */
-        public void onInterruptData(BluetoothDevice device, byte reportId, byte[] data) {
-            Log.d(TAG, "onInterruptData: device=" + device + " reportId=" + reportId);
-        }
-
-        /**
-         * Callback called when Virtual Cable is removed. After this callback is received connection
-         * will be disconnected automatically.
-         */
-        public void onVirtualCableUnplug(BluetoothDevice device) {
-            Log.d(TAG, "onVirtualCableUnplug: device=" + device);
-        }
-    }
-
-    private static class CallbackWrapper extends IBluetoothHidDeviceCallback.Stub {
-
-        private final Executor mExecutor;
-        private final Callback mCallback;
-        private final AttributionSource mAttributionSource;
-
-        CallbackWrapper(Executor executor, Callback callback, AttributionSource attributionSource) {
-            mExecutor = executor;
-            mCallback = callback;
-            mAttributionSource = attributionSource;
-        }
-
-        @Override
-        public void onAppStatusChanged(BluetoothDevice pluggedDevice, boolean registered) {
-            Attributable.setAttributionSource(pluggedDevice, mAttributionSource);
-            final long token = clearCallingIdentity();
-            try {
-                mExecutor.execute(() -> mCallback.onAppStatusChanged(pluggedDevice, registered));
-            } finally {
-                restoreCallingIdentity(token);
-            }
-        }
-
-        @Override
-        public void onConnectionStateChanged(BluetoothDevice device, int state) {
-            Attributable.setAttributionSource(device, mAttributionSource);
-            final long token = clearCallingIdentity();
-            try {
-                mExecutor.execute(() -> mCallback.onConnectionStateChanged(device, state));
-            } finally {
-                restoreCallingIdentity(token);
-            }
-        }
-
-        @Override
-        public void onGetReport(BluetoothDevice device, byte type, byte id, int bufferSize) {
-            Attributable.setAttributionSource(device, mAttributionSource);
-            final long token = clearCallingIdentity();
-            try {
-                mExecutor.execute(() -> mCallback.onGetReport(device, type, id, bufferSize));
-            } finally {
-                restoreCallingIdentity(token);
-            }
-        }
-
-        @Override
-        public void onSetReport(BluetoothDevice device, byte type, byte id, byte[] data) {
-            Attributable.setAttributionSource(device, mAttributionSource);
-            final long token = clearCallingIdentity();
-            try {
-                mExecutor.execute(() -> mCallback.onSetReport(device, type, id, data));
-            } finally {
-                restoreCallingIdentity(token);
-            }
-        }
-
-        @Override
-        public void onSetProtocol(BluetoothDevice device, byte protocol) {
-            Attributable.setAttributionSource(device, mAttributionSource);
-            final long token = clearCallingIdentity();
-            try {
-                mExecutor.execute(() -> mCallback.onSetProtocol(device, protocol));
-            } finally {
-                restoreCallingIdentity(token);
-            }
-        }
-
-        @Override
-        public void onInterruptData(BluetoothDevice device, byte reportId, byte[] data) {
-            Attributable.setAttributionSource(device, mAttributionSource);
-            final long token = clearCallingIdentity();
-            try {
-                mExecutor.execute(() -> mCallback.onInterruptData(device, reportId, data));
-            } finally {
-                restoreCallingIdentity(token);
-            }
-        }
-
-        @Override
-        public void onVirtualCableUnplug(BluetoothDevice device) {
-            Attributable.setAttributionSource(device, mAttributionSource);
-            final long token = clearCallingIdentity();
-            try {
-                mExecutor.execute(() -> mCallback.onVirtualCableUnplug(device));
-            } finally {
-                restoreCallingIdentity(token);
-            }
-        }
-    }
-
-    private final BluetoothAdapter mAdapter;
-    private final AttributionSource mAttributionSource;
-    private final BluetoothProfileConnector<IBluetoothHidDevice> mProfileConnector =
-            new BluetoothProfileConnector(this, BluetoothProfile.HID_DEVICE,
-                    "BluetoothHidDevice", IBluetoothHidDevice.class.getName()) {
-                @Override
-                public IBluetoothHidDevice getServiceInterface(IBinder service) {
-                    return IBluetoothHidDevice.Stub.asInterface(service);
-                }
-    };
-
-    BluetoothHidDevice(Context context, ServiceListener listener, BluetoothAdapter adapter) {
-        mAdapter = adapter;
-        mAttributionSource = adapter.getAttributionSource();
-        mProfileConnector.connect(context, listener);
-    }
-
-    void close() {
-        mProfileConnector.disconnect();
-    }
-
-    private IBluetoothHidDevice getService() {
-        return mProfileConnector.getService();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
-    public List<BluetoothDevice> getConnectedDevices() {
-        final IBluetoothHidDevice service = getService();
-        final List<BluetoothDevice> defaultValue = new ArrayList<>();
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<List<BluetoothDevice>> recv =
-                        new SynchronousResultReceiver();
-                service.getConnectedDevices(mAttributionSource, recv);
-                return Attributable.setAttributionSource(
-                        recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
-                        mAttributionSource);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
-    public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
-        final IBluetoothHidDevice service = getService();
-        final List<BluetoothDevice> defaultValue = new ArrayList<>();
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<List<BluetoothDevice>> recv =
-                        new SynchronousResultReceiver();
-                service.getDevicesMatchingConnectionStates(states, mAttributionSource, recv);
-                return Attributable.setAttributionSource(
-                        recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
-                        mAttributionSource);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
-    public int getConnectionState(BluetoothDevice device) {
-        final IBluetoothHidDevice service = getService();
-        final int defaultValue = STATE_DISCONNECTED;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
-                service.getConnectionState(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Registers application to be used for HID device. Connections to HID Device are only possible
-     * when application is registered. Only one application can be registered at one time. When an
-     * application is registered, the HID Host service will be disabled until it is unregistered.
-     * When no longer used, application should be unregistered using {@link #unregisterApp()}. The
-     * app will be automatically unregistered if it is not foreground. The registration status
-     * should be tracked by the application by handling callback from Callback#onAppStatusChanged.
-     * The app registration status is not related to the return value of this method.
-     *
-     * @param sdp {@link BluetoothHidDeviceAppSdpSettings} object of HID Device SDP record. The HID
-     *     Device SDP record is required.
-     * @param inQos {@link BluetoothHidDeviceAppQosSettings} object of Incoming QoS Settings. The
-     *     Incoming QoS Settings is not required. Use null or default
-     *     BluetoothHidDeviceAppQosSettings.Builder for default values.
-     * @param outQos {@link BluetoothHidDeviceAppQosSettings} object of Outgoing QoS Settings. The
-     *     Outgoing QoS Settings is not required. Use null or default
-     *     BluetoothHidDeviceAppQosSettings.Builder for default values.
-     * @param executor {@link Executor} object on which callback will be executed. The Executor
-     *     object is required.
-     * @param callback {@link Callback} object to which callback messages will be sent. The Callback
-     *     object is required.
-     * @return true if the command is successfully sent; otherwise false.
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean registerApp(
-            BluetoothHidDeviceAppSdpSettings sdp,
-            BluetoothHidDeviceAppQosSettings inQos,
-            BluetoothHidDeviceAppQosSettings outQos,
-            Executor executor,
-            Callback callback) {
-        boolean result = false;
-
-        if (sdp == null) {
-            throw new IllegalArgumentException("sdp parameter cannot be null");
-        }
-
-        if (executor == null) {
-            throw new IllegalArgumentException("executor parameter cannot be null");
-        }
-
-        if (callback == null) {
-            throw new IllegalArgumentException("callback parameter cannot be null");
-        }
-
-        final IBluetoothHidDevice service = getService();
-        final boolean defaultValue = result;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                CallbackWrapper cbw = new CallbackWrapper(executor, callback, mAttributionSource);
-                service.registerApp(sdp, inQos, outQos, cbw, mAttributionSource, recv);
-                result = recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Unregisters application. Active connection will be disconnected and no new connections will
-     * be allowed until registered again using {@link #registerApp
-     * (BluetoothHidDeviceAppQosSettings, BluetoothHidDeviceAppQosSettings,
-     * BluetoothHidDeviceAppQosSettings, Executor, Callback)}. The registration status should be
-     * tracked by the application by handling callback from Callback#onAppStatusChanged. The app
-     * registration status is not related to the return value of this method.
-     *
-     * @return true if the command is successfully sent; otherwise false.
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean unregisterApp() {
-        final IBluetoothHidDevice service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.unregisterApp(mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Sends report to remote host using interrupt channel.
-     *
-     * @param id Report Id, as defined in descriptor. Can be 0 in case Report Id are not defined in
-     *     descriptor.
-     * @param data Report data, not including Report Id.
-     * @return true if the command is successfully sent; otherwise false.
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean sendReport(BluetoothDevice device, int id, byte[] data) {
-        final IBluetoothHidDevice service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.sendReport(device, id, data, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Sends report to remote host as reply for GET_REPORT request from {@link
-     * Callback#onGetReport(BluetoothDevice, byte, byte, int)}.
-     *
-     * @param type Report Type, as in request.
-     * @param id Report Id, as in request.
-     * @param data Report data, not including Report Id.
-     * @return true if the command is successfully sent; otherwise false.
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean replyReport(BluetoothDevice device, byte type, byte id, byte[] data) {
-        final IBluetoothHidDevice service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.replyReport(device, type, id, data, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Sends error handshake message as reply for invalid SET_REPORT request from {@link
-     * Callback#onSetReport(BluetoothDevice, byte, byte, byte[])}.
-     *
-     * @param error Error to be sent for SET_REPORT via HANDSHAKE.
-     * @return true if the command is successfully sent; otherwise false.
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean reportError(BluetoothDevice device, byte error) {
-        final IBluetoothHidDevice service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.reportError(device, error, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Gets the application name of the current HidDeviceService user.
-     *
-     * @return the current user name, or empty string if cannot get the name
-     * {@hide}
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public String getUserAppName() {
-        final IBluetoothHidDevice service = getService();
-        final String defaultValue = "";
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<String> recv = new SynchronousResultReceiver();
-                service.getUserAppName(mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Initiates connection to host which is currently paired with this device. If the application
-     * is not registered, #connect(BluetoothDevice) will fail. The connection state should be
-     * tracked by the application by handling callback from Callback#onConnectionStateChanged. The
-     * connection state is not related to the return value of this method.
-     *
-     * @return true if the command is successfully sent; otherwise false.
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean connect(BluetoothDevice device) {
-        final IBluetoothHidDevice service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.connect(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Disconnects from currently connected host. The connection state should be tracked by the
-     * application by handling callback from Callback#onConnectionStateChanged. The connection state
-     * is not related to the return value of this method.
-     *
-     * @return true if the command is successfully sent; otherwise false.
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean disconnect(BluetoothDevice device) {
-        final IBluetoothHidDevice service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.disconnect(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Connects Hid Device if connectionPolicy is {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED}
-     * and disconnects Hid device if connectionPolicy is
-     * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}.
-     *
-     * <p> The device should already be paired.
-     * Connection policy can be one of:
-     * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED},
-     * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN},
-     * {@link BluetoothProfile#CONNECTION_POLICY_UNKNOWN}
-     *
-     * @param device Paired bluetooth device
-     * @param connectionPolicy determines whether hid device should be connected or disconnected
-     * @return true if hid device is connected or disconnected, false otherwise
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public boolean setConnectionPolicy(@NonNull BluetoothDevice device,
-            @ConnectionPolicy int connectionPolicy) {
-        if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
-        final IBluetoothHidDevice service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)
-                && (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_FORBIDDEN
-                    || connectionPolicy == BluetoothProfile.CONNECTION_POLICY_ALLOWED)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.setConnectionPolicy(device, connectionPolicy, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    private boolean isEnabled() {
-        if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true;
-        return false;
-    }
-
-    private boolean isValidDevice(BluetoothDevice device) {
-        if (device == null) return false;
-
-        if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
-        return false;
-    }
-
-    private static void log(String msg) {
-        if (DBG) {
-            Log.d(TAG, msg);
-        }
-    }
-}
diff --git a/core/java/android/bluetooth/BluetoothHidDeviceAppQosSettings.java b/core/java/android/bluetooth/BluetoothHidDeviceAppQosSettings.java
deleted file mode 100644
index b21ebe5..0000000
--- a/core/java/android/bluetooth/BluetoothHidDeviceAppQosSettings.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Represents the Quality of Service (QoS) settings for a Bluetooth HID Device application.
- *
- * <p>The BluetoothHidDevice framework will update the L2CAP QoS settings for the app during
- * registration.
- *
- * <p>{@see BluetoothHidDevice}
- */
-public final class BluetoothHidDeviceAppQosSettings implements Parcelable {
-
-    private final int mServiceType;
-    private final int mTokenRate;
-    private final int mTokenBucketSize;
-    private final int mPeakBandwidth;
-    private final int mLatency;
-    private final int mDelayVariation;
-
-    public static final int SERVICE_NO_TRAFFIC = 0x00;
-    public static final int SERVICE_BEST_EFFORT = 0x01;
-    public static final int SERVICE_GUARANTEED = 0x02;
-
-    public static final int MAX = (int) 0xffffffff;
-
-    /**
-     * Create a BluetoothHidDeviceAppQosSettings object for the Bluetooth L2CAP channel. The QoS
-     * Settings is optional. Please refer to Bluetooth HID Specfication v1.1.1 Section 5.2 and
-     * Appendix D for parameters.
-     *
-     * @param serviceType L2CAP service type, default = SERVICE_BEST_EFFORT
-     * @param tokenRate L2CAP token rate, default = 0
-     * @param tokenBucketSize L2CAP token bucket size, default = 0
-     * @param peakBandwidth L2CAP peak bandwidth, default = 0
-     * @param latency L2CAP latency, default = MAX
-     * @param delayVariation L2CAP delay variation, default = MAX
-     */
-    public BluetoothHidDeviceAppQosSettings(
-            int serviceType,
-            int tokenRate,
-            int tokenBucketSize,
-            int peakBandwidth,
-            int latency,
-            int delayVariation) {
-        mServiceType = serviceType;
-        mTokenRate = tokenRate;
-        mTokenBucketSize = tokenBucketSize;
-        mPeakBandwidth = peakBandwidth;
-        mLatency = latency;
-        mDelayVariation = delayVariation;
-    }
-
-    public int getServiceType() {
-        return mServiceType;
-    }
-
-    public int getTokenRate() {
-        return mTokenRate;
-    }
-
-    public int getTokenBucketSize() {
-        return mTokenBucketSize;
-    }
-
-    public int getPeakBandwidth() {
-        return mPeakBandwidth;
-    }
-
-    public int getLatency() {
-        return mLatency;
-    }
-
-    public int getDelayVariation() {
-        return mDelayVariation;
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    public static final @android.annotation.NonNull Parcelable.Creator<BluetoothHidDeviceAppQosSettings> CREATOR =
-            new Parcelable.Creator<BluetoothHidDeviceAppQosSettings>() {
-
-                @Override
-                public BluetoothHidDeviceAppQosSettings createFromParcel(Parcel in) {
-
-                    return new BluetoothHidDeviceAppQosSettings(
-                            in.readInt(),
-                            in.readInt(),
-                            in.readInt(),
-                            in.readInt(),
-                            in.readInt(),
-                            in.readInt());
-                }
-
-                @Override
-                public BluetoothHidDeviceAppQosSettings[] newArray(int size) {
-                    return new BluetoothHidDeviceAppQosSettings[size];
-                }
-            };
-
-    @Override
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeInt(mServiceType);
-        out.writeInt(mTokenRate);
-        out.writeInt(mTokenBucketSize);
-        out.writeInt(mPeakBandwidth);
-        out.writeInt(mLatency);
-        out.writeInt(mDelayVariation);
-    }
-}
diff --git a/core/java/android/bluetooth/BluetoothHidDeviceAppSdpSettings.java b/core/java/android/bluetooth/BluetoothHidDeviceAppSdpSettings.java
deleted file mode 100644
index 4e1a2aa..0000000
--- a/core/java/android/bluetooth/BluetoothHidDeviceAppSdpSettings.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.EventLog;
-
-
-/**
- * Represents the Service Discovery Protocol (SDP) settings for a Bluetooth HID Device application.
- *
- * <p>The BluetoothHidDevice framework adds the SDP record during app registration, so that the
- * Android device can be discovered as a Bluetooth HID Device.
- *
- * <p>{@see BluetoothHidDevice}
- */
-public final class BluetoothHidDeviceAppSdpSettings implements Parcelable {
-
-    private static final int MAX_DESCRIPTOR_SIZE = 2048;
-
-    private final String mName;
-    private final String mDescription;
-    private final String mProvider;
-    private final byte mSubclass;
-    private final byte[] mDescriptors;
-
-    /**
-     * Create a BluetoothHidDeviceAppSdpSettings object for the Bluetooth SDP record.
-     *
-     * @param name Name of this Bluetooth HID device. Maximum length is 50 bytes.
-     * @param description Description for this Bluetooth HID device. Maximum length is 50 bytes.
-     * @param provider Provider of this Bluetooth HID device. Maximum length is 50 bytes.
-     * @param subclass Subclass of this Bluetooth HID device. See <a
-     *     href="www.usb.org/developers/hidpage/HID1_11.pdf">
-     *     www.usb.org/developers/hidpage/HID1_11.pdf Section 4.2</a>
-     * @param descriptors Descriptors of this Bluetooth HID device. See <a
-     *     href="www.usb.org/developers/hidpage/HID1_11.pdf">
-     *     www.usb.org/developers/hidpage/HID1_11.pdf Chapter 6</a> Maximum length is 2048 bytes.
-     */
-    public BluetoothHidDeviceAppSdpSettings(
-            String name, String description, String provider, byte subclass, byte[] descriptors) {
-        mName = name;
-        mDescription = description;
-        mProvider = provider;
-        mSubclass = subclass;
-
-        if (descriptors == null || descriptors.length > MAX_DESCRIPTOR_SIZE) {
-            EventLog.writeEvent(0x534e4554, "119819889", -1, "");
-            throw new IllegalArgumentException("descriptors must be not null and shorter than "
-                    + MAX_DESCRIPTOR_SIZE);
-        }
-        mDescriptors = descriptors.clone();
-    }
-
-    public String getName() {
-        return mName;
-    }
-
-    public String getDescription() {
-        return mDescription;
-    }
-
-    public String getProvider() {
-        return mProvider;
-    }
-
-    public byte getSubclass() {
-        return mSubclass;
-    }
-
-    public byte[] getDescriptors() {
-        return mDescriptors;
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    public static final @android.annotation.NonNull Parcelable.Creator<BluetoothHidDeviceAppSdpSettings> CREATOR =
-            new Parcelable.Creator<BluetoothHidDeviceAppSdpSettings>() {
-
-                @Override
-                public BluetoothHidDeviceAppSdpSettings createFromParcel(Parcel in) {
-
-                    return new BluetoothHidDeviceAppSdpSettings(
-                            in.readString(),
-                            in.readString(),
-                            in.readString(),
-                            in.readByte(),
-                            in.createByteArray());
-                }
-
-                @Override
-                public BluetoothHidDeviceAppSdpSettings[] newArray(int size) {
-                    return new BluetoothHidDeviceAppSdpSettings[size];
-                }
-            };
-
-    @Override
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeString(mName);
-        out.writeString(mDescription);
-        out.writeString(mProvider);
-        out.writeByte(mSubclass);
-        out.writeByteArray(mDescriptors);
-    }
-}
diff --git a/core/java/android/bluetooth/BluetoothHidHost.java b/core/java/android/bluetooth/BluetoothHidHost.java
deleted file mode 100644
index ecbeddf..0000000
--- a/core/java/android/bluetooth/BluetoothHidHost.java
+++ /dev/null
@@ -1,831 +0,0 @@
-/*
- * Copyright (C) 2011 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.bluetooth;
-
-import static android.bluetooth.BluetoothUtils.getSyncTimeout;
-
-import android.Manifest;
-import android.annotation.NonNull;
-import android.annotation.RequiresPermission;
-import android.annotation.SdkConstant;
-import android.annotation.SdkConstant.SdkConstantType;
-import android.annotation.SuppressLint;
-import android.annotation.SystemApi;
-import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
-import android.bluetooth.annotations.RequiresLegacyBluetoothAdminPermission;
-import android.bluetooth.annotations.RequiresLegacyBluetoothPermission;
-import android.content.AttributionSource;
-import android.content.Context;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.util.Log;
-
-import com.android.modules.utils.SynchronousResultReceiver;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.TimeoutException;
-
-
-/**
- * This class provides the public APIs to control the Bluetooth Input
- * Device Profile.
- *
- * <p>BluetoothHidHost is a proxy object for controlling the Bluetooth
- * Service via IPC. Use {@link BluetoothAdapter#getProfileProxy} to get
- * the BluetoothHidHost proxy object.
- *
- * <p>Each method is protected with its appropriate permission.
- *
- * @hide
- */
-@SystemApi
-public final class BluetoothHidHost implements BluetoothProfile {
-    private static final String TAG = "BluetoothHidHost";
-    private static final boolean DBG = true;
-    private static final boolean VDBG = false;
-
-    /**
-     * Intent used to broadcast the change in connection state of the Input
-     * Device profile.
-     *
-     * <p>This intent will have 3 extras:
-     * <ul>
-     * <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
-     * <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li>
-     * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
-     * </ul>
-     *
-     * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
-     * {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTING},
-     * {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTING}.
-     */
-    @SuppressLint("ActionValue")
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_CONNECTION_STATE_CHANGED =
-            "android.bluetooth.input.profile.action.CONNECTION_STATE_CHANGED";
-
-    /**
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_PROTOCOL_MODE_CHANGED =
-            "android.bluetooth.input.profile.action.PROTOCOL_MODE_CHANGED";
-
-    /**
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_HANDSHAKE =
-            "android.bluetooth.input.profile.action.HANDSHAKE";
-
-    /**
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_REPORT =
-            "android.bluetooth.input.profile.action.REPORT";
-
-    /**
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_VIRTUAL_UNPLUG_STATUS =
-            "android.bluetooth.input.profile.action.VIRTUAL_UNPLUG_STATUS";
-
-    /**
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_IDLE_TIME_CHANGED =
-            "android.bluetooth.input.profile.action.IDLE_TIME_CHANGED";
-
-    /**
-     * Return codes for the connect and disconnect Bluez / Dbus calls.
-     *
-     * @hide
-     */
-    public static final int INPUT_DISCONNECT_FAILED_NOT_CONNECTED = 5000;
-
-    /**
-     * @hide
-     */
-    public static final int INPUT_CONNECT_FAILED_ALREADY_CONNECTED = 5001;
-
-    /**
-     * @hide
-     */
-    public static final int INPUT_CONNECT_FAILED_ATTEMPT_FAILED = 5002;
-
-    /**
-     * @hide
-     */
-    public static final int INPUT_OPERATION_GENERIC_FAILURE = 5003;
-
-    /**
-     * @hide
-     */
-    public static final int INPUT_OPERATION_SUCCESS = 5004;
-
-    /**
-     * @hide
-     */
-    public static final int PROTOCOL_REPORT_MODE = 0;
-
-    /**
-     * @hide
-     */
-    public static final int PROTOCOL_BOOT_MODE = 1;
-
-    /**
-     * @hide
-     */
-    public static final int PROTOCOL_UNSUPPORTED_MODE = 255;
-
-    /*  int reportType, int reportType, int bufferSize */
-    /**
-     * @hide
-     */
-    public static final byte REPORT_TYPE_INPUT = 1;
-
-    /**
-     * @hide
-     */
-    public static final byte REPORT_TYPE_OUTPUT = 2;
-
-    /**
-     * @hide
-     */
-    public static final byte REPORT_TYPE_FEATURE = 3;
-
-    /**
-     * @hide
-     */
-    public static final int VIRTUAL_UNPLUG_STATUS_SUCCESS = 0;
-
-    /**
-     * @hide
-     */
-    public static final int VIRTUAL_UNPLUG_STATUS_FAIL = 1;
-
-    /**
-     * @hide
-     */
-    public static final String EXTRA_PROTOCOL_MODE =
-            "android.bluetooth.BluetoothHidHost.extra.PROTOCOL_MODE";
-
-    /**
-     * @hide
-     */
-    public static final String EXTRA_REPORT_TYPE =
-            "android.bluetooth.BluetoothHidHost.extra.REPORT_TYPE";
-
-    /**
-     * @hide
-     */
-    public static final String EXTRA_REPORT_ID =
-            "android.bluetooth.BluetoothHidHost.extra.REPORT_ID";
-
-    /**
-     * @hide
-     */
-    public static final String EXTRA_REPORT_BUFFER_SIZE =
-            "android.bluetooth.BluetoothHidHost.extra.REPORT_BUFFER_SIZE";
-
-    /**
-     * @hide
-     */
-    public static final String EXTRA_REPORT = "android.bluetooth.BluetoothHidHost.extra.REPORT";
-
-    /**
-     * @hide
-     */
-    public static final String EXTRA_STATUS = "android.bluetooth.BluetoothHidHost.extra.STATUS";
-
-    /**
-     * @hide
-     */
-    public static final String EXTRA_VIRTUAL_UNPLUG_STATUS =
-            "android.bluetooth.BluetoothHidHost.extra.VIRTUAL_UNPLUG_STATUS";
-
-    /**
-     * @hide
-     */
-    public static final String EXTRA_IDLE_TIME =
-            "android.bluetooth.BluetoothHidHost.extra.IDLE_TIME";
-
-    private final BluetoothAdapter mAdapter;
-    private final AttributionSource mAttributionSource;
-    private final BluetoothProfileConnector<IBluetoothHidHost> mProfileConnector =
-            new BluetoothProfileConnector(this, BluetoothProfile.HID_HOST,
-                    "BluetoothHidHost", IBluetoothHidHost.class.getName()) {
-                @Override
-                public IBluetoothHidHost getServiceInterface(IBinder service) {
-                    return IBluetoothHidHost.Stub.asInterface(service);
-                }
-    };
-
-    /**
-     * Create a BluetoothHidHost proxy object for interacting with the local
-     * Bluetooth Service which handles the InputDevice profile
-     */
-    /* package */ BluetoothHidHost(Context context, ServiceListener listener,
-            BluetoothAdapter adapter) {
-        mAdapter = adapter;
-        mAttributionSource = adapter.getAttributionSource();
-        mProfileConnector.connect(context, listener);
-    }
-
-    /*package*/ void close() {
-        if (VDBG) log("close()");
-        mProfileConnector.disconnect();
-    }
-
-    private IBluetoothHidHost getService() {
-        return mProfileConnector.getService();
-    }
-
-    /**
-     * Initiate connection to a profile of the remote bluetooth device.
-     *
-     * <p> The system supports connection to multiple input devices.
-     *
-     * <p> This API returns false in scenarios like the profile on the
-     * device is already connected or Bluetooth is not turned on.
-     * When this API returns true, it is guaranteed that
-     * connection state intent for the profile will be broadcasted with
-     * the state. Users can get the connection state of the profile
-     * from this intent.
-     *
-     * @param device Remote Bluetooth Device
-     * @return false on immediate error, true otherwise
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public boolean connect(BluetoothDevice device) {
-        if (DBG) log("connect(" + device + ")");
-        final IBluetoothHidHost service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.connect(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Initiate disconnection from a profile
-     *
-     * <p> This API will return false in scenarios like the profile on the
-     * Bluetooth device is not in connected state etc. When this API returns,
-     * true, it is guaranteed that the connection state change
-     * intent will be broadcasted with the state. Users can get the
-     * disconnection state of the profile from this intent.
-     *
-     * <p> If the disconnection is initiated by a remote device, the state
-     * will transition from {@link #STATE_CONNECTED} to
-     * {@link #STATE_DISCONNECTED}. If the disconnect is initiated by the
-     * host (local) device the state will transition from
-     * {@link #STATE_CONNECTED} to state {@link #STATE_DISCONNECTING} to
-     * state {@link #STATE_DISCONNECTED}. The transition to
-     * {@link #STATE_DISCONNECTING} can be used to distinguish between the
-     * two scenarios.
-     *
-     * @param device Remote Bluetooth Device
-     * @return false on immediate error, true otherwise
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public boolean disconnect(BluetoothDevice device) {
-        if (DBG) log("disconnect(" + device + ")");
-        final IBluetoothHidHost service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.disconnect(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * {@inheritDoc}
-     *
-     * @hide
-     */
-    @SystemApi
-    @Override
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
-    public @NonNull List<BluetoothDevice> getConnectedDevices() {
-        if (VDBG) log("getConnectedDevices()");
-        final IBluetoothHidHost service = getService();
-        final List<BluetoothDevice> defaultValue = new ArrayList<BluetoothDevice>();
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<List<BluetoothDevice>> recv =
-                        new SynchronousResultReceiver();
-                service.getConnectedDevices(mAttributionSource, recv);
-                return Attributable.setAttributionSource(
-                        recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
-                        mAttributionSource);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * {@inheritDoc}
-     *
-     * @hide
-     */
-    @Override
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
-    public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
-        if (VDBG) log("getDevicesMatchingStates()");
-        final IBluetoothHidHost service = getService();
-        final List<BluetoothDevice> defaultValue = new ArrayList<BluetoothDevice>();
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<List<BluetoothDevice>> recv =
-                        new SynchronousResultReceiver();
-                service.getDevicesMatchingConnectionStates(states, mAttributionSource, recv);
-                return Attributable.setAttributionSource(
-                        recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
-                        mAttributionSource);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * {@inheritDoc}
-     *
-     * @hide
-     */
-    @SystemApi
-    @Override
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
-    public int getConnectionState(@NonNull BluetoothDevice device) {
-        if (VDBG) log("getState(" + device + ")");
-        if (device == null) {
-            throw new IllegalArgumentException("device must not be null");
-        }
-        final IBluetoothHidHost service = getService();
-        final int defaultValue = BluetoothProfile.STATE_DISCONNECTED;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
-                service.getConnectionState(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Set priority of the profile
-     *
-     * <p> The device should already be paired.
-     * Priority can be one of {@link #PRIORITY_ON} or {@link #PRIORITY_OFF},
-     *
-     * @param device Paired bluetooth device
-     * @param priority
-     * @return true if priority is set, false on error
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public boolean setPriority(BluetoothDevice device, int priority) {
-        if (DBG) log("setPriority(" + device + ", " + priority + ")");
-        return setConnectionPolicy(device, BluetoothAdapter.priorityToConnectionPolicy(priority));
-    }
-
-    /**
-     * Set connection policy of the profile
-     *
-     * <p> The device should already be paired.
-     * Connection policy can be one of {@link #CONNECTION_POLICY_ALLOWED},
-     * {@link #CONNECTION_POLICY_FORBIDDEN}, {@link #CONNECTION_POLICY_UNKNOWN}
-     *
-     * @param device Paired bluetooth device
-     * @param connectionPolicy is the connection policy to set to for this profile
-     * @return true if connectionPolicy is set, false on error
-     * @hide
-     */
-    @SystemApi
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public boolean setConnectionPolicy(@NonNull BluetoothDevice device,
-            @ConnectionPolicy int connectionPolicy) {
-        if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
-        if (device == null) {
-            throw new IllegalArgumentException("device must not be null");
-        }
-        final IBluetoothHidHost service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)
-                && (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_FORBIDDEN
-                    || connectionPolicy == BluetoothProfile.CONNECTION_POLICY_ALLOWED)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.setConnectionPolicy(device, connectionPolicy, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Get the priority of the profile.
-     *
-     * <p> The priority can be any of:
-     * {@link #PRIORITY_OFF}, {@link #PRIORITY_ON}, {@link #PRIORITY_UNDEFINED}
-     *
-     * @param device Bluetooth device
-     * @return priority of the device
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public int getPriority(BluetoothDevice device) {
-        if (VDBG) log("getPriority(" + device + ")");
-        return BluetoothAdapter.connectionPolicyToPriority(getConnectionPolicy(device));
-    }
-
-    /**
-     * Get the connection policy of the profile.
-     *
-     * <p> The connection policy can be any of:
-     * {@link #CONNECTION_POLICY_ALLOWED}, {@link #CONNECTION_POLICY_FORBIDDEN},
-     * {@link #CONNECTION_POLICY_UNKNOWN}
-     *
-     * @param device Bluetooth device
-     * @return connection policy of the device
-     * @hide
-     */
-    @SystemApi
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public @ConnectionPolicy int getConnectionPolicy(@NonNull BluetoothDevice device) {
-        if (VDBG) log("getConnectionPolicy(" + device + ")");
-        if (device == null) {
-            throw new IllegalArgumentException("device must not be null");
-        }
-        final IBluetoothHidHost service = getService();
-        final int defaultValue = BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
-                service.getConnectionPolicy(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    private boolean isEnabled() {
-        return mAdapter.getState() == BluetoothAdapter.STATE_ON;
-    }
-
-    private static boolean isValidDevice(BluetoothDevice device) {
-        return device != null && BluetoothAdapter.checkBluetoothAddress(device.getAddress());
-    }
-
-    /**
-     * Initiate virtual unplug for a HID input device.
-     *
-     * @param device Remote Bluetooth Device
-     * @return false on immediate error, true otherwise
-     * @hide
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean virtualUnplug(BluetoothDevice device) {
-        if (DBG) log("virtualUnplug(" + device + ")");
-        final IBluetoothHidHost service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.virtualUnplug(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Send Get_Protocol_Mode command to the connected HID input device.
-     *
-     * @param device Remote Bluetooth Device
-     * @return false on immediate error, true otherwise
-     * @hide
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean getProtocolMode(BluetoothDevice device) {
-        if (VDBG) log("getProtocolMode(" + device + ")");
-        final IBluetoothHidHost service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.getProtocolMode(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Send Set_Protocol_Mode command to the connected HID input device.
-     *
-     * @param device Remote Bluetooth Device
-     * @return false on immediate error, true otherwise
-     * @hide
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean setProtocolMode(BluetoothDevice device, int protocolMode) {
-        if (DBG) log("setProtocolMode(" + device + ")");
-        final IBluetoothHidHost service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.setProtocolMode(device, protocolMode, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Send Get_Report command to the connected HID input device.
-     *
-     * @param device Remote Bluetooth Device
-     * @param reportType Report type
-     * @param reportId Report ID
-     * @param bufferSize Report receiving buffer size
-     * @return false on immediate error, true otherwise
-     * @hide
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean getReport(BluetoothDevice device, byte reportType, byte reportId,
-            int bufferSize) {
-        if (VDBG) {
-            log("getReport(" + device + "), reportType=" + reportType + " reportId=" + reportId
-                    + "bufferSize=" + bufferSize);
-        }
-        final IBluetoothHidHost service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.getReport(device, reportType, reportId, bufferSize, mAttributionSource,
-                        recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Send Set_Report command to the connected HID input device.
-     *
-     * @param device Remote Bluetooth Device
-     * @param reportType Report type
-     * @param report Report receiving buffer size
-     * @return false on immediate error, true otherwise
-     * @hide
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean setReport(BluetoothDevice device, byte reportType, String report) {
-        if (VDBG) log("setReport(" + device + "), reportType=" + reportType + " report=" + report);
-        final IBluetoothHidHost service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.setReport(device, reportType, report, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Send Send_Data command to the connected HID input device.
-     *
-     * @param device Remote Bluetooth Device
-     * @param report Report to send
-     * @return false on immediate error, true otherwise
-     * @hide
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean sendData(BluetoothDevice device, String report) {
-        if (DBG) log("sendData(" + device + "), report=" + report);
-        final IBluetoothHidHost service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.sendData(device, report, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Send Get_Idle_Time command to the connected HID input device.
-     *
-     * @param device Remote Bluetooth Device
-     * @return false on immediate error, true otherwise
-     * @hide
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean getIdleTime(BluetoothDevice device) {
-        if (DBG) log("getIdletime(" + device + ")");
-        final IBluetoothHidHost service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.getIdleTime(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Send Set_Idle_Time command to the connected HID input device.
-     *
-     * @param device Remote Bluetooth Device
-     * @param idleTime Idle time to be set on HID Device
-     * @return false on immediate error, true otherwise
-     * @hide
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean setIdleTime(BluetoothDevice device, byte idleTime) {
-        if (DBG) log("setIdletime(" + device + "), idleTime=" + idleTime);
-        final IBluetoothHidHost service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.setIdleTime(device, idleTime, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    private static void log(String msg) {
-        Log.d(TAG, msg);
-    }
-}
diff --git a/core/java/android/bluetooth/BluetoothInputStream.java b/core/java/android/bluetooth/BluetoothInputStream.java
deleted file mode 100644
index 95f9229..0000000
--- a/core/java/android/bluetooth/BluetoothInputStream.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2009 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.bluetooth;
-
-import android.annotation.SuppressLint;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * BluetoothInputStream.
- *
- * Used to write to a Bluetooth socket.
- *
- * @hide
- */
-@SuppressLint("AndroidFrameworkBluetoothPermission")
-/*package*/ final class BluetoothInputStream extends InputStream {
-    private BluetoothSocket mSocket;
-
-    /*package*/ BluetoothInputStream(BluetoothSocket s) {
-        mSocket = s;
-    }
-
-    /**
-     * Return number of bytes available before this stream will block.
-     */
-    public int available() throws IOException {
-        return mSocket.available();
-    }
-
-    public void close() throws IOException {
-        mSocket.close();
-    }
-
-    /**
-     * Reads a single byte from this stream and returns it as an integer in the
-     * range from 0 to 255. Returns -1 if the end of the stream has been
-     * reached. Blocks until one byte has been read, the end of the source
-     * stream is detected or an exception is thrown.
-     *
-     * @return the byte read or -1 if the end of stream has been reached.
-     * @throws IOException if the stream is closed or another IOException occurs.
-     * @since Android 1.5
-     */
-    public int read() throws IOException {
-        byte[] b = new byte[1];
-        int ret = mSocket.read(b, 0, 1);
-        if (ret == 1) {
-            return (int) b[0] & 0xff;
-        } else {
-            return -1;
-        }
-    }
-
-    /**
-     * Reads at most {@code length} bytes from this stream and stores them in
-     * the byte array {@code b} starting at {@code offset}.
-     *
-     * @param b the byte array in which to store the bytes read.
-     * @param offset the initial position in {@code buffer} to store the bytes read from this
-     * stream.
-     * @param length the maximum number of bytes to store in {@code b}.
-     * @return the number of bytes actually read or -1 if the end of the stream has been reached.
-     * @throws IndexOutOfBoundsException if {@code offset < 0} or {@code length < 0}, or if {@code
-     * offset + length} is greater than the length of {@code b}.
-     * @throws IOException if the stream is closed or another IOException occurs.
-     * @since Android 1.5
-     */
-    public int read(byte[] b, int offset, int length) throws IOException {
-        if (b == null) {
-            throw new NullPointerException("byte array is null");
-        }
-        if ((offset | length) < 0 || length > b.length - offset) {
-            throw new ArrayIndexOutOfBoundsException("invalid offset or length");
-        }
-        return mSocket.read(b, offset, length);
-    }
-}
diff --git a/core/java/android/bluetooth/BluetoothLeAudio.java b/core/java/android/bluetooth/BluetoothLeAudio.java
deleted file mode 100644
index 15db686..0000000
--- a/core/java/android/bluetooth/BluetoothLeAudio.java
+++ /dev/null
@@ -1,829 +0,0 @@
-/*
- * Copyright 2020 HIMSA II K/S - www.himsa.com.
- * Represented by EHIMA - www.ehima.com
- *
- * 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.bluetooth;
-
-import static android.bluetooth.BluetoothUtils.getSyncTimeout;
-
-import android.Manifest;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.RequiresPermission;
-import android.annotation.SdkConstant;
-import android.annotation.SdkConstant.SdkConstantType;
-import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
-import android.bluetooth.annotations.RequiresLegacyBluetoothPermission;
-import android.content.AttributionSource;
-import android.content.Context;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.util.CloseGuard;
-import android.util.Log;
-
-import com.android.modules.utils.SynchronousResultReceiver;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.TimeoutException;
-
-/**
- * This class provides the public APIs to control the LeAudio profile.
- *
- * <p>BluetoothLeAudio is a proxy object for controlling the Bluetooth LE Audio
- * Service via IPC. Use {@link BluetoothAdapter#getProfileProxy} to get
- * the BluetoothLeAudio proxy object.
- *
- * <p> Android only supports one set of connected Bluetooth LeAudio device at a time. Each
- * method is protected with its appropriate permission.
- */
-public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
-    private static final String TAG = "BluetoothLeAudio";
-    private static final boolean DBG = false;
-    private static final boolean VDBG = false;
-
-    private CloseGuard mCloseGuard;
-
-    /**
-     * Intent used to broadcast the change in connection state of the LeAudio
-     * profile. Please note that in the binaural case, there will be two different LE devices for
-     * the left and right side and each device will have their own connection state changes.
-     *
-     * <p>This intent will have 3 extras:
-     * <ul>
-     * <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
-     * <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li>
-     * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
-     * </ul>
-     *
-     * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
-     * {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTING},
-     * {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTING}.
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_LE_AUDIO_CONNECTION_STATE_CHANGED =
-            "android.bluetooth.action.LE_AUDIO_CONNECTION_STATE_CHANGED";
-
-    /**
-     * Intent used to broadcast the selection of a connected device as active.
-     *
-     * <p>This intent will have one extra:
-     * <ul>
-     * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. It can
-     * be null if no device is active. </li>
-     * </ul>
-     *
-     * @hide
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_LE_AUDIO_ACTIVE_DEVICE_CHANGED =
-            "android.bluetooth.action.LE_AUDIO_ACTIVE_DEVICE_CHANGED";
-
-    /**
-     * Intent used to broadcast group node status information.
-     *
-     * <p>This intent will have 3 extra:
-     * <ul>
-     * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. It can
-     * be null if no device is active. </li>
-     * <li> {@link #EXTRA_LE_AUDIO_GROUP_ID} - Group id. </li>
-     * <li> {@link #EXTRA_LE_AUDIO_GROUP_NODE_STATUS} - Group node status. </li>
-     * </ul>
-     *
-     * @hide
-     */
-    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_LE_AUDIO_GROUP_NODE_STATUS_CHANGED =
-            "android.bluetooth.action.LE_AUDIO_GROUP_NODE_STATUS_CHANGED";
-
-
-    /**
-     * Intent used to broadcast group status information.
-     *
-     * <p>This intent will have 4 extra:
-     * <ul>
-     * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. It can
-     * be null if no device is active. </li>
-     * <li> {@link #EXTRA_LE_AUDIO_GROUP_ID} - Group id. </li>
-     * <li> {@link #EXTRA_LE_AUDIO_GROUP_STATUS} - Group status. </li>
-     * </ul>
-     *
-     * @hide
-     */
-    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_LE_AUDIO_GROUP_STATUS_CHANGED =
-            "android.bluetooth.action.LE_AUDIO_GROUP_STATUS_CHANGED";
-
-    /**
-     * Intent used to broadcast group audio configuration changed information.
-     *
-     * <p>This intent will have 5 extra:
-     * <ul>
-     * <li> {@link #EXTRA_LE_AUDIO_GROUP_ID} - Group id. </li>
-     * <li> {@link #EXTRA_LE_AUDIO_DIRECTION} - Direction as bit mask. </li>
-     * <li> {@link #EXTRA_LE_AUDIO_SINK_LOCATION} - Sink location as per Bluetooth Assigned
-     * Numbers </li>
-     * <li> {@link #EXTRA_LE_AUDIO_SOURCE_LOCATION} - Source location as per Bluetooth Assigned
-     * Numbers </li>
-     * <li> {@link #EXTRA_LE_AUDIO_AVAILABLE_CONTEXTS} - Available contexts for group as per
-     * Bluetooth Assigned Numbers </li>
-     * </ul>
-     *
-     * @hide
-     */
-    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_LE_AUDIO_CONF_CHANGED =
-            "android.bluetooth.action.LE_AUDIO_CONF_CHANGED";
-
-    /**
-     * Indicates unspecified audio content.
-     * @hide
-     */
-    public static final int CONTEXT_TYPE_UNSPECIFIED = 0x0001;
-
-    /**
-     * Indicates conversation between humans as, for example, in telephony or video calls.
-     * @hide
-     */
-    public static final int CONTEXT_TYPE_COMMUNICATION = 0x0002;
-
-    /**
-     * Indicates media as, for example, in music, public radio, podcast or video soundtrack.
-     * @hide
-     */
-    public static final int CONTEXT_TYPE_MEDIA = 0x0004;
-
-    /**
-     * Indicates instructional audio as, for example, in navigation, traffic announcements
-     * or user guidance.
-     * @hide
-     */
-    public static final int CONTEXT_TYPE_INSTRUCTIONAL = 0x0008;
-
-    /**
-     * Indicates attention seeking audio as, for example, in beeps signalling arrival of a message
-     * or keyboard clicks.
-     * @hide
-     */
-    public static final int CONTEXT_TYPE_ATTENTION_SEEKING = 0x0010;
-
-    /**
-     * Indicates immediate alerts as, for example, in a low battery alarm, timer expiry or alarm
-     * clock.
-     * @hide
-     */
-    public static final int CONTEXT_TYPE_IMMEDIATE_ALERT = 0x0020;
-
-    /**
-     * Indicates man machine communication as, for example, with voice recognition or virtual
-     * assistant.
-     * @hide
-     */
-    public static final int CONTEXT_TYPE_MAN_MACHINE = 0x0040;
-
-    /**
-     * Indicates emergency alerts as, for example, with fire alarms or other urgent alerts.
-     * @hide
-     */
-    public static final int CONTEXT_TYPE_EMERGENCY_ALERT = 0x0080;
-
-    /**
-     * Indicates ringtone as in a call alert.
-     * @hide
-     */
-    public static final int CONTEXT_TYPE_RINGTONE = 0x0100;
-
-    /**
-     * Indicates audio associated with a television program and/or with metadata conforming to the
-     * Bluetooth Broadcast TV profile.
-     * @hide
-     */
-    public static final int CONTEXT_TYPE_TV = 0x0200;
-
-    /**
-     * Indicates audio associated with a low latency live audio stream.
-     *
-     * @hide
-     */
-    public static final int CONTEXT_TYPE_LIVE = 0x0400;
-
-    /**
-     * Indicates audio associated with a video game stream.
-     * @hide
-     */
-    public static final int CONTEXT_TYPE_GAME = 0x0800;
-
-    /**
-     * This represents an invalid group ID.
-     *
-     * @hide
-     */
-    public static final int GROUP_ID_INVALID = IBluetoothLeAudio.LE_AUDIO_GROUP_ID_INVALID;
-
-    /**
-     * Contains group id.
-     * @hide
-     */
-    public static final String EXTRA_LE_AUDIO_GROUP_ID =
-            "android.bluetooth.extra.LE_AUDIO_GROUP_ID";
-
-    /**
-     * Contains group node status, can be any of
-     * <p>
-     * <ul>
-     * <li> {@link #GROUP_NODE_ADDED} </li>
-     * <li> {@link #GROUP_NODE_REMOVED} </li>
-     * </ul>
-     * <p>
-     * @hide
-     */
-    public static final String EXTRA_LE_AUDIO_GROUP_NODE_STATUS =
-            "android.bluetooth.extra.LE_AUDIO_GROUP_NODE_STATUS";
-
-    /**
-     * Contains group status, can be any of
-     *
-     * <p>
-     * <ul>
-     * <li> {@link #GROUP_STATUS_ACTIVE} </li>
-     * <li> {@link #GROUP_STATUS_INACTIVE} </li>
-     * </ul>
-     * <p>
-     * @hide
-     */
-    public static final String EXTRA_LE_AUDIO_GROUP_STATUS =
-            "android.bluetooth.extra.LE_AUDIO_GROUP_STATUS";
-
-    /**
-     * Contains bit mask for direction, bit 0 set when Sink, bit 1 set when Source.
-     * @hide
-     */
-    public static final String EXTRA_LE_AUDIO_DIRECTION =
-            "android.bluetooth.extra.LE_AUDIO_DIRECTION";
-
-    /**
-     * Contains source location as per Bluetooth Assigned Numbers
-     * @hide
-     */
-    public static final String EXTRA_LE_AUDIO_SOURCE_LOCATION =
-            "android.bluetooth.extra.LE_AUDIO_SOURCE_LOCATION";
-
-    /**
-     * Contains sink location as per Bluetooth Assigned Numbers
-     * @hide
-     */
-    public static final String EXTRA_LE_AUDIO_SINK_LOCATION =
-            "android.bluetooth.extra.LE_AUDIO_SINK_LOCATION";
-
-    /**
-     * Contains available context types for group as per Bluetooth Assigned Numbers
-     * @hide
-     */
-    public static final String EXTRA_LE_AUDIO_AVAILABLE_CONTEXTS =
-            "android.bluetooth.extra.LE_AUDIO_AVAILABLE_CONTEXTS";
-
-    private final BluetoothAdapter mAdapter;
-    private final AttributionSource mAttributionSource;
-    /**
-     * Indicating that group is Active ( Audio device is available )
-     * @hide
-     */
-    public static final int GROUP_STATUS_ACTIVE = IBluetoothLeAudio.GROUP_STATUS_ACTIVE;
-
-    /**
-     * Indicating that group is Inactive ( Audio device is not available )
-     * @hide
-     */
-    public static final int GROUP_STATUS_INACTIVE = IBluetoothLeAudio.GROUP_STATUS_INACTIVE;
-
-    /**
-     * Indicating that node has been added to the group.
-     * @hide
-     */
-    public static final int GROUP_NODE_ADDED = IBluetoothLeAudio.GROUP_NODE_ADDED;
-
-    /**
-     * Indicating that node has been removed from the group.
-     * @hide
-     */
-    public static final int GROUP_NODE_REMOVED = IBluetoothLeAudio.GROUP_NODE_REMOVED;
-
-    private final BluetoothProfileConnector<IBluetoothLeAudio> mProfileConnector =
-            new BluetoothProfileConnector(this, BluetoothProfile.LE_AUDIO, "BluetoothLeAudio",
-                    IBluetoothLeAudio.class.getName()) {
-                @Override
-                public IBluetoothLeAudio getServiceInterface(IBinder service) {
-                    return IBluetoothLeAudio.Stub.asInterface(service);
-                }
-    };
-
-    /**
-     * Create a BluetoothLeAudio proxy object for interacting with the local
-     * Bluetooth LeAudio service.
-     */
-    /* package */ BluetoothLeAudio(Context context, ServiceListener listener,
-            BluetoothAdapter adapter) {
-        mAdapter = adapter;
-        mAttributionSource = adapter.getAttributionSource();
-        mProfileConnector.connect(context, listener);
-        mCloseGuard = new CloseGuard();
-        mCloseGuard.open("close");
-    }
-
-    /**
-     * @hide
-     */
-    public void close() {
-        mProfileConnector.disconnect();
-    }
-
-    private IBluetoothLeAudio getService() {
-        return mProfileConnector.getService();
-    }
-
-    protected void finalize() {
-        if (mCloseGuard != null) {
-            mCloseGuard.warnIfOpen();
-        }
-        close();
-    }
-
-    /**
-     * Initiate connection to a profile of the remote bluetooth device.
-     *
-     * <p> This API returns false in scenarios like the profile on the
-     * device is already connected or Bluetooth is not turned on.
-     * When this API returns true, it is guaranteed that
-     * connection state intent for the profile will be broadcasted with
-     * the state. Users can get the connection state of the profile
-     * from this intent.
-     *
-     *
-     * @param device Remote Bluetooth Device
-     * @return false on immediate error, true otherwise
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean connect(@Nullable BluetoothDevice device) {
-        if (DBG) log("connect(" + device + ")");
-        final IBluetoothLeAudio service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (mAdapter.isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.connect(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Initiate disconnection from a profile
-     *
-     * <p> This API will return false in scenarios like the profile on the
-     * Bluetooth device is not in connected state etc. When this API returns,
-     * true, it is guaranteed that the connection state change
-     * intent will be broadcasted with the state. Users can get the
-     * disconnection state of the profile from this intent.
-     *
-     * <p> If the disconnection is initiated by a remote device, the state
-     * will transition from {@link #STATE_CONNECTED} to
-     * {@link #STATE_DISCONNECTED}. If the disconnect is initiated by the
-     * host (local) device the state will transition from
-     * {@link #STATE_CONNECTED} to state {@link #STATE_DISCONNECTING} to
-     * state {@link #STATE_DISCONNECTED}. The transition to
-     * {@link #STATE_DISCONNECTING} can be used to distinguish between the
-     * two scenarios.
-     *
-     *
-     * @param device Remote Bluetooth Device
-     * @return false on immediate error, true otherwise
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean disconnect(@Nullable BluetoothDevice device) {
-        if (DBG) log("disconnect(" + device + ")");
-        final IBluetoothLeAudio service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (mAdapter.isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.disconnect(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public @NonNull List<BluetoothDevice> getConnectedDevices() {
-        if (VDBG) log("getConnectedDevices()");
-        final IBluetoothLeAudio service = getService();
-        final List<BluetoothDevice> defaultValue = new ArrayList<BluetoothDevice>();
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (mAdapter.isEnabled()) {
-            try {
-                final SynchronousResultReceiver<List<BluetoothDevice>> recv =
-                        new SynchronousResultReceiver();
-                service.getConnectedDevices(mAttributionSource, recv);
-                return Attributable.setAttributionSource(
-                        recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
-                        mAttributionSource);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public @NonNull List<BluetoothDevice> getDevicesMatchingConnectionStates(
-            @NonNull int[] states) {
-        if (VDBG) log("getDevicesMatchingStates()");
-        final IBluetoothLeAudio service = getService();
-        final List<BluetoothDevice> defaultValue = new ArrayList<BluetoothDevice>();
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (mAdapter.isEnabled()) {
-            try {
-                final SynchronousResultReceiver<List<BluetoothDevice>> recv =
-                        new SynchronousResultReceiver();
-                service.getDevicesMatchingConnectionStates(states, mAttributionSource, recv);
-                return Attributable.setAttributionSource(
-                        recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
-                        mAttributionSource);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public @BtProfileState int getConnectionState(@NonNull BluetoothDevice device) {
-        if (VDBG) log("getState(" + device + ")");
-        final IBluetoothLeAudio service = getService();
-        final int defaultValue = BluetoothProfile.STATE_DISCONNECTED;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (mAdapter.isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
-                service.getConnectionState(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Select a connected device as active.
-     *
-     * The active device selection is per profile. An active device's
-     * purpose is profile-specific. For example, LeAudio audio
-     * streaming is to the active LeAudio device. If a remote device
-     * is not connected, it cannot be selected as active.
-     *
-     * <p> This API returns false in scenarios like the profile on the
-     * device is not connected or Bluetooth is not turned on.
-     * When this API returns true, it is guaranteed that the
-     * {@link #ACTION_LE_AUDIO_ACTIVE_DEVICE_CHANGED} intent will be broadcasted
-     * with the active device.
-     *
-     *
-     * @param device the remote Bluetooth device. Could be null to clear
-     * the active device and stop streaming audio to a Bluetooth device.
-     * @return false on immediate error, true otherwise
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean setActiveDevice(@Nullable BluetoothDevice device) {
-        if (DBG) log("setActiveDevice(" + device + ")");
-        final IBluetoothLeAudio service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (mAdapter.isEnabled() && ((device == null) || isValidDevice(device))) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.setActiveDevice(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Get the connected LeAudio devices that are active
-     *
-     * @return the list of active devices. Returns empty list on error.
-     * @hide
-     */
-    @NonNull
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public List<BluetoothDevice> getActiveDevices() {
-        if (VDBG) log("getActiveDevice()");
-        final IBluetoothLeAudio service = getService();
-        final List<BluetoothDevice> defaultValue = new ArrayList<BluetoothDevice>();
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (mAdapter.isEnabled()) {
-            try {
-                final SynchronousResultReceiver<List<BluetoothDevice>> recv =
-                        new SynchronousResultReceiver();
-                service.getActiveDevices(mAttributionSource, recv);
-                return Attributable.setAttributionSource(
-                        recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
-                        mAttributionSource);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Get device group id. Devices with same group id belong to same group (i.e left and right
-     * earbud)
-     * @param device LE Audio capable device
-     * @return group id that this device currently belongs to
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public int getGroupId(@NonNull BluetoothDevice device) {
-        if (VDBG) log("getGroupId()");
-        final IBluetoothLeAudio service = getService();
-        final int defaultValue = GROUP_ID_INVALID;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (mAdapter.isEnabled()) {
-            try {
-                final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
-                service.getGroupId(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Set volume for the streaming devices
-     *
-     * @param volume volume to set
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED})
-    public void setVolume(int volume) {
-        if (VDBG) log("setVolume(vol: " + volume + " )");
-        final IBluetoothLeAudio service = getService();
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (mAdapter.isEnabled()) {
-            try {
-                final SynchronousResultReceiver recv = new SynchronousResultReceiver();
-                service.setVolume(volume, mAttributionSource, recv);
-                recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(null);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-    }
-
-    /**
-     * Add device to the given group.
-     * @param group_id group ID the device is being added to
-     * @param device the active device
-     * @return true on success, otherwise false
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED
-    })
-    public boolean groupAddNode(int group_id, @NonNull BluetoothDevice device) {
-        if (VDBG) log("groupAddNode()");
-        final IBluetoothLeAudio service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (mAdapter.isEnabled()) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.groupAddNode(group_id, device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Remove device from a given group.
-     * @param group_id group ID the device is being removed from
-     * @param device the active device
-     * @return true on success, otherwise false
-     *
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED
-    })
-    public boolean groupRemoveNode(int group_id, @NonNull BluetoothDevice device) {
-        if (VDBG) log("groupRemoveNode()");
-        final IBluetoothLeAudio service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (mAdapter.isEnabled()) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.groupRemoveNode(group_id, device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Set connection policy of the profile
-     *
-     * <p> The device should already be paired.
-     * Connection policy can be one of {@link #CONNECTION_POLICY_ALLOWED},
-     * {@link #CONNECTION_POLICY_FORBIDDEN}, {@link #CONNECTION_POLICY_UNKNOWN}
-     *
-     * @param device Paired bluetooth device
-     * @param connectionPolicy is the connection policy to set to for this profile
-     * @return true if connectionPolicy is set, false on error
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public boolean setConnectionPolicy(@NonNull BluetoothDevice device,
-            @ConnectionPolicy int connectionPolicy) {
-        if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
-        final IBluetoothLeAudio service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (mAdapter.isEnabled() && isValidDevice(device)
-                    && (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_FORBIDDEN
-                        || connectionPolicy == BluetoothProfile.CONNECTION_POLICY_ALLOWED)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.setConnectionPolicy(device, connectionPolicy, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Get the connection policy of the profile.
-     *
-     * <p> The connection policy can be any of:
-     * {@link #CONNECTION_POLICY_ALLOWED}, {@link #CONNECTION_POLICY_FORBIDDEN},
-     * {@link #CONNECTION_POLICY_UNKNOWN}
-     *
-     * @param device Bluetooth device
-     * @return connection policy of the device
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public @ConnectionPolicy int getConnectionPolicy(@Nullable BluetoothDevice device) {
-        if (VDBG) log("getConnectionPolicy(" + device + ")");
-        final IBluetoothLeAudio service = getService();
-        final int defaultValue = BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (mAdapter.isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
-                service.getConnectionPolicy(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-
-    /**
-     * Helper for converting a state to a string.
-     *
-     * For debug use only - strings are not internationalized.
-     *
-     * @hide
-     */
-    public static String stateToString(int state) {
-        switch (state) {
-            case STATE_DISCONNECTED:
-                return "disconnected";
-            case STATE_CONNECTING:
-                return "connecting";
-            case STATE_CONNECTED:
-                return "connected";
-            case STATE_DISCONNECTING:
-                return "disconnecting";
-            default:
-                return "<unknown state " + state + ">";
-        }
-    }
-
-    private boolean isValidDevice(@Nullable BluetoothDevice device) {
-        if (device == null) return false;
-
-        if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
-        return false;
-    }
-
-    private static void log(String msg) {
-        Log.d(TAG, msg);
-    }
-}
diff --git a/core/java/android/bluetooth/BluetoothLeAudioCodecConfig.java b/core/java/android/bluetooth/BluetoothLeAudioCodecConfig.java
deleted file mode 100644
index dcaf4b6..0000000
--- a/core/java/android/bluetooth/BluetoothLeAudioCodecConfig.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Represents the codec configuration for a Bluetooth LE Audio source device.
- * <p>Contains the source codec type.
- * <p>The source codec type values are the same as those supported by the
- * device hardware.
- *
- * {@see BluetoothLeAudioCodecConfig}
- */
-public final class BluetoothLeAudioCodecConfig {
-    // Add an entry for each source codec here.
-
-    /** @hide */
-    @IntDef(prefix = "SOURCE_CODEC_TYPE_", value = {
-            SOURCE_CODEC_TYPE_LC3,
-            SOURCE_CODEC_TYPE_INVALID
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface SourceCodecType {};
-
-    public static final int SOURCE_CODEC_TYPE_LC3 = 0;
-    public static final int SOURCE_CODEC_TYPE_INVALID = 1000 * 1000;
-
-    /**
-     * Represents the count of valid source codec types. Can be accessed via
-     * {@link #getMaxCodecType}.
-     */
-    private static final int SOURCE_CODEC_TYPE_MAX = 1;
-
-    private final @SourceCodecType int mCodecType;
-
-    /**
-     * Creates a new BluetoothLeAudioCodecConfig.
-     *
-     * @param codecType the source codec type
-     */
-    private BluetoothLeAudioCodecConfig(@SourceCodecType int codecType) {
-        mCodecType = codecType;
-    }
-
-    @Override
-    public String toString() {
-        return "{codecName:" + getCodecName() + "}";
-    }
-
-    /**
-     * Gets the codec type.
-     *
-     * @return the codec type
-     */
-    public @SourceCodecType int getCodecType() {
-        return mCodecType;
-    }
-
-    /**
-     * Returns the valid codec types count.
-     */
-    public static int getMaxCodecType() {
-        return SOURCE_CODEC_TYPE_MAX;
-    }
-
-    /**
-     * Gets the codec name.
-     *
-     * @return the codec name
-     */
-    public @NonNull String getCodecName() {
-        switch (mCodecType) {
-            case SOURCE_CODEC_TYPE_LC3:
-                return "LC3";
-            case SOURCE_CODEC_TYPE_INVALID:
-                return "INVALID CODEC";
-            default:
-                break;
-        }
-        return "UNKNOWN CODEC(" + mCodecType + ")";
-    }
-
-    /**
-     * Builder for {@link BluetoothLeAudioCodecConfig}.
-     * <p> By default, the codec type will be set to
-     * {@link BluetoothLeAudioCodecConfig#SOURCE_CODEC_TYPE_INVALID}
-     */
-    public static final class Builder {
-        private int mCodecType = BluetoothLeAudioCodecConfig.SOURCE_CODEC_TYPE_INVALID;
-
-        /**
-         * Set codec type for Bluetooth codec config.
-         *
-         * @param codecType of this codec
-         * @return the same Builder instance
-         */
-        public @NonNull Builder setCodecType(@SourceCodecType int codecType) {
-            mCodecType = codecType;
-            return this;
-        }
-
-        /**
-         * Build {@link BluetoothLeAudioCodecConfig}.
-         * @return new BluetoothLeAudioCodecConfig built
-         */
-        public @NonNull BluetoothLeAudioCodecConfig build() {
-            return new BluetoothLeAudioCodecConfig(mCodecType);
-        }
-    }
-}
diff --git a/core/java/android/bluetooth/BluetoothLeBroadcast.java b/core/java/android/bluetooth/BluetoothLeBroadcast.java
deleted file mode 100644
index fed9f91..0000000
--- a/core/java/android/bluetooth/BluetoothLeBroadcast.java
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-import android.annotation.IntDef;
-import android.content.Context;
-import android.util.Log;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.List;
-
-/**
- * This class provides the public APIs to control the Bluetooth LE Broadcast Source profile.
- *
- * <p>BluetoothLeBroadcast is a proxy object for controlling the Bluetooth LE Broadcast
- * Source Service via IPC. Use {@link BluetoothAdapter#getProfileProxy}
- * to get the BluetoothLeBroadcast proxy object.
- *
- * @hide
- */
-public final class BluetoothLeBroadcast implements BluetoothProfile {
-    private static final String TAG = "BluetoothLeBroadcast";
-    private static final boolean DBG = true;
-    private static final boolean VDBG = false;
-
-    /**
-     * Constants used by the LE Audio Broadcast profile for the Broadcast state
-     *
-     * @hide
-     */
-    @IntDef(prefix = {"LE_AUDIO_BROADCAST_STATE_"}, value = {
-      LE_AUDIO_BROADCAST_STATE_DISABLED,
-      LE_AUDIO_BROADCAST_STATE_ENABLING,
-      LE_AUDIO_BROADCAST_STATE_ENABLED,
-      LE_AUDIO_BROADCAST_STATE_DISABLING,
-      LE_AUDIO_BROADCAST_STATE_PLAYING,
-      LE_AUDIO_BROADCAST_STATE_NOT_PLAYING
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface LeAudioBroadcastState {}
-
-    /**
-     * Indicates that LE Audio Broadcast mode is currently disabled
-     *
-     * @hide
-     */
-    public static final int LE_AUDIO_BROADCAST_STATE_DISABLED = 10;
-
-    /**
-     * Indicates that LE Audio Broadcast mode is being enabled
-     *
-     * @hide
-     */
-    public static final int LE_AUDIO_BROADCAST_STATE_ENABLING = 11;
-
-    /**
-     * Indicates that LE Audio Broadcast mode is currently enabled
-     *
-     * @hide
-     */
-    public static final int LE_AUDIO_BROADCAST_STATE_ENABLED = 12;
-    /**
-     * Indicates that LE Audio Broadcast mode is being disabled
-     *
-     * @hide
-     */
-    public static final int LE_AUDIO_BROADCAST_STATE_DISABLING = 13;
-
-    /**
-     * Indicates that an LE Audio Broadcast mode is currently playing
-     *
-     * @hide
-     */
-    public static final int LE_AUDIO_BROADCAST_STATE_PLAYING = 14;
-
-    /**
-     * Indicates that LE Audio Broadcast is currently not playing
-     *
-     * @hide
-     */
-    public static final int LE_AUDIO_BROADCAST_STATE_NOT_PLAYING = 15;
-
-    /**
-     * Constants used by the LE Audio Broadcast profile for encryption key length
-     *
-     * @hide
-     */
-    @IntDef(prefix = {"LE_AUDIO_BROADCAST_ENCRYPTION_KEY_"}, value = {
-      LE_AUDIO_BROADCAST_ENCRYPTION_KEY_32BIT,
-      LE_AUDIO_BROADCAST_ENCRYPTION_KEY_128BIT
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface LeAudioEncryptionKeyLength {}
-
-    /**
-     * Indicates that the LE Audio Broadcast encryption key size is 32 bits.
-     *
-     * @hide
-     */
-    public static final int LE_AUDIO_BROADCAST_ENCRYPTION_KEY_32BIT = 16;
-
-    /**
-     * Indicates that the LE Audio Broadcast encryption key size is 128 bits.
-     *
-     * @hide
-     */
-    public static final int LE_AUDIO_BROADCAST_ENCRYPTION_KEY_128BIT = 17;
-
-    /**
-     * Interface for receiving events related to broadcasts
-     */
-    public interface Callback {
-        /**
-         * Called when broadcast state has changed
-         *
-         * @param prevState broadcast state before the change
-         * @param newState broadcast state after the change
-         */
-        @LeAudioBroadcastState
-        void onBroadcastStateChange(int prevState, int newState);
-        /**
-         * Called when encryption key has been updated
-         *
-         * @param success true if the key was updated successfully, false otherwise
-         */
-        void onEncryptionKeySet(boolean success);
-    }
-
-    /**
-     * Create a BluetoothLeBroadcast proxy object for interacting with the local
-     * LE Audio Broadcast Source service.
-     *
-     * @hide
-     */
-    /*package*/ BluetoothLeBroadcast(Context context,
-                                     BluetoothProfile.ServiceListener listener) {
-    }
-
-    /**
-     * Not supported since LE Audio Broadcasts do not establish a connection
-     *
-     * @throws UnsupportedOperationException
-     *
-     * @hide
-     */
-    @Override
-    public int getConnectionState(BluetoothDevice device) {
-        throw new UnsupportedOperationException(
-                   "LE Audio Broadcasts are not connection-oriented.");
-    }
-
-    /**
-     * Not supported since LE Audio Broadcasts do not establish a connection
-     *
-     * @throws UnsupportedOperationException
-     *
-     * @hide
-     */
-    @Override
-    public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
-        throw new UnsupportedOperationException(
-                   "LE Audio Broadcasts are not connection-oriented.");
-    }
-
-    /**
-     * Not supported since LE Audio Broadcasts do not establish a connection
-     *
-     * @throws UnsupportedOperationException
-     *
-     * @hide
-     */
-    @Override
-    public List<BluetoothDevice> getConnectedDevices() {
-        throw new UnsupportedOperationException(
-                   "LE Audio Broadcasts are not connection-oriented.");
-    }
-
-    /**
-     * Enable LE Audio Broadcast mode.
-     *
-     * Generates a new broadcast ID and enables sending of encrypted or unencrypted
-     * isochronous PDUs
-     *
-     * @hide
-     */
-    public int enableBroadcastMode() {
-        if (DBG) log("enableBroadcastMode");
-        return BluetoothStatusCodes.ERROR_LE_AUDIO_BROADCAST_SOURCE_SET_BROADCAST_MODE_FAILED;
-    }
-
-    /**
-     * Disable LE Audio Broadcast mode.
-     *
-     * @hide
-     */
-    public int disableBroadcastMode() {
-        if (DBG) log("disableBroadcastMode");
-        return BluetoothStatusCodes.ERROR_LE_AUDIO_BROADCAST_SOURCE_SET_BROADCAST_MODE_FAILED;
-    }
-
-    /**
-     * Get the current LE Audio broadcast state
-     *
-     * @hide
-     */
-    @LeAudioBroadcastState
-    public int getBroadcastState() {
-        if (DBG) log("getBroadcastState");
-        return LE_AUDIO_BROADCAST_STATE_DISABLED;
-    }
-
-    /**
-     * Enable LE Audio broadcast encryption
-     *
-     * @param keyLength if useExisting is true, this specifies the length of the key that should
-     *                  be generated
-     * @param useExisting true, if an existing key should be used
-     *                    false, if a new key should be generated
-     *
-     * @hide
-     */
-    @LeAudioEncryptionKeyLength
-    public int enableEncryption(boolean useExisting, int keyLength) {
-        if (DBG) log("enableEncryption useExisting=" + useExisting + " keyLength=" + keyLength);
-        return BluetoothStatusCodes.ERROR_LE_AUDIO_BROADCAST_SOURCE_ENABLE_ENCRYPTION_FAILED;
-    }
-
-    /**
-     * Disable LE Audio broadcast encryption
-     *
-     * @param removeExisting true, if the existing key should be removed
-     *                       false, otherwise
-     *
-     * @hide
-     */
-    public int disableEncryption(boolean removeExisting) {
-        if (DBG) log("disableEncryption removeExisting=" + removeExisting);
-        return BluetoothStatusCodes.ERROR_LE_AUDIO_BROADCAST_SOURCE_DISABLE_ENCRYPTION_FAILED;
-    }
-
-    /**
-     * Enable or disable LE Audio broadcast encryption
-     *
-     * @param key use the provided key if non-null, generate a new key if null
-     * @param keyLength 0 if encryption is disabled, 4 bytes (low security),
-     *                  16 bytes (high security)
-     *
-     * @hide
-     */
-    @LeAudioEncryptionKeyLength
-    public int setEncryptionKey(byte[] key, int keyLength) {
-        if (DBG) log("setEncryptionKey key=" + key + " keyLength=" + keyLength);
-        return BluetoothStatusCodes.ERROR_LE_AUDIO_BROADCAST_SOURCE_SET_ENCRYPTION_KEY_FAILED;
-    }
-
-
-    /**
-     * Get the encryption key that was set before
-     *
-     * @return encryption key as a byte array or null if no encryption key was set
-     *
-     * @hide
-     */
-    public byte[] getEncryptionKey() {
-        if (DBG) log("getEncryptionKey");
-        return null;
-    }
-
-    private static void log(String msg) {
-        Log.d(TAG, msg);
-    }
-}
diff --git a/core/java/android/bluetooth/BluetoothLeBroadcastAssistantCallback.java b/core/java/android/bluetooth/BluetoothLeBroadcastAssistantCallback.java
deleted file mode 100644
index b866cce..0000000
--- a/core/java/android/bluetooth/BluetoothLeBroadcastAssistantCallback.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.bluetooth.le.ScanResult;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * This class provides a set of callbacks that are invoked when scanning for Broadcast Sources is
- * offloaded to a Broadcast Assistant.
- *
- * <p>An LE Audio Broadcast Assistant can help a Broadcast Sink to scan for available Broadcast
- * Sources. The Broadcast Sink achieves this by offloading the scan to a Broadcast Assistant. This
- * is facilitated by the Broadcast Audio Scan Service (BASS). A BASS server is a GATT server that is
- * part of the Scan Delegator on a Broadcast Sink. A BASS client instead runs on the Broadcast
- * Assistant.
- *
- * <p>Once a GATT connection is established between the BASS client and the BASS server, the
- * Broadcast Sink can offload the scans to the Broadcast Assistant. Upon finding new Broadcast
- * Sources, the Broadcast Assistant then notifies the Broadcast Sink about these over the
- * established GATT connection. The Scan Delegator on the Broadcast Sink can also notify the
- * Assistant about changes such as addition and removal of Broadcast Sources.
- *
- * @hide
- */
-public abstract class BluetoothLeBroadcastAssistantCallback {
-
-    /**
-     * Broadcast Audio Scan Service (BASS) codes returned by a BASS Server
-     *
-     * @hide
-     */
-    @IntDef(
-            prefix = "BASS_STATUS_",
-            value = {
-                BASS_STATUS_SUCCESS,
-                BASS_STATUS_FAILURE,
-                BASS_STATUS_INVALID_GATT_HANDLE,
-                BASS_STATUS_TXN_TIMEOUT,
-                BASS_STATUS_INVALID_SOURCE_ID,
-                BASS_STATUS_COLOCATED_SRC_UNAVAILABLE,
-                BASS_STATUS_INVALID_SOURCE_SELECTED,
-                BASS_STATUS_SOURCE_UNAVAILABLE,
-                BASS_STATUS_DUPLICATE_ADDITION,
-            })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface BassStatus {}
-
-    public static final int BASS_STATUS_SUCCESS = 0x00;
-    public static final int BASS_STATUS_FAILURE = 0x01;
-    public static final int BASS_STATUS_INVALID_GATT_HANDLE = 0x02;
-    public static final int BASS_STATUS_TXN_TIMEOUT = 0x03;
-
-    public static final int BASS_STATUS_INVALID_SOURCE_ID = 0x04;
-    public static final int BASS_STATUS_COLOCATED_SRC_UNAVAILABLE = 0x05;
-    public static final int BASS_STATUS_INVALID_SOURCE_SELECTED = 0x06;
-    public static final int BASS_STATUS_SOURCE_UNAVAILABLE = 0x07;
-    public static final int BASS_STATUS_DUPLICATE_ADDITION = 0x08;
-    public static final int BASS_STATUS_NO_EMPTY_SLOT = 0x09;
-    public static final int BASS_STATUS_INVALID_GROUP_OP = 0x10;
-
-    /**
-     * Callback invoked when a new LE Audio Broadcast Source is found.
-     *
-     * @param result {@link ScanResult} scan result representing a Broadcast Source
-     */
-    public void onBluetoothLeBroadcastSourceFound(@NonNull ScanResult result) {}
-
-    /**
-     * Callback invoked when the Broadcast Assistant synchronizes with Periodic Advertisements (PAs)
-     * of an LE Audio Broadcast Source.
-     *
-     * @param source the selected Broadcast Source
-     */
-    public void onBluetoothLeBroadcastSourceSelected(
-            @NonNull BluetoothLeBroadcastSourceInfo source, @BassStatus int status) {}
-
-    /**
-     * Callback invoked when the Broadcast Assistant loses synchronization with an LE Audio
-     * Broadcast Source.
-     *
-     * @param source the Broadcast Source with which synchronization was lost
-     */
-    public void onBluetoothLeBroadcastSourceLost(
-            @NonNull BluetoothLeBroadcastSourceInfo source, @BassStatus int status) {}
-
-    /**
-     * Callback invoked when a new LE Audio Broadcast Source has been successfully added to the Scan
-     * Delegator (within a Broadcast Sink, for example).
-     *
-     * @param sink Scan Delegator device on which a new Broadcast Source has been added
-     * @param source the added Broadcast Source
-     */
-    public void onBluetoothLeBroadcastSourceAdded(
-            @NonNull BluetoothDevice sink,
-            @NonNull BluetoothLeBroadcastSourceInfo source,
-            @BassStatus int status) {}
-
-    /**
-     * Callback invoked when an existing LE Audio Broadcast Source within a remote Scan Delegator
-     * has been updated.
-     *
-     * @param sink Scan Delegator device on which a Broadcast Source has been updated
-     * @param source the updated Broadcast Source
-     */
-    public void onBluetoothLeBroadcastSourceUpdated(
-            @NonNull BluetoothDevice sink,
-            @NonNull BluetoothLeBroadcastSourceInfo source,
-            @BassStatus int status) {}
-
-    /**
-     * Callback invoked when an LE Audio Broadcast Source has been successfully removed from the
-     * Scan Delegator (within a Broadcast Sink, for example).
-     *
-     * @param sink Scan Delegator device from which a Broadcast Source has been removed
-     * @param source the removed Broadcast Source
-     */
-    public void onBluetoothLeBroadcastSourceRemoved(
-            @NonNull BluetoothDevice sink,
-            @NonNull BluetoothLeBroadcastSourceInfo source,
-            @BassStatus int status) {}
-}
diff --git a/core/java/android/bluetooth/BluetoothLeBroadcastSourceInfo.java b/core/java/android/bluetooth/BluetoothLeBroadcastSourceInfo.java
deleted file mode 100644
index cb47280..0000000
--- a/core/java/android/bluetooth/BluetoothLeBroadcastSourceInfo.java
+++ /dev/null
@@ -1,788 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.Log;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Objects;
-
-/**
- * This class represents an LE Audio Broadcast Source and the associated information that is needed
- * by Broadcast Audio Scan Service (BASS) residing on a Scan Delegator.
- *
- * <p>For example, the Scan Delegator on an LE Audio Broadcast Sink can use the information
- * contained within an instance of this class to synchronize with an LE Audio Broadcast Source in
- * order to listen to a Broadcast Audio Stream.
- *
- * <p>BroadcastAssistant has a BASS client which facilitates scanning and discovery of Broadcast
- * Sources on behalf of say a Broadcast Sink. Upon successful discovery of one or more Broadcast
- * sources, this information needs to be communicated to the BASS Server residing within the Scan
- * Delegator on a Broadcast Sink. This is achieved using the Periodic Advertising Synchronization
- * Transfer (PAST) procedure. This procedure uses information contained within an instance of this
- * class.
- *
- * @hide
- */
-public final class BluetoothLeBroadcastSourceInfo implements Parcelable {
-    private static final String TAG = "BluetoothLeBroadcastSourceInfo";
-    private static final boolean DBG = true;
-
-    /**
-     * Constants representing Broadcast Source address types
-     *
-     * @hide
-     */
-    @IntDef(
-            prefix = "LE_AUDIO_BROADCAST_SOURCE_ADDRESS_TYPE_",
-            value = {
-                LE_AUDIO_BROADCAST_SOURCE_ADDRESS_TYPE_PUBLIC,
-                LE_AUDIO_BROADCAST_SOURCE_ADDRESS_TYPE_RANDOM,
-                LE_AUDIO_BROADCAST_SOURCE_ADDRESS_TYPE_INVALID
-            })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface LeAudioBroadcastSourceAddressType {}
-
-    /**
-     * Represents a public address used by an LE Audio Broadcast Source
-     *
-     * @hide
-     */
-    public static final int LE_AUDIO_BROADCAST_SOURCE_ADDRESS_TYPE_PUBLIC = 0;
-
-    /**
-     * Represents a random address used by an LE Audio Broadcast Source
-     *
-     * @hide
-     */
-    public static final int LE_AUDIO_BROADCAST_SOURCE_ADDRESS_TYPE_RANDOM = 1;
-
-    /**
-     * Represents an invalid address used by an LE Audio Broadcast Seurce
-     *
-     * @hide
-     */
-    public static final int LE_AUDIO_BROADCAST_SOURCE_ADDRESS_TYPE_INVALID = 0xFFFF;
-
-    /**
-     * Periodic Advertising Synchronization state
-     *
-     * <p>Periodic Advertising (PA) enables the LE Audio Broadcast Assistant to discover broadcast
-     * audio streams as well as the audio stream configuration on behalf of an LE Audio Broadcast
-     * Sink. This information can then be transferred to the LE Audio Broadcast Sink using the
-     * Periodic Advertising Synchronizaton Transfer (PAST) procedure.
-     *
-     * @hide
-     */
-    @IntDef(
-            prefix = "LE_AUDIO_BROADCAST_SINK_PA_SYNC_STATE_",
-            value = {
-                LE_AUDIO_BROADCAST_SINK_PA_SYNC_STATE_IDLE,
-                LE_AUDIO_BROADCAST_SINK_PA_SYNC_STATE_SYNCINFO_REQ,
-                LE_AUDIO_BROADCAST_SINK_PA_SYNC_STATE_IN_SYNC,
-                LE_AUDIO_BROADCAST_SINK_PA_SYNC_STATE_SYNC_FAIL,
-                LE_AUDIO_BROADCAST_SINK_PA_SYNC_STATE_NO_PAST
-            })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface LeAudioBroadcastSinkPaSyncState {}
-
-    /**
-     * Indicates that the Broadcast Sink is not synchronized with the Periodic Advertisements (PA)
-     *
-     * @hide
-     */
-    public static final int LE_AUDIO_BROADCAST_SINK_PA_SYNC_STATE_IDLE = 0;
-
-    /**
-     * Indicates that the Broadcast Sink requested the Broadcast Assistant to synchronize with the
-     * Periodic Advertisements (PA).
-     *
-     * <p>This is also known as scan delegation or scan offloading.
-     *
-     * @hide
-     */
-    public static final int LE_AUDIO_BROADCAST_SINK_PA_SYNC_STATE_SYNCINFO_REQ = 1;
-
-    /**
-     * Indicates that the Broadcast Sink is synchronized with the Periodic Advertisements (PA).
-     *
-     * @hide
-     */
-    public static final int LE_AUDIO_BROADCAST_SINK_PA_SYNC_STATE_IN_SYNC = 2;
-
-    /**
-     * Indicates that the Broadcast Sink was unable to synchronize with the Periodic Advertisements
-     * (PA).
-     *
-     * @hide
-     */
-    public static final int LE_AUDIO_BROADCAST_SINK_PA_SYNC_STATE_SYNC_FAIL = 3;
-
-    /**
-     * Indicates that the Broadcast Sink should be synchronized with the Periodic Advertisements
-     * (PA) using the Periodic Advertisements Synchronization Transfert (PAST) procedure.
-     *
-     * @hide
-     */
-    public static final int LE_AUDIO_BROADCAST_SINK_PA_SYNC_STATE_NO_PAST = 4;
-
-    /**
-     * Indicates that the Broadcast Sink synchornization state is invalid.
-     *
-     * @hide
-     */
-    public static final int LE_AUDIO_BROADCAST_SINK_PA_SYNC_STATE_INVALID = 0xFFFF;
-
-    /** @hide */
-    @IntDef(
-            prefix = "LE_AUDIO_BROADCAST_SINK_AUDIO_SYNC_STATE_",
-            value = {
-                LE_AUDIO_BROADCAST_SINK_AUDIO_SYNC_STATE_NOT_SYNCHRONIZED,
-                LE_AUDIO_BROADCAST_SINK_AUDIO_SYNC_STATE_SYNCHRONIZED
-            })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface LeAudioBroadcastSinkAudioSyncState {}
-
-    /**
-     * Indicates that the Broadcast Sink is not synchronized with a Broadcast Audio Stream.
-     *
-     * @hide
-     */
-    public static final int LE_AUDIO_BROADCAST_SINK_AUDIO_SYNC_STATE_NOT_SYNCHRONIZED = 0;
-
-    /**
-     * Indicates that the Broadcast Sink is synchronized with a Broadcast Audio Stream.
-     *
-     * @hide
-     */
-    public static final int LE_AUDIO_BROADCAST_SINK_AUDIO_SYNC_STATE_SYNCHRONIZED = 1;
-
-    /**
-     * Indicates that the Broadcast Sink audio synchronization state is invalid.
-     *
-     * @hide
-     */
-    public static final int LE_AUDIO_BROADCAST_SINK_AUDIO_SYNC_STATE_INVALID = 0xFFFF;
-
-    /** @hide */
-    @IntDef(
-            prefix = "LE_AUDIO_BROADCAST_SINK_ENC_STATE_",
-            value = {
-                LE_AUDIO_BROADCAST_SINK_ENC_STATE_NOT_ENCRYPTED,
-                LE_AUDIO_BROADCAST_SINK_ENC_STATE_CODE_REQUIRED,
-                LE_AUDIO_BROADCAST_SINK_ENC_STATE_DECRYPTING,
-                LE_AUDIO_BROADCAST_SINK_ENC_STATE_BAD_CODE
-            })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface LeAudioBroadcastSinkEncryptionState {}
-
-    /**
-     * Indicates that the Broadcast Sink is synchronized with an unencrypted audio stream.
-     *
-     * @hide
-     */
-    public static final int LE_AUDIO_BROADCAST_SINK_ENC_STATE_NOT_ENCRYPTED = 0;
-
-    /**
-     * Indicates that the Broadcast Sink needs a Broadcast Code to synchronize with the audio
-     * stream.
-     *
-     * @hide
-     */
-    public static final int LE_AUDIO_BROADCAST_SINK_ENC_STATE_CODE_REQUIRED = 1;
-
-    /**
-     * Indicates that the Broadcast Sink is synchronized with an encrypted audio stream.
-     *
-     * @hide
-     */
-    public static final int LE_AUDIO_BROADCAST_SINK_ENC_STATE_DECRYPTING = 2;
-
-    /**
-     * Indicates that the Broadcast Sink is unable to decrypt an audio stream due to an incorrect
-     * Broadcast Code
-     *
-     * @hide
-     */
-    public static final int LE_AUDIO_BROADCAST_SINK_ENC_STATE_BAD_CODE = 3;
-
-    /**
-     * Indicates that the Broadcast Sink encryption state is invalid.
-     *
-     * @hide
-     */
-    public static final int LE_AUDIO_BROADCAST_SINK_ENC_STATE_INVALID = 0xFF;
-
-    /**
-     * Represents an invalid LE Audio Broadcast Source ID
-     *
-     * @hide
-     */
-    public static final byte LE_AUDIO_BROADCAST_SINK_INVALID_SOURCE_ID = (byte) 0x00;
-
-    /**
-     * Represents an invalid Broadcast ID of a Broadcast Source
-     *
-     * @hide
-     */
-    public static final int INVALID_BROADCAST_ID = 0xFFFFFF;
-
-    private byte mSourceId;
-    private @LeAudioBroadcastSourceAddressType int mSourceAddressType;
-    private BluetoothDevice mSourceDevice;
-    private byte mSourceAdvSid;
-    private int mBroadcastId;
-    private @LeAudioBroadcastSinkPaSyncState int mPaSyncState;
-    private @LeAudioBroadcastSinkEncryptionState int mEncryptionStatus;
-    private @LeAudioBroadcastSinkAudioSyncState int mAudioSyncState;
-    private byte[] mBadBroadcastCode;
-    private byte mNumSubGroups;
-    private Map<Integer, Integer> mSubgroupBisSyncState = new HashMap<Integer, Integer>();
-    private Map<Integer, byte[]> mSubgroupMetadata = new HashMap<Integer, byte[]>();
-
-    private String mBroadcastCode;
-    private static final int BIS_NO_PREF = 0xFFFFFFFF;
-    private static final int BROADCAST_CODE_SIZE = 16;
-
-    /**
-     * Constructor to create an Empty object of {@link BluetoothLeBroadcastSourceInfo } with the
-     * given Source Id.
-     *
-     * <p>This is mainly used to represent the Empty Broadcast Source entries
-     *
-     * @param sourceId Source Id for this Broadcast Source info object
-     * @hide
-     */
-    public BluetoothLeBroadcastSourceInfo(byte sourceId) {
-        mSourceId = sourceId;
-        mSourceAddressType = LE_AUDIO_BROADCAST_SOURCE_ADDRESS_TYPE_INVALID;
-        mSourceDevice = null;
-        mSourceAdvSid = (byte) 0x00;
-        mBroadcastId = INVALID_BROADCAST_ID;
-        mPaSyncState = LE_AUDIO_BROADCAST_SINK_PA_SYNC_STATE_INVALID;
-        mAudioSyncState = LE_AUDIO_BROADCAST_SINK_AUDIO_SYNC_STATE_INVALID;
-        mEncryptionStatus = LE_AUDIO_BROADCAST_SINK_ENC_STATE_INVALID;
-        mBadBroadcastCode = null;
-        mNumSubGroups = 0;
-        mBroadcastCode = null;
-    }
-
-    /*package*/ BluetoothLeBroadcastSourceInfo(
-            byte sourceId,
-            @LeAudioBroadcastSourceAddressType int addressType,
-            @NonNull BluetoothDevice device,
-            byte advSid,
-            int broadcastId,
-            @LeAudioBroadcastSinkPaSyncState int paSyncstate,
-            @LeAudioBroadcastSinkEncryptionState int encryptionStatus,
-            @LeAudioBroadcastSinkAudioSyncState int audioSyncstate,
-            @Nullable byte[] badCode,
-            byte numSubGroups,
-            @NonNull Map<Integer, Integer> bisSyncState,
-            @Nullable Map<Integer, byte[]> subgroupMetadata,
-            @NonNull String broadcastCode) {
-        mSourceId = sourceId;
-        mSourceAddressType = addressType;
-        mSourceDevice = device;
-        mSourceAdvSid = advSid;
-        mBroadcastId = broadcastId;
-        mPaSyncState = paSyncstate;
-        mEncryptionStatus = encryptionStatus;
-        mAudioSyncState = audioSyncstate;
-
-        if (badCode != null && badCode.length != 0) {
-            mBadBroadcastCode = new byte[badCode.length];
-            System.arraycopy(badCode, 0, mBadBroadcastCode, 0, badCode.length);
-        }
-        mNumSubGroups = numSubGroups;
-        mSubgroupBisSyncState = new HashMap<Integer, Integer>(bisSyncState);
-        mSubgroupMetadata = new HashMap<Integer, byte[]>(subgroupMetadata);
-        mBroadcastCode = broadcastCode;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (o instanceof BluetoothLeBroadcastSourceInfo) {
-            BluetoothLeBroadcastSourceInfo other = (BluetoothLeBroadcastSourceInfo) o;
-            return (other.mSourceId == mSourceId
-                    && other.mSourceAddressType == mSourceAddressType
-                    && other.mSourceDevice == mSourceDevice
-                    && other.mSourceAdvSid == mSourceAdvSid
-                    && other.mBroadcastId == mBroadcastId
-                    && other.mPaSyncState == mPaSyncState
-                    && other.mEncryptionStatus == mEncryptionStatus
-                    && other.mAudioSyncState == mAudioSyncState
-                    && Arrays.equals(other.mBadBroadcastCode, mBadBroadcastCode)
-                    && other.mNumSubGroups == mNumSubGroups
-                    && mSubgroupBisSyncState.equals(other.mSubgroupBisSyncState)
-                    && mSubgroupMetadata.equals(other.mSubgroupMetadata)
-                    && other.mBroadcastCode == mBroadcastCode);
-        }
-        return false;
-    }
-
-    /**
-     * Checks if an instance of {@link BluetoothLeBroadcastSourceInfo} is empty.
-     *
-     * @hide
-     */
-    public boolean isEmpty() {
-        boolean ret = false;
-        if (mSourceAddressType == LE_AUDIO_BROADCAST_SOURCE_ADDRESS_TYPE_INVALID
-                && mSourceDevice == null
-                && mSourceAdvSid == (byte) 0
-                && mPaSyncState == LE_AUDIO_BROADCAST_SINK_PA_SYNC_STATE_INVALID
-                && mEncryptionStatus == LE_AUDIO_BROADCAST_SINK_ENC_STATE_INVALID
-                && mAudioSyncState == LE_AUDIO_BROADCAST_SINK_AUDIO_SYNC_STATE_INVALID
-                && mBadBroadcastCode == null
-                && mNumSubGroups == 0
-                && mSubgroupBisSyncState.size() == 0
-                && mSubgroupMetadata.size() == 0
-                && mBroadcastCode == null) {
-            ret = true;
-        }
-        return ret;
-    }
-
-    /**
-     * Compares an instance of {@link BluetoothLeBroadcastSourceInfo} with the provided instance.
-     *
-     * @hide
-     */
-    public boolean matches(BluetoothLeBroadcastSourceInfo srcInfo) {
-        boolean ret = false;
-        if (srcInfo == null) {
-            ret = false;
-        } else {
-            if (mSourceDevice == null) {
-                if (mSourceAdvSid == srcInfo.getAdvertisingSid()
-                        && mSourceAddressType == srcInfo.getAdvAddressType()) {
-                    ret = true;
-                }
-            } else {
-                if (mSourceDevice.equals(srcInfo.getSourceDevice())
-                        && mSourceAdvSid == srcInfo.getAdvertisingSid()
-                        && mSourceAddressType == srcInfo.getAdvAddressType()
-                        && mBroadcastId == srcInfo.getBroadcastId()) {
-                    ret = true;
-                }
-            }
-        }
-        return ret;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(
-                mSourceId,
-                mSourceAddressType,
-                mSourceDevice,
-                mSourceAdvSid,
-                mBroadcastId,
-                mPaSyncState,
-                mEncryptionStatus,
-                mAudioSyncState,
-                mBadBroadcastCode,
-                mNumSubGroups,
-                mSubgroupBisSyncState,
-                mSubgroupMetadata,
-                mBroadcastCode);
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public String toString() {
-        return "{BluetoothLeBroadcastSourceInfo : mSourceId"
-                + mSourceId
-                + " addressType: "
-                + mSourceAddressType
-                + " sourceDevice: "
-                + mSourceDevice
-                + " mSourceAdvSid:"
-                + mSourceAdvSid
-                + " mBroadcastId:"
-                + mBroadcastId
-                + " mPaSyncState:"
-                + mPaSyncState
-                + " mEncryptionStatus:"
-                + mEncryptionStatus
-                + " mAudioSyncState:"
-                + mAudioSyncState
-                + " mBadBroadcastCode:"
-                + mBadBroadcastCode
-                + " mNumSubGroups:"
-                + mNumSubGroups
-                + " mSubgroupBisSyncState:"
-                + mSubgroupBisSyncState
-                + " mSubgroupMetadata:"
-                + mSubgroupMetadata
-                + " mBroadcastCode:"
-                + mBroadcastCode
-                + "}";
-    }
-
-    /**
-     * Get the Source Id
-     *
-     * @return byte representing the Source Id, {@link
-     *     #LE_AUDIO_BROADCAST_ASSISTANT_INVALID_SOURCE_ID} if invalid
-     * @hide
-     */
-    public byte getSourceId() {
-        return mSourceId;
-    }
-
-    /**
-     * Set the Source Id
-     *
-     * @param sourceId source Id
-     * @hide
-     */
-    public void setSourceId(byte sourceId) {
-        mSourceId = sourceId;
-    }
-
-    /**
-     * Set the Broadcast Source device
-     *
-     * @param sourceDevice the Broadcast Source BluetoothDevice
-     * @hide
-     */
-    public void setSourceDevice(@NonNull BluetoothDevice sourceDevice) {
-        mSourceDevice = sourceDevice;
-    }
-
-    /**
-     * Get the Broadcast Source BluetoothDevice
-     *
-     * @return Broadcast Source BluetoothDevice
-     * @hide
-     */
-    public @NonNull BluetoothDevice getSourceDevice() {
-        return mSourceDevice;
-    }
-
-    /**
-     * Set the address type of the Broadcast Source advertisements
-     *
-     * @hide
-     */
-    public void setAdvAddressType(@LeAudioBroadcastSourceAddressType int addressType) {
-        mSourceAddressType = addressType;
-    }
-
-    /**
-     * Get the address type used by advertisements from the Broadcast Source.
-     * BluetoothLeBroadcastSourceInfo Object
-     *
-     * @hide
-     */
-    @LeAudioBroadcastSourceAddressType
-    public int getAdvAddressType() {
-        return mSourceAddressType;
-    }
-
-    /**
-     * Set the advertising SID of the Broadcast Source advertisement.
-     *
-     * @param advSid advertising SID of the Broadcast Source
-     * @hide
-     */
-    public void setAdvertisingSid(byte advSid) {
-        mSourceAdvSid = advSid;
-    }
-
-    /**
-     * Get the advertising SID of the Broadcast Source advertisement.
-     *
-     * @return advertising SID of the Broadcast Source
-     * @hide
-     */
-    public byte getAdvertisingSid() {
-        return mSourceAdvSid;
-    }
-
-    /**
-     * Get the Broadcast ID of the Broadcast Source.
-     *
-     * @return broadcast ID
-     * @hide
-     */
-    public int getBroadcastId() {
-        return mBroadcastId;
-    }
-
-    /**
-     * Set the Periodic Advertising (PA) Sync State.
-     *
-     * @hide
-     */
-    /*package*/ void setPaSyncState(@LeAudioBroadcastSinkPaSyncState int paSyncState) {
-        mPaSyncState = paSyncState;
-    }
-
-    /**
-     * Get the Periodic Advertising (PA) Sync State
-     *
-     * @hide
-     */
-    public @LeAudioBroadcastSinkPaSyncState int getMetadataSyncState() {
-        return mPaSyncState;
-    }
-
-    /**
-     * Set the audio sync state
-     *
-     * @hide
-     */
-    /*package*/ void setAudioSyncState(@LeAudioBroadcastSinkAudioSyncState int audioSyncState) {
-        mAudioSyncState = audioSyncState;
-    }
-
-    /**
-     * Get the audio sync state
-     *
-     * @hide
-     */
-    public @LeAudioBroadcastSinkAudioSyncState int getAudioSyncState() {
-        return mAudioSyncState;
-    }
-
-    /**
-     * Set the encryption status
-     *
-     * @hide
-     */
-    /*package*/ void setEncryptionStatus(
-            @LeAudioBroadcastSinkEncryptionState int encryptionStatus) {
-        mEncryptionStatus = encryptionStatus;
-    }
-
-    /**
-     * Get the encryption status
-     *
-     * @hide
-     */
-    public @LeAudioBroadcastSinkEncryptionState int getEncryptionStatus() {
-        return mEncryptionStatus;
-    }
-
-    /**
-     * Get the incorrect broadcast code that the Scan delegator used to decrypt the Broadcast Audio
-     * Stream and failed.
-     *
-     * <p>This code is valid only if {@link #getEncryptionStatus} returns {@link
-     * #LE_AUDIO_BROADCAST_SINK_ENC_STATE_BAD_CODE}
-     *
-     * @return byte array containing bad broadcast value, null if the current encryption status is
-     *     not {@link #LE_AUDIO_BROADCAST_SINK_ENC_STATE_BAD_CODE}
-     * @hide
-     */
-    public @Nullable byte[] getBadBroadcastCode() {
-        return mBadBroadcastCode;
-    }
-
-    /**
-     * Get the number of subgroups.
-     *
-     * @return number of subgroups
-     * @hide
-     */
-    public byte getNumberOfSubGroups() {
-        return mNumSubGroups;
-    }
-
-    public @NonNull Map<Integer, Integer> getSubgroupBisSyncState() {
-        return mSubgroupBisSyncState;
-    }
-
-    public void setSubgroupBisSyncState(@NonNull Map<Integer, Integer> bisSyncState) {
-        mSubgroupBisSyncState = new HashMap<Integer, Integer>(bisSyncState);
-    }
-
-    /*package*/ void setBroadcastCode(@NonNull String broadcastCode) {
-        mBroadcastCode = broadcastCode;
-    }
-
-    /**
-     * Get the broadcast code
-     *
-     * @return
-     * @hide
-     */
-    public @NonNull String getBroadcastCode() {
-        return mBroadcastCode;
-    }
-
-    /**
-     * Set the broadcast ID
-     *
-     * @param broadcastId broadcast ID of the Broadcast Source
-     * @hide
-     */
-    public void setBroadcastId(int broadcastId) {
-        mBroadcastId = broadcastId;
-    }
-
-    private void writeSubgroupBisSyncStateToParcel(
-            @NonNull Parcel dest, @NonNull Map<Integer, Integer> subgroupBisSyncState) {
-        dest.writeInt(subgroupBisSyncState.size());
-        for (Map.Entry<Integer, Integer> entry : subgroupBisSyncState.entrySet()) {
-            dest.writeInt(entry.getKey());
-            dest.writeInt(entry.getValue());
-        }
-    }
-
-    private static void readSubgroupBisSyncStateFromParcel(
-            @NonNull Parcel in, @NonNull Map<Integer, Integer> subgroupBisSyncState) {
-        int size = in.readInt();
-
-        for (int i = 0; i < size; i++) {
-            Integer key = in.readInt();
-            Integer value = in.readInt();
-            subgroupBisSyncState.put(key, value);
-        }
-    }
-
-    private void writeSubgroupMetadataToParcel(
-            @NonNull Parcel dest, @Nullable Map<Integer, byte[]> subgroupMetadata) {
-        if (subgroupMetadata == null) {
-            dest.writeInt(0);
-            return;
-        }
-
-        dest.writeInt(subgroupMetadata.size());
-        for (Map.Entry<Integer, byte[]> entry : subgroupMetadata.entrySet()) {
-            dest.writeInt(entry.getKey());
-            byte[] metadata = entry.getValue();
-            if (metadata != null) {
-                dest.writeInt(metadata.length);
-                dest.writeByteArray(metadata);
-            }
-        }
-    }
-
-    private static void readSubgroupMetadataFromParcel(
-            @NonNull Parcel in, @NonNull Map<Integer, byte[]> subgroupMetadata) {
-        int size = in.readInt();
-
-        for (int i = 0; i < size; i++) {
-            Integer key = in.readInt();
-            Integer metaDataLen = in.readInt();
-            byte[] metadata = null;
-            if (metaDataLen != 0) {
-                metadata = new byte[metaDataLen];
-                in.readByteArray(metadata);
-            }
-            subgroupMetadata.put(key, metadata);
-        }
-    }
-
-    public static final @NonNull Parcelable.Creator<BluetoothLeBroadcastSourceInfo> CREATOR =
-            new Parcelable.Creator<BluetoothLeBroadcastSourceInfo>() {
-                public @NonNull BluetoothLeBroadcastSourceInfo createFromParcel(
-                        @NonNull Parcel in) {
-                    final byte sourceId = in.readByte();
-                    final int sourceAddressType = in.readInt();
-                    final BluetoothDevice sourceDevice =
-                            in.readTypedObject(BluetoothDevice.CREATOR);
-                    final byte sourceAdvSid = in.readByte();
-                    final int broadcastId = in.readInt();
-                    final int paSyncState = in.readInt();
-                    final int audioSyncState = in.readInt();
-                    final int encryptionStatus = in.readInt();
-                    final int badBroadcastLen = in.readInt();
-                    byte[] badBroadcastCode = null;
-
-                    if (badBroadcastLen > 0) {
-                        badBroadcastCode = new byte[badBroadcastLen];
-                        in.readByteArray(badBroadcastCode);
-                    }
-                    final byte numSubGroups = in.readByte();
-                    final String broadcastCode = in.readString();
-                    Map<Integer, Integer> subgroupBisSyncState = new HashMap<Integer, Integer>();
-                    readSubgroupBisSyncStateFromParcel(in, subgroupBisSyncState);
-                    Map<Integer, byte[]> subgroupMetadata = new HashMap<Integer, byte[]>();
-                    readSubgroupMetadataFromParcel(in, subgroupMetadata);
-
-                    BluetoothLeBroadcastSourceInfo srcInfo =
-                            new BluetoothLeBroadcastSourceInfo(
-                                    sourceId,
-                                    sourceAddressType,
-                                    sourceDevice,
-                                    sourceAdvSid,
-                                    broadcastId,
-                                    paSyncState,
-                                    encryptionStatus,
-                                    audioSyncState,
-                                    badBroadcastCode,
-                                    numSubGroups,
-                                    subgroupBisSyncState,
-                                    subgroupMetadata,
-                                    broadcastCode);
-                    return srcInfo;
-                }
-
-                public @NonNull BluetoothLeBroadcastSourceInfo[] newArray(int size) {
-                    return new BluetoothLeBroadcastSourceInfo[size];
-                }
-            };
-
-    @Override
-    public void writeToParcel(@NonNull Parcel out, int flags) {
-        out.writeByte(mSourceId);
-        out.writeInt(mSourceAddressType);
-        out.writeTypedObject(mSourceDevice, 0);
-        out.writeByte(mSourceAdvSid);
-        out.writeInt(mBroadcastId);
-        out.writeInt(mPaSyncState);
-        out.writeInt(mAudioSyncState);
-        out.writeInt(mEncryptionStatus);
-
-        if (mBadBroadcastCode != null) {
-            out.writeInt(mBadBroadcastCode.length);
-            out.writeByteArray(mBadBroadcastCode);
-        } else {
-            // zero indicates that there is no "bad broadcast code"
-            out.writeInt(0);
-        }
-        out.writeByte(mNumSubGroups);
-        out.writeString(mBroadcastCode);
-        writeSubgroupBisSyncStateToParcel(out, mSubgroupBisSyncState);
-        writeSubgroupMetadataToParcel(out, mSubgroupMetadata);
-    }
-
-    private static void log(@NonNull String msg) {
-        if (DBG) {
-            Log.d(TAG, msg);
-        }
-    }
-}
-;
diff --git a/core/java/android/bluetooth/BluetoothLeCall.java b/core/java/android/bluetooth/BluetoothLeCall.java
deleted file mode 100644
index fb7789d..0000000
--- a/core/java/android/bluetooth/BluetoothLeCall.java
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * Copyright 2021 HIMSA II K/S - www.himsa.com.
- * Represented by EHIMA - www.ehima.com
- *
- * 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.bluetooth;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.ParcelUuid;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Objects;
-import java.util.UUID;
-
-/**
- * Representation of Call
- *
- * @hide
- */
-public final class BluetoothLeCall implements Parcelable {
-
-    /** @hide */
-    @IntDef(prefix = "STATE_", value = {
-            STATE_INCOMING,
-            STATE_DIALING,
-            STATE_ALERTING,
-            STATE_ACTIVE,
-            STATE_LOCALLY_HELD,
-            STATE_REMOTELY_HELD,
-            STATE_LOCALLY_AND_REMOTELY_HELD
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface State {
-    }
-
-    /**
-     * A remote party is calling (incoming call).
-     *
-     * @hide
-     */
-    public static final int STATE_INCOMING = 0x00;
-
-    /**
-     * The process to call the remote party has started but the remote party is not
-     * being alerted (outgoing call).
-     *
-     * @hide
-     */
-    public static final int STATE_DIALING = 0x01;
-
-    /**
-     * A remote party is being alerted (outgoing call).
-     *
-     * @hide
-     */
-    public static final int STATE_ALERTING = 0x02;
-
-    /**
-     * The call is in an active conversation.
-     *
-     * @hide
-     */
-    public static final int STATE_ACTIVE = 0x03;
-
-    /**
-     * The call is connected but held locally. “Locally Held” implies that either
-     * the server or the client can affect the state.
-     *
-     * @hide
-     */
-    public static final int STATE_LOCALLY_HELD = 0x04;
-
-    /**
-     * The call is connected but held remotely. “Remotely Held” means that the state
-     * is controlled by the remote party of a call.
-     *
-     * @hide
-     */
-    public static final int STATE_REMOTELY_HELD = 0x05;
-
-    /**
-     * The call is connected but held both locally and remotely.
-     *
-     * @hide
-     */
-    public static final int STATE_LOCALLY_AND_REMOTELY_HELD = 0x06;
-
-    /**
-     * Whether the call direction is outgoing.
-     *
-     * @hide
-     */
-    public static final int FLAG_OUTGOING_CALL = 0x00000001;
-
-    /**
-     * Whether the call URI and Friendly Name are withheld by server.
-     *
-     * @hide
-     */
-    public static final int FLAG_WITHHELD_BY_SERVER = 0x00000002;
-
-    /**
-     * Whether the call URI and Friendly Name are withheld by network.
-     *
-     * @hide
-     */
-    public static final int FLAG_WITHHELD_BY_NETWORK = 0x00000004;
-
-    /** Unique UUID that identifies this call */
-    private UUID mUuid;
-
-    /** Remote Caller URI */
-    private String mUri;
-
-    /** Caller friendly name */
-    private String mFriendlyName;
-
-    /** Call state */
-    private @State int mState;
-
-    /** Call flags */
-    private int mCallFlags;
-
-    /** @hide */
-    public BluetoothLeCall(@NonNull BluetoothLeCall that) {
-        mUuid = new UUID(that.getUuid().getMostSignificantBits(),
-                that.getUuid().getLeastSignificantBits());
-        mUri = that.mUri;
-        mFriendlyName = that.mFriendlyName;
-        mState = that.mState;
-        mCallFlags = that.mCallFlags;
-    }
-
-    /** @hide */
-    public BluetoothLeCall(@NonNull UUID uuid, @NonNull String uri, @NonNull String friendlyName,
-            @State int state, int callFlags) {
-        mUuid = uuid;
-        mUri = uri;
-        mFriendlyName = friendlyName;
-        mState = state;
-        mCallFlags = callFlags;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o)
-            return true;
-        if (o == null || getClass() != o.getClass())
-            return false;
-        BluetoothLeCall that = (BluetoothLeCall) o;
-        return mUuid.equals(that.mUuid) && mUri.equals(that.mUri)
-                && mFriendlyName.equals(that.mFriendlyName) && mState == that.mState
-                && mCallFlags == that.mCallFlags;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(mUuid, mUri, mFriendlyName, mState, mCallFlags);
-    }
-
-    /**
-     * Returns a string representation of this BluetoothLeCall.
-     *
-     * <p>
-     * Currently this is the UUID.
-     *
-     * @return string representation of this BluetoothLeCall
-     */
-    @Override
-    public String toString() {
-        return mUuid.toString();
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(@NonNull Parcel out, int flags) {
-        out.writeParcelable(new ParcelUuid(mUuid), 0);
-        out.writeString(mUri);
-        out.writeString(mFriendlyName);
-        out.writeInt(mState);
-        out.writeInt(mCallFlags);
-    }
-
-    public static final @android.annotation.NonNull Parcelable.Creator<BluetoothLeCall> CREATOR =
-    						    new Parcelable.Creator<BluetoothLeCall>() {
-        public BluetoothLeCall createFromParcel(Parcel in) {
-            return new BluetoothLeCall(in);
-        }
-
-        public BluetoothLeCall[] newArray(int size) {
-            return new BluetoothLeCall[size];
-        }
-    };
-
-    private BluetoothLeCall(Parcel in) {
-        mUuid = ((ParcelUuid) in.readParcelable(null)).getUuid();
-        mUri = in.readString();
-        mFriendlyName = in.readString();
-        mState = in.readInt();
-        mCallFlags = in.readInt();
-    }
-
-    /**
-     * Returns an UUID of this BluetoothLeCall.
-     *
-     * <p>
-     * An UUID is unique identifier of a BluetoothLeCall.
-     *
-     * @return UUID of this BluetoothLeCall
-     * @hide
-     */
-    public @NonNull UUID getUuid() {
-        return mUuid;
-    }
-
-    /**
-     * Returns a URI of the remote party of this BluetoothLeCall.
-     *
-     * @return string representation of this BluetoothLeCall
-     * @hide
-     */
-    public @NonNull String getUri() {
-        return mUri;
-    }
-
-    /**
-     * Returns a friendly name of the call.
-     *
-     * @return friendly name representation of this BluetoothLeCall
-     * @hide
-     */
-    public @NonNull String getFriendlyName() {
-        return mFriendlyName;
-    }
-
-    /**
-     * Returns the call state.
-     *
-     * @return the state of this BluetoothLeCall
-     * @hide
-     */
-    public @State int getState() {
-        return mState;
-    }
-
-    /**
-     * Returns the call flags.
-     *
-     * @return call flags
-     * @hide
-     */
-    public int getCallFlags() {
-        return mCallFlags;
-    }
-
-    /**
-     * Whether the call direction is incoming.
-     *
-     * @return true if incoming call, false otherwise
-     * @hide
-     */
-    public boolean isIncomingCall() {
-        return (mCallFlags & FLAG_OUTGOING_CALL) == 0;
-    }
-}
diff --git a/core/java/android/bluetooth/BluetoothLeCallControl.java b/core/java/android/bluetooth/BluetoothLeCallControl.java
deleted file mode 100644
index fb080c9..0000000
--- a/core/java/android/bluetooth/BluetoothLeCallControl.java
+++ /dev/null
@@ -1,899 +0,0 @@
-/*
- * Copyright 2019 HIMSA II K/S - www.himsa.com.
- * Represented by EHIMA - www.ehima.com
- *
- * 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.bluetooth;
-
-import android.Manifest;
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.RequiresPermission;
-import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
-import android.content.ComponentName;
-import android.content.Context;
-import android.os.Binder;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.Message;
-import android.os.ParcelUuid;
-import android.os.RemoteException;
-import android.util.Log;
-import android.annotation.SuppressLint;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-import java.util.concurrent.Executor;
-
-/**
- * This class provides the APIs to control the Call Control profile.
- *
- * <p>
- * This class provides Bluetooth Telephone Bearer Service functionality,
- * allowing applications to expose a GATT Service based interface to control the
- * state of the calls by remote devices such as LE audio devices.
- *
- * <p>
- * BluetoothLeCallControl is a proxy object for controlling the Bluetooth Telephone Bearer
- * Service via IPC. Use {@link BluetoothAdapter#getProfileProxy} to get the
- * BluetoothLeCallControl proxy object.
- *
- * @hide
- */
-public final class BluetoothLeCallControl implements BluetoothProfile {
-    private static final String TAG = "BluetoothLeCallControl";
-    private static final boolean DBG = true;
-    private static final boolean VDBG = false;
-
-    /** @hide */
-    @IntDef(prefix = "RESULT_", value = {
-            RESULT_SUCCESS,
-            RESULT_ERROR_UNKNOWN_CALL_ID,
-            RESULT_ERROR_INVALID_URI,
-            RESULT_ERROR_APPLICATION
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface Result {
-    }
-
-    /**
-     * Opcode write was successful.
-     *
-     * @hide
-     */
-    public static final int RESULT_SUCCESS = 0;
-
-    /**
-     * Unknown call Id has been used in the operation.
-     *
-     * @hide
-     */
-    public static final int RESULT_ERROR_UNKNOWN_CALL_ID = 1;
-
-    /**
-     * The URI provided in {@link Callback#onPlaceCallRequest} is invalid.
-     *
-     * @hide
-     */
-    public static final int RESULT_ERROR_INVALID_URI = 2;
-
-    /**
-     * Application internal error.
-     *
-     * @hide
-     */
-    public static final int RESULT_ERROR_APPLICATION = 3;
-
-    /** @hide */
-    @IntDef(prefix = "TERMINATION_REASON_", value = {
-            TERMINATION_REASON_INVALID_URI,
-            TERMINATION_REASON_FAIL,
-            TERMINATION_REASON_REMOTE_HANGUP,
-            TERMINATION_REASON_SERVER_HANGUP,
-            TERMINATION_REASON_LINE_BUSY,
-            TERMINATION_REASON_NETWORK_CONGESTION,
-            TERMINATION_REASON_CLIENT_HANGUP,
-            TERMINATION_REASON_NO_SERVICE,
-            TERMINATION_REASON_NO_ANSWER
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface TerminationReason {
-    }
-
-    /**
-     * Remote Caller ID value used to place a call was formed improperly.
-     *
-     * @hide
-     */
-    public static final int TERMINATION_REASON_INVALID_URI = 0x00;
-
-    /**
-     * Call fail.
-     *
-     * @hide
-     */
-    public static final int TERMINATION_REASON_FAIL = 0x01;
-
-    /**
-     * Remote party ended call.
-     *
-     * @hide
-     */
-    public static final int TERMINATION_REASON_REMOTE_HANGUP = 0x02;
-
-    /**
-     * Call ended from the server.
-     *
-     * @hide
-     */
-    public static final int TERMINATION_REASON_SERVER_HANGUP = 0x03;
-
-    /**
-     * Line busy.
-     *
-     * @hide
-     */
-    public static final int TERMINATION_REASON_LINE_BUSY = 0x04;
-
-    /**
-     * Network congestion.
-     *
-     * @hide
-     */
-    public static final int TERMINATION_REASON_NETWORK_CONGESTION = 0x05;
-
-    /**
-     * Client terminated.
-     *
-     * @hide
-     */
-    public static final int TERMINATION_REASON_CLIENT_HANGUP = 0x06;
-
-    /**
-     * No service.
-     *
-     * @hide
-     */
-    public static final int TERMINATION_REASON_NO_SERVICE = 0x07;
-
-    /**
-     * No answer.
-     *
-     * @hide
-     */
-    public static final int TERMINATION_REASON_NO_ANSWER = 0x08;
-
-    /*
-     * Flag indicating support for hold/unhold call feature.
-     *
-     * @hide
-     */
-    public static final int CAPABILITY_HOLD_CALL = 0x00000001;
-
-    /**
-     * Flag indicating support for joining calls feature.
-     *
-     * @hide
-     */
-    public static final int CAPABILITY_JOIN_CALLS = 0x00000002;
-
-    private static final int MESSAGE_TBS_SERVICE_CONNECTED = 102;
-    private static final int MESSAGE_TBS_SERVICE_DISCONNECTED = 103;
-
-    private static final int REG_TIMEOUT = 10000;
-
-    /**
-     * The template class is used to call callback functions on events from the TBS
-     * server. Callback functions are wrapped in this class and registered to the
-     * Android system during app registration.
-     *
-     * @hide
-     */
-    public abstract static class Callback {
-
-        private static final String TAG = "BluetoothLeCallControl.Callback";
-
-        /**
-         * Called when a remote client requested to accept the call.
-         *
-         * <p>
-         * An application must call {@link BluetoothLeCallControl#requestResult} to complete the
-         * request.
-         *
-         * @param requestId The Id of the request
-         * @param callId    The call Id requested to be accepted
-         * @hide
-         */
-        public abstract void onAcceptCall(int requestId, @NonNull UUID callId);
-
-        /**
-         * A remote client has requested to terminate the call.
-         *
-         * <p>
-         * An application must call {@link BluetoothLeCallControl#requestResult} to complete the
-         * request.
-         *
-         * @param requestId The Id of the request
-         * @param callId    The call Id requested to terminate
-         * @hide
-         */
-        public abstract void onTerminateCall(int requestId, @NonNull UUID callId);
-
-        /**
-         * A remote client has requested to hold the call.
-         *
-         * <p>
-         * An application must call {@link BluetoothLeCallControl#requestResult} to complete the
-         * request.
-         *
-         * @param requestId The Id of the request
-         * @param callId    The call Id requested to be put on hold
-         * @hide
-         */
-        public void onHoldCall(int requestId, @NonNull UUID callId) {
-            Log.e(TAG, "onHoldCall: unimplemented, however CAPABILITY_HOLD_CALL is set!");
-        }
-
-        /**
-         * A remote client has requested to unhold the call.
-         *
-         * <p>
-         * An application must call {@link BluetoothLeCallControl#requestResult} to complete the
-         * request.
-         *
-         * @param requestId The Id of the request
-         * @param callId    The call Id requested to unhold
-         * @hide
-         */
-        public void onUnholdCall(int requestId, @NonNull UUID callId) {
-            Log.e(TAG, "onUnholdCall: unimplemented, however CAPABILITY_HOLD_CALL is set!");
-        }
-
-        /**
-         * A remote client has requested to place a call.
-         *
-         * <p>
-         * An application must call {@link BluetoothLeCallControl#requestResult} to complete the
-         * request.
-         *
-         * @param requestId The Id of the request
-         * @param callId    The Id to be assigned for the new call
-         * @param uri       The caller URI requested
-         * @hide
-         */
-        public abstract void onPlaceCall(int requestId, @NonNull UUID callId, @NonNull String uri);
-
-        /**
-         * A remote client has requested to join the calls.
-         *
-         * <p>
-         * An application must call {@link BluetoothLeCallControl#requestResult} to complete the
-         * request.
-         *
-         * @param requestId The Id of the request
-         * @param callIds   The call Id list requested to join
-         * @hide
-         */
-        public void onJoinCalls(int requestId, @NonNull List<UUID> callIds) {
-            Log.e(TAG, "onJoinCalls: unimplemented, however CAPABILITY_JOIN_CALLS is set!");
-        }
-    }
-
-    private class CallbackWrapper extends IBluetoothLeCallControlCallback.Stub {
-
-        private final Executor mExecutor;
-        private final Callback mCallback;
-
-        CallbackWrapper(Executor executor, Callback callback) {
-            mExecutor = executor;
-            mCallback = callback;
-        }
-
-        @Override
-        public void onBearerRegistered(int ccid) {
-            if (mCallback != null) {
-                mCcid = ccid;
-            } else {
-                // registration timeout
-                Log.e(TAG, "onBearerRegistered: mCallback is null");
-            }
-        }
-
-        @Override
-        public void onAcceptCall(int requestId, ParcelUuid uuid) {
-            final long identityToken = Binder.clearCallingIdentity();
-            try {
-                mExecutor.execute(() -> mCallback.onAcceptCall(requestId, uuid.getUuid()));
-            } finally {
-                Binder.restoreCallingIdentity(identityToken);
-            }
-        }
-
-        @Override
-        public void onTerminateCall(int requestId, ParcelUuid uuid) {
-            final long identityToken = Binder.clearCallingIdentity();
-            try {
-                mExecutor.execute(() -> mCallback.onTerminateCall(requestId, uuid.getUuid()));
-            } finally {
-                Binder.restoreCallingIdentity(identityToken);
-            }
-        }
-
-        @Override
-        public void onHoldCall(int requestId, ParcelUuid uuid) {
-            final long identityToken = Binder.clearCallingIdentity();
-            try {
-                mExecutor.execute(() -> mCallback.onHoldCall(requestId, uuid.getUuid()));
-            } finally {
-                Binder.restoreCallingIdentity(identityToken);
-            }
-        }
-
-        @Override
-        public void onUnholdCall(int requestId, ParcelUuid uuid) {
-            final long identityToken = Binder.clearCallingIdentity();
-            try {
-                mExecutor.execute(() -> mCallback.onUnholdCall(requestId, uuid.getUuid()));
-            } finally {
-                Binder.restoreCallingIdentity(identityToken);
-            }
-        }
-
-        @Override
-        public void onPlaceCall(int requestId, ParcelUuid uuid, String uri) {
-            final long identityToken = Binder.clearCallingIdentity();
-            try {
-                mExecutor.execute(() -> mCallback.onPlaceCall(requestId, uuid.getUuid(), uri));
-            } finally {
-                Binder.restoreCallingIdentity(identityToken);
-            }
-        }
-
-        @Override
-        public void onJoinCalls(int requestId, List<ParcelUuid> parcelUuids) {
-            List<UUID> uuids = new ArrayList<>();
-            for (ParcelUuid parcelUuid : parcelUuids) {
-                uuids.add(parcelUuid.getUuid());
-            }
-
-            final long identityToken = Binder.clearCallingIdentity();
-            try {
-                mExecutor.execute(() -> mCallback.onJoinCalls(requestId, uuids));
-            } finally {
-                Binder.restoreCallingIdentity(identityToken);
-            }
-        }
-    };
-
-    private Context mContext;
-    private ServiceListener mServiceListener;
-    private volatile IBluetoothLeCallControl mService;
-    private BluetoothAdapter mAdapter;
-    private int mCcid = 0;
-    private String mToken;
-    private Callback mCallback = null;
-
-    private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
-        new IBluetoothStateChangeCallback.Stub() {
-        public void onBluetoothStateChange(boolean up) {
-            if (DBG)
-                Log.d(TAG, "onBluetoothStateChange: up=" + up);
-            if (!up) {
-                doUnbind();
-            } else {
-                doBind();
-            }
-        }
-    };
-
-    /**
-     * Create a BluetoothLeCallControl proxy object for interacting with the local Bluetooth
-     * telephone bearer service.
-     */
-    /* package */ BluetoothLeCallControl(Context context, ServiceListener listener) {
-        mContext = context;
-        mAdapter = BluetoothAdapter.getDefaultAdapter();
-        mServiceListener = listener;
-
-        IBluetoothManager mgr = mAdapter.getBluetoothManager();
-        if (mgr != null) {
-            try {
-                mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
-            } catch (RemoteException e) {
-                Log.e(TAG, "", e);
-            }
-        }
-
-        doBind();
-    }
-
-    private boolean doBind() {
-        synchronized (mConnection) {
-            if (mService == null) {
-                if (VDBG)
-                    Log.d(TAG, "Binding service...");
-                try {
-                    return mAdapter.getBluetoothManager().
-                            bindBluetoothProfileService(BluetoothProfile.LE_CALL_CONTROL,
-                            mConnection);
-                } catch (RemoteException e) {
-                    Log.e(TAG, "Unable to bind TelephoneBearerService", e);
-                }
-            }
-        }
-        return false;
-    }
-
-    private void doUnbind() {
-        synchronized (mConnection) {
-            if (mService != null) {
-                if (VDBG)
-                    Log.d(TAG, "Unbinding service...");
-                try {
-                    mAdapter.getBluetoothManager().
-                        unbindBluetoothProfileService(BluetoothProfile.LE_CALL_CONTROL,
-                        mConnection);
-                } catch (RemoteException e) {
-                    Log.e(TAG, "Unable to unbind TelephoneBearerService", e);
-                } finally {
-                    mService = null;
-                }
-            }
-        }
-    }
-
-    /* package */ void close() {
-        if (VDBG)
-            log("close()");
-        unregisterBearer();
-
-        IBluetoothManager mgr = mAdapter.getBluetoothManager();
-        if (mgr != null) {
-            try {
-                mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
-            } catch (RemoteException re) {
-                Log.e(TAG, "", re);
-            }
-        }
-        mServiceListener = null;
-        doUnbind();
-    }
-
-    private IBluetoothLeCallControl getService() {
-        return mService;
-    }
-
-    /**
-     * Not supported
-     *
-     * @throws UnsupportedOperationException
-     */
-    @Override
-    public int getConnectionState(@Nullable BluetoothDevice device) {
-        throw new UnsupportedOperationException("not supported");
-    }
-
-    /**
-     * Not supported
-     *
-     * @throws UnsupportedOperationException
-     */
-    @Override
-    public @NonNull List<BluetoothDevice> getConnectedDevices() {
-        throw new UnsupportedOperationException("not supported");
-    }
-
-    /**
-     * Not supported
-     *
-     * @throws UnsupportedOperationException
-     */
-    @Override
-    public @NonNull List<BluetoothDevice> getDevicesMatchingConnectionStates(
-        @NonNull int[] states) {
-        throw new UnsupportedOperationException("not supported");
-    }
-
-    /**
-     * Register Telephone Bearer exposing the interface that allows remote devices
-     * to track and control the call states.
-     *
-     * <p>
-     * This is an asynchronous call. The callback is used to notify success or
-     * failure if the function returns true.
-     *
-     * <p>
-     * Requires {@link android.Manifest.permission#BLUETOOTH} permission.
-     *
-     * <!-- The UCI is a String identifier of the telephone bearer as defined at
-     * https://www.bluetooth.com/specifications/assigned-numbers/uniform-caller-identifiers
-     * (login required). -->
-     *
-     * <!-- The examples of common URI schemes can be found in
-     * https://iana.org/assignments/uri-schemes/uri-schemes.xhtml -->
-     *
-     * <!-- The Technology is an integer value. The possible values are defined at
-     * https://www.bluetooth.com/specifications/assigned-numbers (login required).
-     * -->
-     *
-     * @param uci          Bearer Unique Client Identifier
-     * @param uriSchemes   URI Schemes supported list
-     * @param capabilities bearer capabilities
-     * @param provider     Network provider name
-     * @param technology   Network technology
-     * @param executor     {@link Executor} object on which callback will be
-     *                     executed. The Executor object is required.
-     * @param callback     {@link Callback} object to which callback messages will
-     *                     be sent. The Callback object is required.
-     * @return true on success, false otherwise
-     * @hide
-     */
-    @SuppressLint("ExecutorRegistration")
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)
-    public boolean registerBearer(@Nullable String uci,
-                    @NonNull List<String> uriSchemes, int capabilities,
-                    @NonNull String provider, int technology,
-                    @NonNull Executor executor, @NonNull Callback callback) {
-        if (DBG) {
-            Log.d(TAG, "registerBearer");
-        }
-        if (callback == null) {
-            throw new IllegalArgumentException("null parameter: " + callback);
-        }
-        if (mCcid != 0) {
-            return false;
-        }
-
-        mToken = uci;
-
-        final IBluetoothLeCallControl service = getService();
-        if (service != null) {
-            if (mCallback != null) {
-                Log.e(TAG, "Bearer can be opened only once");
-                return false;
-            }
-
-            mCallback = callback;
-            try {
-                CallbackWrapper callbackWrapper = new CallbackWrapper(executor, callback);
-                service.registerBearer(mToken, callbackWrapper, uci, uriSchemes, capabilities,
-                                        provider, technology);
-            } catch (RemoteException e) {
-                Log.e(TAG, "", e);
-                mCallback = null;
-                return false;
-            }
-
-            if (mCcid == 0) {
-                mCallback = null;
-                return false;
-            }
-
-            return true;
-        }
-
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-        }
-
-        return false;
-    }
-
-    /**
-     * Unregister Telephone Bearer Service and destroy all the associated data.
-     *
-     * @hide
-     */
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)
-    public void unregisterBearer() {
-        if (DBG) {
-            Log.d(TAG, "unregisterBearer");
-        }
-        if (mCcid == 0) {
-            return;
-        }
-
-        int ccid = mCcid;
-        mCcid = 0;
-        mCallback = null;
-
-        final IBluetoothLeCallControl service = getService();
-        if (service != null) {
-            try {
-                service.unregisterBearer(mToken);
-            } catch (RemoteException e) {
-                Log.e(TAG, "", e);
-            }
-        }
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-        }
-    }
-
-    /**
-     * Get the Content Control ID (CCID) value.
-     *
-     * @return ccid Content Control ID value
-     * @hide
-     */
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)
-    public int getContentControlId() {
-        return mCcid;
-    }
-
-    /**
-     * Notify about the newly added call.
-     *
-     * <p>
-     * This shall be called as early as possible after the call has been added.
-     *
-     * <p>
-     * Requires {@link android.Manifest.permission#BLUETOOTH} permission.
-     *
-     * @param call Newly added call
-     * @hide
-     */
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)
-    public void onCallAdded(@NonNull BluetoothLeCall call) {
-        if (DBG) {
-            Log.d(TAG, "onCallAdded: call=" + call);
-        }
-        if (mCcid == 0) {
-            return;
-        }
-
-        final IBluetoothLeCallControl service = getService();
-        if (service != null) {
-            try {
-                service.callAdded(mCcid, call);
-            } catch (RemoteException e) {
-                Log.e(TAG, "", e);
-            }
-        }
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-        }
-    }
-
-    /**
-     * Notify about the removed call.
-     *
-     * <p>
-     * This shall be called as early as possible after the call has been removed.
-     *
-     * <p>
-     * Requires {@link android.Manifest.permission#BLUETOOTH} permission.
-     *
-     * @param callId The Id of a call that has been removed
-     * @param reason Call termination reason
-     * @hide
-     */
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)
-    public void onCallRemoved(@NonNull UUID callId, @TerminationReason int reason) {
-        if (DBG) {
-            Log.d(TAG, "callRemoved: callId=" + callId);
-        }
-        if (mCcid == 0) {
-            return;
-        }
-
-        final IBluetoothLeCallControl service = getService();
-        if (service != null) {
-            try {
-                service.callRemoved(mCcid, new ParcelUuid(callId), reason);
-            } catch (RemoteException e) {
-                Log.e(TAG, "", e);
-            }
-        }
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-        }
-    }
-
-    /**
-     * Notify the call state change
-     *
-     * <p>
-     * This shall be called as early as possible after the state of the call has
-     * changed.
-     *
-     * <p>
-     * Requires {@link android.Manifest.permission#BLUETOOTH} permission.
-     *
-     * @param callId The call Id that state has been changed
-     * @param state  Call state
-     * @hide
-     */
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)
-    public void onCallStateChanged(@NonNull UUID callId, @BluetoothLeCall.State int state) {
-        if (DBG) {
-            Log.d(TAG, "callStateChanged: callId=" + callId + " state=" + state);
-        }
-        if (mCcid == 0) {
-            return;
-        }
-
-        final IBluetoothLeCallControl service = getService();
-        if (service != null) {
-            try {
-                service.callStateChanged(mCcid, new ParcelUuid(callId), state);
-            } catch (RemoteException e) {
-                Log.e(TAG, "", e);
-            }
-        }
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-        }
-    }
-
-    /**
-     * Provide the current calls list
-     *
-     * <p>
-     * This function must be invoked after registration if application has any
-     * calls.
-     *
-     * @param calls current calls list
-     * @hide
-     */
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)
-     public void currentCallsList(@NonNull List<BluetoothLeCall> calls) {
-        final IBluetoothLeCallControl service = getService();
-        if (service != null) {
-            try {
-                service.currentCallsList(mCcid, calls);
-            } catch (RemoteException e) {
-                Log.e(TAG, "", e);
-            }
-        }
-    }
-
-    /**
-     * Provide the network current status
-     *
-     * <p>
-     * This function must be invoked on change of network state.
-     *
-     * <p>
-     * Requires {@link android.Manifest.permission#BLUETOOTH} permission.
-     *
-     * <!-- The Technology is an integer value. The possible values are defined at
-     * https://www.bluetooth.com/specifications/assigned-numbers (login required).
-     * -->
-     *
-     * @param provider   Network provider name
-     * @param technology Network technology
-     * @hide
-     */
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)
-    public void networkStateChanged(@NonNull String provider, int technology) {
-        if (DBG) {
-            Log.d(TAG, "networkStateChanged: provider=" + provider + ", technology=" + technology);
-        }
-        if (mCcid == 0) {
-            return;
-        }
-
-        final IBluetoothLeCallControl service = getService();
-        if (service != null) {
-            try {
-                service.networkStateChanged(mCcid, provider, technology);
-            } catch (RemoteException e) {
-                Log.e(TAG, "", e);
-            }
-        }
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-        }
-    }
-
-    /**
-     * Send a response to a call control request to a remote device.
-     *
-     * <p>
-     * This function must be invoked in when a request is received by one of these
-     * callback methods:
-     *
-     * <ul>
-     * <li>{@link Callback#onAcceptCall}
-     * <li>{@link Callback#onTerminateCall}
-     * <li>{@link Callback#onHoldCall}
-     * <li>{@link Callback#onUnholdCall}
-     * <li>{@link Callback#onPlaceCall}
-     * <li>{@link Callback#onJoinCalls}
-     * </ul>
-     *
-     * @param requestId The ID of the request that was received with the callback
-     * @param result    The result of the request to be sent to the remote devices
-     */
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)
-    public void requestResult(int requestId, @Result int result) {
-        if (DBG) {
-            Log.d(TAG, "requestResult: requestId=" + requestId + " result=" + result);
-        }
-        if (mCcid == 0) {
-            return;
-        }
-
-        final IBluetoothLeCallControl service = getService();
-        if (service != null) {
-            try {
-                service.requestResult(mCcid, requestId, result);
-            } catch (RemoteException e) {
-                Log.e(TAG, "", e);
-            }
-        }
-    }
-
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)
-    private static boolean isValidDevice(@Nullable BluetoothDevice device) {
-        return device != null && BluetoothAdapter.checkBluetoothAddress(device.getAddress());
-    }
-
-    private static void log(String msg) {
-        Log.d(TAG, msg);
-    }
-
-    private final IBluetoothProfileServiceConnection mConnection =
-                                    new IBluetoothProfileServiceConnection.Stub() {
-        @Override
-        public void onServiceConnected(ComponentName className, IBinder service) {
-            if (DBG) {
-                Log.d(TAG, "Proxy object connected");
-            }
-            mService = IBluetoothLeCallControl.Stub.asInterface(Binder.allowBlocking(service));
-            mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_TBS_SERVICE_CONNECTED));
-        }
-
-        @Override
-        public void onServiceDisconnected(ComponentName className) {
-            if (DBG) {
-                Log.d(TAG, "Proxy object disconnected");
-            }
-            doUnbind();
-            mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_TBS_SERVICE_DISCONNECTED));
-        }
-    };
-
-    private final Handler mHandler = new Handler(Looper.getMainLooper()) {
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-            case MESSAGE_TBS_SERVICE_CONNECTED: {
-                if (mServiceListener != null) {
-                    mServiceListener.onServiceConnected(BluetoothProfile.LE_CALL_CONTROL,
-                        BluetoothLeCallControl.this);
-                }
-                break;
-            }
-            case MESSAGE_TBS_SERVICE_DISCONNECTED: {
-                if (mServiceListener != null) {
-                    mServiceListener.onServiceDisconnected(BluetoothProfile.LE_CALL_CONTROL);
-                }
-                break;
-            }
-            }
-        }
-    };
-}
diff --git a/core/java/android/bluetooth/BluetoothManager.java b/core/java/android/bluetooth/BluetoothManager.java
deleted file mode 100644
index fef6f22..0000000
--- a/core/java/android/bluetooth/BluetoothManager.java
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-import android.annotation.RequiresFeature;
-import android.annotation.RequiresNoPermission;
-import android.annotation.RequiresPermission;
-import android.annotation.SystemService;
-import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
-import android.bluetooth.annotations.RequiresLegacyBluetoothPermission;
-import android.content.AttributionSource;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * High level manager used to obtain an instance of an {@link BluetoothAdapter}
- * and to conduct overall Bluetooth Management.
- * <p>
- * Use {@link android.content.Context#getSystemService(java.lang.String)}
- * with {@link Context#BLUETOOTH_SERVICE} to create an {@link BluetoothManager},
- * then call {@link #getAdapter} to obtain the {@link BluetoothAdapter}.
- * </p>
- * <div class="special reference">
- * <h3>Developer Guides</h3>
- * <p>
- * For more information about using BLUETOOTH, read the <a href=
- * "{@docRoot}guide/topics/connectivity/bluetooth.html">Bluetooth</a> developer
- * guide.
- * </p>
- * </div>
- *
- * @see Context#getSystemService
- * @see BluetoothAdapter#getDefaultAdapter()
- */
-@SystemService(Context.BLUETOOTH_SERVICE)
-@RequiresFeature(PackageManager.FEATURE_BLUETOOTH)
-public final class BluetoothManager {
-    private static final String TAG = "BluetoothManager";
-    private static final boolean DBG = false;
-
-    private final AttributionSource mAttributionSource;
-    private final BluetoothAdapter mAdapter;
-
-    /**
-     * @hide
-     */
-    public BluetoothManager(Context context) {
-        mAttributionSource = (context != null) ? context.getAttributionSource() :
-                AttributionSource.myAttributionSource();
-        mAdapter = BluetoothAdapter.createAdapter(mAttributionSource);
-    }
-
-    /**
-     * Get the BLUETOOTH Adapter for this device.
-     *
-     * @return the BLUETOOTH Adapter
-     */
-    @RequiresNoPermission
-    public BluetoothAdapter getAdapter() {
-        return mAdapter;
-    }
-
-    /**
-     * Get the current connection state of the profile to the remote device.
-     *
-     * <p>This is not specific to any application configuration but represents
-     * the connection state of the local Bluetooth adapter for certain profile.
-     * This can be used by applications like status bar which would just like
-     * to know the state of Bluetooth.
-     *
-     * @param device Remote bluetooth device.
-     * @param profile GATT or GATT_SERVER
-     * @return State of the profile connection. One of {@link BluetoothProfile#STATE_CONNECTED},
-     * {@link BluetoothProfile#STATE_CONNECTING}, {@link BluetoothProfile#STATE_DISCONNECTED},
-     * {@link BluetoothProfile#STATE_DISCONNECTING}
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public int getConnectionState(BluetoothDevice device, int profile) {
-        if (DBG) Log.d(TAG, "getConnectionState()");
-
-        List<BluetoothDevice> connectedDevices = getConnectedDevices(profile);
-        for (BluetoothDevice connectedDevice : connectedDevices) {
-            if (device.equals(connectedDevice)) {
-                return BluetoothProfile.STATE_CONNECTED;
-            }
-        }
-
-        return BluetoothProfile.STATE_DISCONNECTED;
-    }
-
-    /**
-     * Get connected devices for the specified profile.
-     *
-     * <p> Return the set of devices which are in state {@link BluetoothProfile#STATE_CONNECTED}
-     *
-     * <p>This is not specific to any application configuration but represents
-     * the connection state of Bluetooth for this profile.
-     * This can be used by applications like status bar which would just like
-     * to know the state of Bluetooth.
-     *
-     * @param profile GATT or GATT_SERVER
-     * @return List of devices. The list will be empty on error.
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public List<BluetoothDevice> getConnectedDevices(int profile) {
-        if (DBG) Log.d(TAG, "getConnectedDevices");
-        return getDevicesMatchingConnectionStates(profile, new int[] {
-                BluetoothProfile.STATE_CONNECTED
-        });
-    }
-
-    /**
-     * Get a list of devices that match any of the given connection
-     * states.
-     *
-     * <p> If none of the devices match any of the given states,
-     * an empty list will be returned.
-     *
-     * <p>This is not specific to any application configuration but represents
-     * the connection state of the local Bluetooth adapter for this profile.
-     * This can be used by applications like status bar which would just like
-     * to know the state of the local adapter.
-     *
-     * @param profile GATT or GATT_SERVER
-     * @param states Array of states. States can be one of {@link BluetoothProfile#STATE_CONNECTED},
-     * {@link BluetoothProfile#STATE_CONNECTING}, {@link BluetoothProfile#STATE_DISCONNECTED},
-     * {@link BluetoothProfile#STATE_DISCONNECTING},
-     * @return List of devices. The list will be empty on error.
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public List<BluetoothDevice> getDevicesMatchingConnectionStates(int profile, int[] states) {
-        if (DBG) Log.d(TAG, "getDevicesMatchingConnectionStates");
-
-        if (profile != BluetoothProfile.GATT && profile != BluetoothProfile.GATT_SERVER) {
-            throw new IllegalArgumentException("Profile not supported: " + profile);
-        }
-
-        List<BluetoothDevice> devices = new ArrayList<BluetoothDevice>();
-
-        try {
-            IBluetoothManager managerService = mAdapter.getBluetoothManager();
-            IBluetoothGatt iGatt = managerService.getBluetoothGatt();
-            if (iGatt == null) return devices;
-            devices = Attributable.setAttributionSource(
-                    iGatt.getDevicesMatchingConnectionStates(states, mAttributionSource),
-                    mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        }
-
-        return devices;
-    }
-
-    /**
-     * Open a GATT Server
-     * The callback is used to deliver results to Caller, such as connection status as well
-     * as the results of any other GATT server operations.
-     * The method returns a BluetoothGattServer instance. You can use BluetoothGattServer
-     * to conduct GATT server operations.
-     *
-     * @param context App context
-     * @param callback GATT server callback handler that will receive asynchronous callbacks.
-     * @return BluetoothGattServer instance
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public BluetoothGattServer openGattServer(Context context,
-            BluetoothGattServerCallback callback) {
-
-        return (openGattServer(context, callback, BluetoothDevice.TRANSPORT_AUTO));
-    }
-
-    /**
-     * Open a GATT Server
-     * The callback is used to deliver results to Caller, such as connection status as well
-     * as the results of any other GATT server operations.
-     * The method returns a BluetoothGattServer instance. You can use BluetoothGattServer
-     * to conduct GATT server operations.
-     *
-     * @param context App context
-     * @param callback GATT server callback handler that will receive asynchronous callbacks.
-     * @param eatt_support idicates if server should use eatt channel for notifications.
-     * @return BluetoothGattServer instance
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public BluetoothGattServer openGattServer(Context context,
-            BluetoothGattServerCallback callback, boolean eatt_support) {
-        return (openGattServer(context, callback, BluetoothDevice.TRANSPORT_AUTO, eatt_support));
-    }
-
-    /**
-     * Open a GATT Server
-     * The callback is used to deliver results to Caller, such as connection status as well
-     * as the results of any other GATT server operations.
-     * The method returns a BluetoothGattServer instance. You can use BluetoothGattServer
-     * to conduct GATT server operations.
-     *
-     * @param context App context
-     * @param callback GATT server callback handler that will receive asynchronous callbacks.
-     * @param transport preferred transport for GATT connections to remote dual-mode devices {@link
-     * BluetoothDevice#TRANSPORT_AUTO} or {@link BluetoothDevice#TRANSPORT_BREDR} or {@link
-     * BluetoothDevice#TRANSPORT_LE}
-     * @return BluetoothGattServer instance
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public BluetoothGattServer openGattServer(Context context,
-            BluetoothGattServerCallback callback, int transport) {
-        return (openGattServer(context, callback, transport, false));
-    }
-
-    /**
-     * Open a GATT Server
-     * The callback is used to deliver results to Caller, such as connection status as well
-     * as the results of any other GATT server operations.
-     * The method returns a BluetoothGattServer instance. You can use BluetoothGattServer
-     * to conduct GATT server operations.
-     *
-     * @param context App context
-     * @param callback GATT server callback handler that will receive asynchronous callbacks.
-     * @param transport preferred transport for GATT connections to remote dual-mode devices {@link
-     * BluetoothDevice#TRANSPORT_AUTO} or {@link BluetoothDevice#TRANSPORT_BREDR} or {@link
-     * BluetoothDevice#TRANSPORT_LE}
-     * @param eatt_support idicates if server should use eatt channel for notifications.
-     * @return BluetoothGattServer instance
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public BluetoothGattServer openGattServer(Context context,
-            BluetoothGattServerCallback callback, int transport, boolean eatt_support) {
-        if (context == null || callback == null) {
-            throw new IllegalArgumentException("null parameter: " + context + " " + callback);
-        }
-
-        // TODO(Bluetooth) check whether platform support BLE
-        //     Do the check here or in GattServer?
-
-        try {
-            IBluetoothManager managerService = mAdapter.getBluetoothManager();
-            IBluetoothGatt iGatt = managerService.getBluetoothGatt();
-            if (iGatt == null) {
-                Log.e(TAG, "Fail to get GATT Server connection");
-                return null;
-            }
-            BluetoothGattServer mGattServer =
-                    new BluetoothGattServer(iGatt, transport, mAdapter);
-            Boolean regStatus = mGattServer.registerCallback(callback, eatt_support);
-            return regStatus ? mGattServer : null;
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-            return null;
-        }
-    }
-}
diff --git a/core/java/android/bluetooth/BluetoothMap.java b/core/java/android/bluetooth/BluetoothMap.java
deleted file mode 100644
index 56e4972..0000000
--- a/core/java/android/bluetooth/BluetoothMap.java
+++ /dev/null
@@ -1,513 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-import static android.bluetooth.BluetoothUtils.getSyncTimeout;
-
-import android.Manifest;
-import android.annotation.NonNull;
-import android.annotation.RequiresNoPermission;
-import android.annotation.RequiresPermission;
-import android.annotation.SdkConstant;
-import android.annotation.SdkConstant.SdkConstantType;
-import android.annotation.SuppressLint;
-import android.annotation.SystemApi;
-import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.content.AttributionSource;
-import android.content.Context;
-import android.os.Build;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.util.CloseGuard;
-import android.util.Log;
-
-import com.android.modules.utils.SynchronousResultReceiver;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.TimeoutException;
-
-/**
- * This class provides the APIs to control the Bluetooth MAP
- * Profile.
- *
- * @hide
- */
-@SystemApi
-public final class BluetoothMap implements BluetoothProfile, AutoCloseable {
-
-    private static final String TAG = "BluetoothMap";
-    private static final boolean DBG = true;
-    private static final boolean VDBG = false;
-
-    private CloseGuard mCloseGuard;
-
-    /** @hide */
-    @SuppressLint("ActionValue")
-    @SystemApi
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_CONNECTION_STATE_CHANGED =
-            "android.bluetooth.map.profile.action.CONNECTION_STATE_CHANGED";
-
-    /**
-     * There was an error trying to obtain the state
-     *
-     * @hide
-     */
-    public static final int STATE_ERROR = -1;
-
-    /** @hide */
-    public static final int RESULT_FAILURE = 0;
-    /** @hide */
-    public static final int RESULT_SUCCESS = 1;
-    /**
-     * Connection canceled before completion.
-     *
-     * @hide
-     */
-    public static final int RESULT_CANCELED = 2;
-
-    private final BluetoothAdapter mAdapter;
-    private final AttributionSource mAttributionSource;
-    private final BluetoothProfileConnector<IBluetoothMap> mProfileConnector =
-            new BluetoothProfileConnector(this, BluetoothProfile.MAP,
-                    "BluetoothMap", IBluetoothMap.class.getName()) {
-                @Override
-                public IBluetoothMap getServiceInterface(IBinder service) {
-                    return IBluetoothMap.Stub.asInterface(service);
-                }
-    };
-
-    /**
-     * Create a BluetoothMap proxy object.
-     */
-    /* package */ BluetoothMap(Context context, ServiceListener listener,
-            BluetoothAdapter adapter) {
-        if (DBG) Log.d(TAG, "Create BluetoothMap proxy object");
-        mAdapter = adapter;
-        mAttributionSource = adapter.getAttributionSource();
-        mProfileConnector.connect(context, listener);
-        mCloseGuard = new CloseGuard();
-        mCloseGuard.open("close");
-    }
-
-    protected void finalize() {
-        if (mCloseGuard != null) {
-            mCloseGuard.warnIfOpen();
-        }
-        close();
-    }
-
-    /**
-     * Close the connection to the backing service.
-     * Other public functions of BluetoothMap will return default error
-     * results once close() has been called. Multiple invocations of close()
-     * are ok.
-     *
-     * @hide
-     */
-    @SystemApi
-    public void close() {
-        if (VDBG) log("close()");
-        mProfileConnector.disconnect();
-    }
-
-    private IBluetoothMap getService() {
-        return mProfileConnector.getService();
-    }
-
-    /**
-     * Get the current state of the BluetoothMap service.
-     *
-     * @return One of the STATE_ return codes, or STATE_ERROR if this proxy object is currently not
-     * connected to the Map service.
-     *
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public int getState() {
-        if (VDBG) log("getState()");
-        final IBluetoothMap service = getService();
-        final int defaultValue = BluetoothMap.STATE_ERROR;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
-                service.getState(mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Get the currently connected remote Bluetooth device (PCE).
-     *
-     * @return The remote Bluetooth device, or null if not in connected or connecting state, or if
-     * this proxy object is not connected to the Map service.
-     *
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public BluetoothDevice getClient() {
-        if (VDBG) log("getClient()");
-        final IBluetoothMap service = getService();
-        final BluetoothDevice defaultValue = null;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<BluetoothDevice> recv =
-                        new SynchronousResultReceiver();
-                service.getClient(mAttributionSource, recv);
-                return Attributable.setAttributionSource(
-                        recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
-                        mAttributionSource);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Returns true if the specified Bluetooth device is connected.
-     * Returns false if not connected, or if this proxy object is not
-     * currently connected to the Map service.
-     *
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean isConnected(BluetoothDevice device) {
-        if (VDBG) log("isConnected(" + device + ")");
-        final IBluetoothMap service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.isConnected(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Initiate connection. Initiation of outgoing connections is not
-     * supported for MAP server.
-     *
-     * @hide
-     */
-    @RequiresNoPermission
-    public boolean connect(BluetoothDevice device) {
-        if (DBG) log("connect(" + device + ")" + "not supported for MAPS");
-        return false;
-    }
-
-    /**
-     * Initiate disconnect.
-     *
-     * @param device Remote Bluetooth Device
-     * @return false on error, true otherwise
-     *
-     * @hide
-     */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean disconnect(BluetoothDevice device) {
-        if (DBG) log("disconnect(" + device + ")");
-        final IBluetoothMap service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.disconnect(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Check class bits for possible Map support.
-     * This is a simple heuristic that tries to guess if a device with the
-     * given class bits might support Map. It is not accurate for all
-     * devices. It tries to err on the side of false positives.
-     *
-     * @return True if this device might support Map.
-     *
-     * @hide
-     */
-    public static boolean doesClassMatchSink(BluetoothClass btClass) {
-        // TODO optimize the rule
-        switch (btClass.getDeviceClass()) {
-            case BluetoothClass.Device.COMPUTER_DESKTOP:
-            case BluetoothClass.Device.COMPUTER_LAPTOP:
-            case BluetoothClass.Device.COMPUTER_SERVER:
-            case BluetoothClass.Device.COMPUTER_UNCATEGORIZED:
-                return true;
-            default:
-                return false;
-        }
-    }
-
-    /**
-     * Get the list of connected devices. Currently at most one.
-     *
-     * @return list of connected devices
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public @NonNull List<BluetoothDevice> getConnectedDevices() {
-        if (DBG) log("getConnectedDevices()");
-        final IBluetoothMap service = getService();
-        final List<BluetoothDevice> defaultValue = new ArrayList<BluetoothDevice>();
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<List<BluetoothDevice>> recv =
-                        new SynchronousResultReceiver();
-                service.getConnectedDevices(mAttributionSource, recv);
-                return Attributable.setAttributionSource(
-                        recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
-                        mAttributionSource);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Get the list of devices matching specified states. Currently at most one.
-     *
-     * @return list of matching devices
-     *
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
-    public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
-        if (DBG) log("getDevicesMatchingStates()");
-        final IBluetoothMap service = getService();
-        final List<BluetoothDevice> defaultValue = new ArrayList<BluetoothDevice>();
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<List<BluetoothDevice>> recv =
-                        new SynchronousResultReceiver();
-                service.getDevicesMatchingConnectionStates(states, mAttributionSource, recv);
-                return Attributable.setAttributionSource(
-                        recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
-                        mAttributionSource);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Get connection state of device
-     *
-     * @return device connection state
-     *
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
-    public int getConnectionState(BluetoothDevice device) {
-        if (DBG) log("getConnectionState(" + device + ")");
-        final IBluetoothMap service = getService();
-        final int defaultValue = BluetoothProfile.STATE_DISCONNECTED;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Integer> recv =
-                        new SynchronousResultReceiver();
-                service.getConnectionState(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Set priority of the profile
-     *
-     * <p> The device should already be paired.
-     * Priority can be one of {@link #PRIORITY_ON} or {@link #PRIORITY_OFF},
-     *
-     * @param device Paired bluetooth device
-     * @param priority
-     * @return true if priority is set, false on error
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public boolean setPriority(BluetoothDevice device, int priority) {
-        if (DBG) log("setPriority(" + device + ", " + priority + ")");
-        return setConnectionPolicy(device, BluetoothAdapter.priorityToConnectionPolicy(priority));
-    }
-
-    /**
-     * Set connection policy of the profile
-     *
-     * <p> The device should already be paired.
-     * Connection policy can be one of {@link #CONNECTION_POLICY_ALLOWED},
-     * {@link #CONNECTION_POLICY_FORBIDDEN}, {@link #CONNECTION_POLICY_UNKNOWN}
-     *
-     * @param device Paired bluetooth device
-     * @param connectionPolicy is the connection policy to set to for this profile
-     * @return true if connectionPolicy is set, false on error
-     * @hide
-     */
-    @SystemApi
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public boolean setConnectionPolicy(@NonNull BluetoothDevice device,
-            @ConnectionPolicy int connectionPolicy) {
-        if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
-        final IBluetoothMap service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)
-                    && (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_FORBIDDEN
-                        || connectionPolicy == BluetoothProfile.CONNECTION_POLICY_ALLOWED)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.setConnectionPolicy(device, connectionPolicy, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Get the priority of the profile.
-     *
-     * <p> The priority can be any of:
-     * {@link #PRIORITY_OFF}, {@link #PRIORITY_ON}, {@link #PRIORITY_UNDEFINED}
-     *
-     * @param device Bluetooth device
-     * @return priority of the device
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public int getPriority(BluetoothDevice device) {
-        if (VDBG) log("getPriority(" + device + ")");
-        return BluetoothAdapter.connectionPolicyToPriority(getConnectionPolicy(device));
-    }
-
-    /**
-     * Get the connection policy of the profile.
-     *
-     * <p> The connection policy can be any of:
-     * {@link #CONNECTION_POLICY_ALLOWED}, {@link #CONNECTION_POLICY_FORBIDDEN},
-     * {@link #CONNECTION_POLICY_UNKNOWN}
-     *
-     * @param device Bluetooth device
-     * @return connection policy of the device
-     * @hide
-     */
-    @SystemApi
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public @ConnectionPolicy int getConnectionPolicy(@NonNull BluetoothDevice device) {
-        if (VDBG) log("getConnectionPolicy(" + device + ")");
-        final IBluetoothMap service = getService();
-        final int defaultValue = BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
-                service.getConnectionPolicy(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    private static void log(String msg) {
-        Log.d(TAG, msg);
-    }
-
-    private boolean isEnabled() {
-        return mAdapter.isEnabled();
-    }
-
-    private static boolean isValidDevice(BluetoothDevice device) {
-        return device != null && BluetoothAdapter.checkBluetoothAddress(device.getAddress());
-    }
-}
diff --git a/core/java/android/bluetooth/BluetoothMapClient.java b/core/java/android/bluetooth/BluetoothMapClient.java
deleted file mode 100644
index 03536f9a..0000000
--- a/core/java/android/bluetooth/BluetoothMapClient.java
+++ /dev/null
@@ -1,686 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-import static android.bluetooth.BluetoothUtils.getSyncTimeout;
-
-import android.Manifest;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.RequiresPermission;
-import android.annotation.SdkConstant;
-import android.annotation.SdkConstant.SdkConstantType;
-import android.annotation.SystemApi;
-import android.app.PendingIntent;
-import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.content.AttributionSource;
-import android.content.Context;
-import android.net.Uri;
-import android.os.Build;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.util.Log;
-
-import com.android.modules.utils.SynchronousResultReceiver;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.concurrent.TimeoutException;
-
-/**
- * This class provides the APIs to control the Bluetooth MAP MCE Profile.
- *
- * @hide
- */
-@SystemApi
-public final class BluetoothMapClient implements BluetoothProfile {
-
-    private static final String TAG = "BluetoothMapClient";
-    private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG);
-    private static final boolean VDBG = Log.isLoggable(TAG, Log.VERBOSE);
-
-    /** @hide */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_CONNECTION_STATE_CHANGED =
-            "android.bluetooth.mapmce.profile.action.CONNECTION_STATE_CHANGED";
-    /** @hide */
-    @RequiresPermission(android.Manifest.permission.RECEIVE_SMS)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_MESSAGE_RECEIVED =
-            "android.bluetooth.mapmce.profile.action.MESSAGE_RECEIVED";
-    /* Actions to be used for pending intents */
-    /** @hide */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_MESSAGE_SENT_SUCCESSFULLY =
-            "android.bluetooth.mapmce.profile.action.MESSAGE_SENT_SUCCESSFULLY";
-    /** @hide */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_MESSAGE_DELIVERED_SUCCESSFULLY =
-            "android.bluetooth.mapmce.profile.action.MESSAGE_DELIVERED_SUCCESSFULLY";
-
-    /**
-     * Action to notify read status changed
-     *
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_MESSAGE_READ_STATUS_CHANGED =
-            "android.bluetooth.mapmce.profile.action.MESSAGE_READ_STATUS_CHANGED";
-
-    /**
-     * Action to notify deleted status changed
-     *
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_MESSAGE_DELETED_STATUS_CHANGED =
-            "android.bluetooth.mapmce.profile.action.MESSAGE_DELETED_STATUS_CHANGED";
-
-    /**
-     * Extras used in ACTION_MESSAGE_RECEIVED intent.
-     * NOTE: HANDLE is only valid for a single session with the device.
-     */
-    /** @hide */
-    public static final String EXTRA_MESSAGE_HANDLE =
-            "android.bluetooth.mapmce.profile.extra.MESSAGE_HANDLE";
-    /** @hide */
-    public static final String EXTRA_MESSAGE_TIMESTAMP =
-            "android.bluetooth.mapmce.profile.extra.MESSAGE_TIMESTAMP";
-    /** @hide */
-    public static final String EXTRA_MESSAGE_READ_STATUS =
-            "android.bluetooth.mapmce.profile.extra.MESSAGE_READ_STATUS";
-    /** @hide */
-    public static final String EXTRA_SENDER_CONTACT_URI =
-            "android.bluetooth.mapmce.profile.extra.SENDER_CONTACT_URI";
-    /** @hide */
-    public static final String EXTRA_SENDER_CONTACT_NAME =
-            "android.bluetooth.mapmce.profile.extra.SENDER_CONTACT_NAME";
-
-    /**
-     * Used as a boolean extra in ACTION_MESSAGE_DELETED_STATUS_CHANGED
-     * Contains the MAP message deleted status
-     * Possible values are:
-     * true: deleted
-     * false: undeleted
-     *
-     * @hide
-     */
-    public static final String EXTRA_MESSAGE_DELETED_STATUS =
-            "android.bluetooth.mapmce.profile.extra.MESSAGE_DELETED_STATUS";
-
-    /**
-     * Extra used in ACTION_MESSAGE_READ_STATUS_CHANGED or ACTION_MESSAGE_DELETED_STATUS_CHANGED
-     * Possible values are:
-     * 0: failure
-     * 1: success
-     *
-     * @hide
-     */
-    public static final String EXTRA_RESULT_CODE =
-            "android.bluetooth.device.extra.RESULT_CODE";
-
-    /**
-     * There was an error trying to obtain the state
-     * @hide
-     */
-    public static final int STATE_ERROR = -1;
-
-    /** @hide */
-    public static final int RESULT_FAILURE = 0;
-    /** @hide */
-    public static final int RESULT_SUCCESS = 1;
-    /**
-     * Connection canceled before completion.
-     * @hide
-     */
-    public static final int RESULT_CANCELED = 2;
-    /** @hide */
-    private static final int UPLOADING_FEATURE_BITMASK = 0x08;
-
-    /*
-     * UNREAD, READ, UNDELETED, DELETED are passed as parameters
-     * to setMessageStatus to indicate the messages new state.
-     */
-
-    /** @hide */
-    public static final int UNREAD = 0;
-    /** @hide */
-    public static final int READ = 1;
-    /** @hide */
-    public static final int UNDELETED = 2;
-    /** @hide */
-    public static final int DELETED = 3;
-
-    private final BluetoothAdapter mAdapter;
-    private final AttributionSource mAttributionSource;
-    private final BluetoothProfileConnector<IBluetoothMapClient> mProfileConnector =
-            new BluetoothProfileConnector(this, BluetoothProfile.MAP_CLIENT,
-                    "BluetoothMapClient", IBluetoothMapClient.class.getName()) {
-                @Override
-                public IBluetoothMapClient getServiceInterface(IBinder service) {
-                    return IBluetoothMapClient.Stub.asInterface(service);
-                }
-    };
-
-    /**
-     * Create a BluetoothMapClient proxy object.
-     */
-    /* package */ BluetoothMapClient(Context context, ServiceListener listener,
-            BluetoothAdapter adapter) {
-        if (DBG) Log.d(TAG, "Create BluetoothMapClient proxy object");
-        mAdapter = adapter;
-        mAttributionSource = adapter.getAttributionSource();
-        mProfileConnector.connect(context, listener);
-    }
-
-    /**
-     * Close the connection to the backing service.
-     * Other public functions of BluetoothMap will return default error
-     * results once close() has been called. Multiple invocations of close()
-     * are ok.
-     * @hide
-     */
-    public void close() {
-        mProfileConnector.disconnect();
-    }
-
-    private IBluetoothMapClient getService() {
-        return mProfileConnector.getService();
-    }
-
-    /**
-     * Returns true if the specified Bluetooth device is connected.
-     * Returns false if not connected, or if this proxy object is not
-     * currently connected to the Map service.
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean isConnected(BluetoothDevice device) {
-        if (VDBG) Log.d(TAG, "isConnected(" + device + ")");
-        final IBluetoothMapClient service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.isConnected(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Initiate connection. Initiation of outgoing connections is not
-     * supported for MAP server.
-     *
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public boolean connect(BluetoothDevice device) {
-        if (DBG) Log.d(TAG, "connect(" + device + ")" + "for MAPS MCE");
-        final IBluetoothMapClient service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.connect(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Initiate disconnect.
-     *
-     * @param device Remote Bluetooth Device
-     * @return false on error, true otherwise
-     *
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public boolean disconnect(BluetoothDevice device) {
-        if (DBG) Log.d(TAG, "disconnect(" + device + ")");
-        final IBluetoothMapClient service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.disconnect(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Get the list of connected devices. Currently at most one.
-     *
-     * @return list of connected devices
-     * @hide
-     */
-    @Override
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
-    public List<BluetoothDevice> getConnectedDevices() {
-        if (DBG) Log.d(TAG, "getConnectedDevices()");
-        final IBluetoothMapClient service = getService();
-        final List<BluetoothDevice> defaultValue = new ArrayList<>();
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<List<BluetoothDevice>> recv =
-                        new SynchronousResultReceiver();
-                service.getConnectedDevices(mAttributionSource, recv);
-                return Attributable.setAttributionSource(
-                        recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
-                        mAttributionSource);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Get the list of devices matching specified states. Currently at most one.
-     *
-     * @return list of matching devices
-     * @hide
-     */
-    @Override
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
-    public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
-        if (DBG) Log.d(TAG, "getDevicesMatchingStates()");
-        final IBluetoothMapClient service = getService();
-        final List<BluetoothDevice> defaultValue = new ArrayList<>();
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<List<BluetoothDevice>> recv =
-                        new SynchronousResultReceiver();
-                service.getDevicesMatchingConnectionStates(states, mAttributionSource, recv);
-                return Attributable.setAttributionSource(
-                        recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
-                        mAttributionSource);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Get connection state of device
-     *
-     * @return device connection state
-     * @hide
-     */
-    @Override
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
-    public int getConnectionState(BluetoothDevice device) {
-        if (DBG) Log.d(TAG, "getConnectionState(" + device + ")");
-        final IBluetoothMapClient service = getService();
-        final int defaultValue =  BluetoothProfile.STATE_DISCONNECTED;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver<>();
-                service.getConnectionState(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Set priority of the profile
-     *
-     * <p> The device should already be paired.
-     * Priority can be one of {@link #PRIORITY_ON} or {@link #PRIORITY_OFF},
-     *
-     * @param device Paired bluetooth device
-     * @param priority
-     * @return true if priority is set, false on error
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public boolean setPriority(BluetoothDevice device, int priority) {
-        if (DBG) Log.d(TAG, "setPriority(" + device + ", " + priority + ")");
-        return setConnectionPolicy(device, BluetoothAdapter.priorityToConnectionPolicy(priority));
-    }
-
-    /**
-     * Set connection policy of the profile
-     *
-     * <p> The device should already be paired.
-     * Connection policy can be one of {@link #CONNECTION_POLICY_ALLOWED},
-     * {@link #CONNECTION_POLICY_FORBIDDEN}, {@link #CONNECTION_POLICY_UNKNOWN}
-     *
-     * @param device Paired bluetooth device
-     * @param connectionPolicy is the connection policy to set to for this profile
-     * @return true if connectionPolicy is set, false on error
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public boolean setConnectionPolicy(@NonNull BluetoothDevice device,
-            @ConnectionPolicy int connectionPolicy) {
-        if (DBG) Log.d(TAG, "setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
-        final IBluetoothMapClient service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)
-                && (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_FORBIDDEN
-                    || connectionPolicy == BluetoothProfile.CONNECTION_POLICY_ALLOWED)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.setConnectionPolicy(device, connectionPolicy, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Get the priority of the profile.
-     *
-     * <p> The priority can be any of:
-     * {@link #PRIORITY_OFF}, {@link #PRIORITY_ON}, {@link #PRIORITY_UNDEFINED}
-     *
-     * @param device Bluetooth device
-     * @return priority of the device
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public int getPriority(BluetoothDevice device) {
-        if (VDBG) Log.d(TAG, "getPriority(" + device + ")");
-        return BluetoothAdapter.connectionPolicyToPriority(getConnectionPolicy(device));
-    }
-
-    /**
-     * Get the connection policy of the profile.
-     *
-     * <p> The connection policy can be any of:
-     * {@link #CONNECTION_POLICY_ALLOWED}, {@link #CONNECTION_POLICY_FORBIDDEN},
-     * {@link #CONNECTION_POLICY_UNKNOWN}
-     *
-     * @param device Bluetooth device
-     * @return connection policy of the device
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public @ConnectionPolicy int getConnectionPolicy(@NonNull BluetoothDevice device) {
-        if (VDBG) Log.d(TAG, "getConnectionPolicy(" + device + ")");
-        final IBluetoothMapClient service = getService();
-        final int defaultValue = BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
-                service.getConnectionPolicy(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Send a message.
-     *
-     * Send an SMS message to either the contacts primary number or the telephone number specified.
-     *
-     * @param device Bluetooth device
-     * @param contacts Uri Collection of the contacts
-     * @param message Message to be sent
-     * @param sentIntent intent issued when message is sent
-     * @param deliveredIntent intent issued when message is delivered
-     * @return true if the message is enqueued, false on error
-     * @hide
-     */
-    @SystemApi
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.SEND_SMS,
-    })
-    public boolean sendMessage(@NonNull BluetoothDevice device, @NonNull Collection<Uri> contacts,
-            @NonNull String message, @Nullable PendingIntent sentIntent,
-            @Nullable PendingIntent deliveredIntent) {
-        return sendMessage(device, contacts.toArray(new Uri[contacts.size()]), message, sentIntent,
-                deliveredIntent);
-    }
-
-     /**
-     * Send a message.
-     *
-     * Send an SMS message to either the contacts primary number or the telephone number specified.
-     *
-     * @param device Bluetooth device
-     * @param contacts Uri[] of the contacts
-     * @param message Message to be sent
-     * @param sentIntent intent issued when message is sent
-     * @param deliveredIntent intent issued when message is delivered
-     * @return true if the message is enqueued, false on error
-     * @hide
-     */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.SEND_SMS,
-    })
-    public boolean sendMessage(BluetoothDevice device, Uri[] contacts, String message,
-            PendingIntent sentIntent, PendingIntent deliveredIntent) {
-        if (DBG) Log.d(TAG, "sendMessage(" + device + ", " + contacts + ", " + message);
-        final IBluetoothMapClient service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.sendMessage(device, contacts, message, sentIntent, deliveredIntent,
-                        mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Get unread messages.  Unread messages will be published via {@link #ACTION_MESSAGE_RECEIVED}.
-     *
-     * @param device Bluetooth device
-     * @return true if the message is enqueued, false on error
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.READ_SMS,
-    })
-    public boolean getUnreadMessages(BluetoothDevice device) {
-        if (DBG) Log.d(TAG, "getUnreadMessages(" + device + ")");
-        final IBluetoothMapClient service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.getUnreadMessages(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Returns the "Uploading" feature bit value from the SDP record's
-     * MapSupportedFeatures field (see Bluetooth MAP 1.4 spec, page 114).
-     * @param device The Bluetooth device to get this value for.
-     * @return Returns true if the Uploading bit value in SDP record's
-     *         MapSupportedFeatures field is set. False is returned otherwise.
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean isUploadingSupported(BluetoothDevice device) {
-        if (DBG) Log.d(TAG, "isUploadingSupported(" + device + ")");
-        final IBluetoothMapClient service = getService();
-        final int defaultValue = 0;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
-                service.getSupportedFeatures(device, mAttributionSource, recv);
-                return (recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue)
-                        & UPLOADING_FEATURE_BITMASK) > 0;
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Set message status of message on MSE
-     * <p>
-     * When read status changed, the result will be published via
-     * {@link #ACTION_MESSAGE_READ_STATUS_CHANGED}
-     * When deleted status changed, the result will be published via
-     * {@link #ACTION_MESSAGE_DELETED_STATUS_CHANGED}
-     *
-     * @param device Bluetooth device
-     * @param handle message handle
-     * @param status <code>UNREAD</code> for "unread", <code>READ</code> for
-     *            "read", <code>UNDELETED</code> for "undeleted", <code>DELETED</code> for
-     *            "deleted", otherwise return error
-     * @return <code>true</code> if request has been sent, <code>false</code> on error
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.READ_SMS,
-    })
-    public boolean setMessageStatus(BluetoothDevice device, String handle, int status) {
-        if (DBG) Log.d(TAG, "setMessageStatus(" + device + ", " + handle + ", " + status + ")");
-        final IBluetoothMapClient service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device) && handle != null && (status == READ
-                    || status == UNREAD || status == UNDELETED  || status == DELETED)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.setMessageStatus(device, handle, status, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    private boolean isEnabled() {
-        return mAdapter.isEnabled();
-    }
-
-    private static boolean isValidDevice(BluetoothDevice device) {
-        return device != null && BluetoothAdapter.checkBluetoothAddress(device.getAddress());
-    }
-}
diff --git a/core/java/android/bluetooth/BluetoothMasInstance.java b/core/java/android/bluetooth/BluetoothMasInstance.java
deleted file mode 100644
index eeaf085..0000000
--- a/core/java/android/bluetooth/BluetoothMasInstance.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-import android.annotation.Nullable;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/** @hide */
-public final class BluetoothMasInstance implements Parcelable {
-    private final int mId;
-    private final String mName;
-    private final int mChannel;
-    private final int mMsgTypes;
-
-    public BluetoothMasInstance(int id, String name, int channel, int msgTypes) {
-        mId = id;
-        mName = name;
-        mChannel = channel;
-        mMsgTypes = msgTypes;
-    }
-
-    @Override
-    public boolean equals(@Nullable Object o) {
-        if (o instanceof BluetoothMasInstance) {
-            return mId == ((BluetoothMasInstance) o).mId;
-        }
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        return mId + (mChannel << 8) + (mMsgTypes << 16);
-    }
-
-    @Override
-    public String toString() {
-        return Integer.toString(mId) + ":" + mName + ":" + mChannel + ":"
-                + Integer.toHexString(mMsgTypes);
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    public static final @android.annotation.NonNull Parcelable.Creator<BluetoothMasInstance> CREATOR =
-            new Parcelable.Creator<BluetoothMasInstance>() {
-                public BluetoothMasInstance createFromParcel(Parcel in) {
-                    return new BluetoothMasInstance(in.readInt(), in.readString(),
-                            in.readInt(), in.readInt());
-                }
-
-                public BluetoothMasInstance[] newArray(int size) {
-                    return new BluetoothMasInstance[size];
-                }
-            };
-
-    @Override
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeInt(mId);
-        out.writeString(mName);
-        out.writeInt(mChannel);
-        out.writeInt(mMsgTypes);
-    }
-
-    public static final class MessageType {
-        public static final int EMAIL = 0x01;
-        public static final int SMS_GSM = 0x02;
-        public static final int SMS_CDMA = 0x04;
-        public static final int MMS = 0x08;
-    }
-
-    public int getId() {
-        return mId;
-    }
-
-    public String getName() {
-        return mName;
-    }
-
-    public int getChannel() {
-        return mChannel;
-    }
-
-    public int getMsgTypes() {
-        return mMsgTypes;
-    }
-
-    public boolean msgSupported(int msg) {
-        return (mMsgTypes & msg) != 0;
-    }
-}
diff --git a/core/java/android/bluetooth/BluetoothOutputStream.java b/core/java/android/bluetooth/BluetoothOutputStream.java
deleted file mode 100644
index ac2b3ed..0000000
--- a/core/java/android/bluetooth/BluetoothOutputStream.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2009 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.bluetooth;
-
-import android.annotation.SuppressLint;
-
-import java.io.IOException;
-import java.io.OutputStream;
-
-/**
- * BluetoothOutputStream.
- *
- * Used to read from a Bluetooth socket.
- *
- * @hide
- */
-@SuppressLint("AndroidFrameworkBluetoothPermission")
-/*package*/ final class BluetoothOutputStream extends OutputStream {
-    private BluetoothSocket mSocket;
-
-    /*package*/ BluetoothOutputStream(BluetoothSocket s) {
-        mSocket = s;
-    }
-
-    /**
-     * Close this output stream and the socket associated with it.
-     */
-    public void close() throws IOException {
-        mSocket.close();
-    }
-
-    /**
-     * Writes a single byte to this stream. Only the least significant byte of
-     * the integer {@code oneByte} is written to the stream.
-     *
-     * @param oneByte the byte to be written.
-     * @throws IOException if an error occurs while writing to this stream.
-     * @since Android 1.0
-     */
-    public void write(int oneByte) throws IOException {
-        byte[] b = new byte[1];
-        b[0] = (byte) oneByte;
-        mSocket.write(b, 0, 1);
-    }
-
-    /**
-     * Writes {@code count} bytes from the byte array {@code buffer} starting
-     * at position {@code offset} to this stream.
-     *
-     * @param b the buffer to be written.
-     * @param offset the start position in {@code buffer} from where to get bytes.
-     * @param count the number of bytes from {@code buffer} to write to this stream.
-     * @throws IOException if an error occurs while writing to this stream.
-     * @throws IndexOutOfBoundsException if {@code offset < 0} or {@code count < 0}, or if {@code
-     * offset + count} is bigger than the length of {@code buffer}.
-     * @since Android 1.0
-     */
-    public void write(byte[] b, int offset, int count) throws IOException {
-        if (b == null) {
-            throw new NullPointerException("buffer is null");
-        }
-        if ((offset | count) < 0 || count > b.length - offset) {
-            throw new IndexOutOfBoundsException("invalid offset or length");
-        }
-        mSocket.write(b, offset, count);
-    }
-}
diff --git a/core/java/android/bluetooth/BluetoothPan.java b/core/java/android/bluetooth/BluetoothPan.java
deleted file mode 100644
index d4ad4ef4..0000000
--- a/core/java/android/bluetooth/BluetoothPan.java
+++ /dev/null
@@ -1,525 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-import static android.bluetooth.BluetoothUtils.getSyncTimeout;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.RequiresPermission;
-import android.annotation.SdkConstant;
-import android.annotation.SdkConstant.SdkConstantType;
-import android.annotation.SuppressLint;
-import android.annotation.SystemApi;
-import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
-import android.bluetooth.annotations.RequiresLegacyBluetoothPermission;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.content.AttributionSource;
-import android.content.Context;
-import android.os.Build;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.util.Log;
-
-import com.android.modules.utils.SynchronousResultReceiver;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.TimeoutException;
-
-/**
- * This class provides the APIs to control the Bluetooth Pan
- * Profile.
- *
- * <p>BluetoothPan is a proxy object for controlling the Bluetooth
- * Service via IPC. Use {@link BluetoothAdapter#getProfileProxy} to get
- * the BluetoothPan proxy object.
- *
- * <p>Each method is protected with its appropriate permission.
- *
- * @hide
- */
-@SystemApi
-public final class BluetoothPan implements BluetoothProfile {
-    private static final String TAG = "BluetoothPan";
-    private static final boolean DBG = true;
-    private static final boolean VDBG = false;
-
-    /**
-     * Intent used to broadcast the change in connection state of the Pan
-     * profile.
-     *
-     * <p>This intent will have 4 extras:
-     * <ul>
-     * <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
-     * <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li>
-     * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
-     * <li> {@link #EXTRA_LOCAL_ROLE} - Which local role the remote device is
-     * bound to. </li>
-     * </ul>
-     *
-     * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
-     * {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTING},
-     * {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTING}.
-     *
-     * <p> {@link #EXTRA_LOCAL_ROLE} can be one of {@link #LOCAL_NAP_ROLE} or
-     * {@link #LOCAL_PANU_ROLE}
-     */
-    @SuppressLint("ActionValue")
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_CONNECTION_STATE_CHANGED =
-            "android.bluetooth.pan.profile.action.CONNECTION_STATE_CHANGED";
-
-    /**
-     * Extra for {@link #ACTION_CONNECTION_STATE_CHANGED} intent
-     * The local role of the PAN profile that the remote device is bound to.
-     * It can be one of {@link #LOCAL_NAP_ROLE} or {@link #LOCAL_PANU_ROLE}.
-     */
-    @SuppressLint("ActionValue")
-    public static final String EXTRA_LOCAL_ROLE = "android.bluetooth.pan.extra.LOCAL_ROLE";
-
-    /**
-     * Intent used to broadcast the change in tethering state of the Pan
-     * Profile
-     *
-     * <p>This intent will have 1 extra:
-     * <ul>
-     * <li> {@link #EXTRA_TETHERING_STATE} - The current state of Bluetooth
-     * tethering. </li>
-     * </ul>
-     *
-     * <p> {@link #EXTRA_TETHERING_STATE} can be any of {@link #TETHERING_STATE_OFF} or
-     * {@link #TETHERING_STATE_ON}
-     */
-    @RequiresLegacyBluetoothPermission
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_TETHERING_STATE_CHANGED =
-            "android.bluetooth.action.TETHERING_STATE_CHANGED";
-
-    /**
-     * Extra for {@link #ACTION_TETHERING_STATE_CHANGED} intent
-     * The tethering state of the PAN profile.
-     * It can be one of {@link #TETHERING_STATE_OFF} or {@link #TETHERING_STATE_ON}.
-     */
-    public static final String EXTRA_TETHERING_STATE =
-            "android.bluetooth.extra.TETHERING_STATE";
-
-    /** @hide */
-    @IntDef({PAN_ROLE_NONE, LOCAL_NAP_ROLE, LOCAL_PANU_ROLE})
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface LocalPanRole {}
-
-    public static final int PAN_ROLE_NONE = 0;
-    /**
-     * The local device is acting as a Network Access Point.
-     */
-    public static final int LOCAL_NAP_ROLE = 1;
-
-    /**
-     * The local device is acting as a PAN User.
-     */
-    public static final int LOCAL_PANU_ROLE = 2;
-
-    /** @hide */
-    @IntDef({PAN_ROLE_NONE, REMOTE_NAP_ROLE, REMOTE_PANU_ROLE})
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface RemotePanRole {}
-
-    public static final int REMOTE_NAP_ROLE = 1;
-
-    public static final int REMOTE_PANU_ROLE = 2;
-
-    /** @hide **/
-    @IntDef({TETHERING_STATE_OFF, TETHERING_STATE_ON})
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface TetheringState{}
-
-    public static final int TETHERING_STATE_OFF = 1;
-
-    public static final int TETHERING_STATE_ON = 2;
-    /**
-     * Return codes for the connect and disconnect Bluez / Dbus calls.
-     *
-     * @hide
-     */
-    public static final int PAN_DISCONNECT_FAILED_NOT_CONNECTED = 1000;
-
-    /**
-     * @hide
-     */
-    public static final int PAN_CONNECT_FAILED_ALREADY_CONNECTED = 1001;
-
-    /**
-     * @hide
-     */
-    public static final int PAN_CONNECT_FAILED_ATTEMPT_FAILED = 1002;
-
-    /**
-     * @hide
-     */
-    public static final int PAN_OPERATION_GENERIC_FAILURE = 1003;
-
-    /**
-     * @hide
-     */
-    public static final int PAN_OPERATION_SUCCESS = 1004;
-
-    private final Context mContext;
-
-    private final BluetoothAdapter mAdapter;
-    private final AttributionSource mAttributionSource;
-    private final BluetoothProfileConnector<IBluetoothPan> mProfileConnector =
-            new BluetoothProfileConnector(this, BluetoothProfile.PAN,
-                    "BluetoothPan", IBluetoothPan.class.getName()) {
-                @Override
-                public IBluetoothPan getServiceInterface(IBinder service) {
-                    return IBluetoothPan.Stub.asInterface(service);
-                }
-    };
-
-
-    /**
-     * Create a BluetoothPan proxy object for interacting with the local
-     * Bluetooth Service which handles the Pan profile
-     *
-     * @hide
-     */
-    @UnsupportedAppUsage
-    /* package */ BluetoothPan(Context context, ServiceListener listener,
-            BluetoothAdapter adapter) {
-        mAdapter = adapter;
-        mAttributionSource = adapter.getAttributionSource();
-        mContext = context;
-        mProfileConnector.connect(context, listener);
-    }
-
-    /**
-     * Closes the connection to the service and unregisters callbacks
-     */
-    @UnsupportedAppUsage
-    void close() {
-        if (VDBG) log("close()");
-        mProfileConnector.disconnect();
-    }
-
-    private IBluetoothPan getService() {
-        return mProfileConnector.getService();
-    }
-
-    /** @hide */
-    protected void finalize() {
-        close();
-    }
-
-    /**
-     * Initiate connection to a profile of the remote bluetooth device.
-     *
-     * <p> This API returns false in scenarios like the profile on the
-     * device is already connected or Bluetooth is not turned on.
-     * When this API returns true, it is guaranteed that
-     * connection state intent for the profile will be broadcasted with
-     * the state. Users can get the connection state of the profile
-     * from this intent.
-     *
-     * @param device Remote Bluetooth Device
-     * @return false on immediate error, true otherwise
-     * @hide
-     */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public boolean connect(BluetoothDevice device) {
-        if (DBG) log("connect(" + device + ")");
-        final IBluetoothPan service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.connect(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Initiate disconnection from a profile
-     *
-     * <p> This API will return false in scenarios like the profile on the
-     * Bluetooth device is not in connected state etc. When this API returns,
-     * true, it is guaranteed that the connection state change
-     * intent will be broadcasted with the state. Users can get the
-     * disconnection state of the profile from this intent.
-     *
-     * <p> If the disconnection is initiated by a remote device, the state
-     * will transition from {@link #STATE_CONNECTED} to
-     * {@link #STATE_DISCONNECTED}. If the disconnect is initiated by the
-     * host (local) device the state will transition from
-     * {@link #STATE_CONNECTED} to state {@link #STATE_DISCONNECTING} to
-     * state {@link #STATE_DISCONNECTED}. The transition to
-     * {@link #STATE_DISCONNECTING} can be used to distinguish between the
-     * two scenarios.
-     *
-     * @param device Remote Bluetooth Device
-     * @return false on immediate error, true otherwise
-     * @hide
-     */
-    @UnsupportedAppUsage
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean disconnect(BluetoothDevice device) {
-        if (DBG) log("disconnect(" + device + ")");
-        final IBluetoothPan service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.disconnect(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Set connection policy of the profile
-     *
-     * <p> The device should already be paired.
-     * Connection policy can be one of {@link #CONNECTION_POLICY_ALLOWED},
-     * {@link #CONNECTION_POLICY_FORBIDDEN}, {@link #CONNECTION_POLICY_UNKNOWN}
-     *
-     * @param device Paired bluetooth device
-     * @param connectionPolicy is the connection policy to set to for this profile
-     * @return true if connectionPolicy is set, false on error
-     * @hide
-     */
-    @SystemApi
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public boolean setConnectionPolicy(@NonNull BluetoothDevice device,
-            @ConnectionPolicy int connectionPolicy) {
-        if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
-        final IBluetoothPan service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)
-                && (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_FORBIDDEN
-                    || connectionPolicy == BluetoothProfile.CONNECTION_POLICY_ALLOWED)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.setConnectionPolicy(device, connectionPolicy, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * {@inheritDoc}
-     * @hide
-     */
-    @SystemApi
-    @Override
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public @NonNull List<BluetoothDevice> getConnectedDevices() {
-        if (VDBG) log("getConnectedDevices()");
-        final IBluetoothPan service = getService();
-        final List<BluetoothDevice> defaultValue = new ArrayList<BluetoothDevice>();
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<List<BluetoothDevice>> recv =
-                        new SynchronousResultReceiver();
-                service.getConnectedDevices(mAttributionSource, recv);
-                return Attributable.setAttributionSource(
-                        recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
-                        mAttributionSource);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * {@inheritDoc}
-     * @hide
-     */
-    @Override
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
-        if (VDBG) log("getDevicesMatchingStates()");
-        final IBluetoothPan service = getService();
-        final List<BluetoothDevice> defaultValue = new ArrayList<BluetoothDevice>();
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<List<BluetoothDevice>> recv =
-                        new SynchronousResultReceiver();
-                service.getDevicesMatchingConnectionStates(states, mAttributionSource, recv);
-                return Attributable.setAttributionSource(
-                        recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
-                        mAttributionSource);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * {@inheritDoc}
-     * @hide
-     */
-    @SystemApi
-    @Override
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public int getConnectionState(@NonNull BluetoothDevice device) {
-        if (VDBG) log("getState(" + device + ")");
-        final IBluetoothPan service = getService();
-        final int defaultValue = BluetoothProfile.STATE_DISCONNECTED;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
-                service.getConnectionState(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Turns on/off bluetooth tethering
-     *
-     * @param value is whether to enable or disable bluetooth tethering
-     * @hide
-     */
-    @SystemApi
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-            android.Manifest.permission.TETHER_PRIVILEGED,
-    })
-    public void setBluetoothTethering(boolean value) {
-        String pkgName = mContext.getOpPackageName();
-        if (DBG) log("setBluetoothTethering(" + value + "), calling package:" + pkgName);
-        final IBluetoothPan service = getService();
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver recv = new SynchronousResultReceiver();
-                service.setBluetoothTethering(value, mAttributionSource, recv);
-                recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(null);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-    }
-
-    /**
-     * Determines whether tethering is enabled
-     *
-     * @return true if tethering is on, false if not or some error occurred
-     * @hide
-     */
-    @SystemApi
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean isTetheringOn() {
-        if (VDBG) log("isTetheringOn()");
-        final IBluetoothPan service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.isTetheringOn(mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    @UnsupportedAppUsage
-    private boolean isEnabled() {
-        return mAdapter.getState() == BluetoothAdapter.STATE_ON;
-    }
-
-    @UnsupportedAppUsage
-    private static boolean isValidDevice(BluetoothDevice device) {
-        return device != null && BluetoothAdapter.checkBluetoothAddress(device.getAddress());
-    }
-
-    @UnsupportedAppUsage
-    private static void log(String msg) {
-        Log.d(TAG, msg);
-    }
-}
diff --git a/core/java/android/bluetooth/BluetoothPbap.java b/core/java/android/bluetooth/BluetoothPbap.java
deleted file mode 100644
index de2db9c..0000000
--- a/core/java/android/bluetooth/BluetoothPbap.java
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-import android.Manifest;
-import android.annotation.NonNull;
-import android.annotation.RequiresPermission;
-import android.annotation.SdkConstant;
-import android.annotation.SuppressLint;
-import android.annotation.SystemApi;
-import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.content.AttributionSource;
-import android.content.Context;
-import android.os.Build;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Public API for controlling the Bluetooth Pbap Service. This includes
- * Bluetooth Phone book Access profile.
- * BluetoothPbap is a proxy object for controlling the Bluetooth Pbap
- * Service via IPC.
- *
- * Creating a BluetoothPbap object will create a binding with the
- * BluetoothPbap service. Users of this object should call close() when they
- * are finished with the BluetoothPbap, so that this proxy object can unbind
- * from the service.
- *
- * This BluetoothPbap object is not immediately bound to the
- * BluetoothPbap service. Use the ServiceListener interface to obtain a
- * notification when it is bound, this is especially important if you wish to
- * immediately call methods on BluetoothPbap after construction.
- *
- * To get an instance of the BluetoothPbap class, you can call
- * {@link BluetoothAdapter#getProfileProxy(Context, ServiceListener, int)} with the final param
- * being {@link BluetoothProfile#PBAP}. The ServiceListener should be able to get the instance of
- * BluetoothPbap in {@link android.bluetooth.BluetoothProfile.ServiceListener#onServiceConnected}.
- *
- * Android only supports one connected Bluetooth Pce at a time.
- *
- * @hide
- */
-@SystemApi
-public class BluetoothPbap implements BluetoothProfile {
-
-    private static final String TAG = "BluetoothPbap";
-    private static final boolean DBG = false;
-
-    /**
-     * Intent used to broadcast the change in connection state of the PBAP
-     * profile.
-     *
-     * <p>This intent will have 3 extras:
-     * <ul>
-     * <li> {@link BluetoothProfile#EXTRA_STATE} - The current state of the profile. </li>
-     * <li> {@link BluetoothProfile#EXTRA_PREVIOUS_STATE}- The previous state of the profile. </li>
-     * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
-     * </ul>
-     * <p>{@link BluetoothProfile#EXTRA_STATE} or {@link BluetoothProfile#EXTRA_PREVIOUS_STATE}
-     *  can be any of {@link BluetoothProfile#STATE_DISCONNECTED},
-     *  {@link BluetoothProfile#STATE_CONNECTING}, {@link BluetoothProfile#STATE_CONNECTED},
-     *  {@link BluetoothProfile#STATE_DISCONNECTING}.
-     *
-     * @hide
-     */
-    @SuppressLint("ActionValue")
-    @SystemApi
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_CONNECTION_STATE_CHANGED =
-            "android.bluetooth.pbap.profile.action.CONNECTION_STATE_CHANGED";
-
-    private final AttributionSource mAttributionSource;
-
-    /** @hide */
-    public static final int RESULT_FAILURE = 0;
-    /** @hide */
-    public static final int RESULT_SUCCESS = 1;
-    /**
-     * Connection canceled before completion.
-     *
-     * @hide
-     */
-    public static final int RESULT_CANCELED = 2;
-
-    private BluetoothAdapter mAdapter;
-    private final BluetoothProfileConnector<IBluetoothPbap> mProfileConnector =
-            new BluetoothProfileConnector(this, BluetoothProfile.PBAP, "BluetoothPbap",
-                    IBluetoothPbap.class.getName()) {
-                @Override
-                public IBluetoothPbap getServiceInterface(IBinder service) {
-                    return IBluetoothPbap.Stub.asInterface(service);
-                }
-    };
-
-    /**
-     * Create a BluetoothPbap proxy object.
-     *
-     * @hide
-     */
-    public BluetoothPbap(Context context, ServiceListener listener, BluetoothAdapter adapter) {
-        mAdapter = adapter;
-        mAttributionSource = adapter.getAttributionSource();
-        mProfileConnector.connect(context, listener);
-    }
-
-    /** @hide */
-    protected void finalize() throws Throwable {
-        try {
-            close();
-        } finally {
-            super.finalize();
-        }
-    }
-
-    /**
-     * Close the connection to the backing service.
-     * Other public functions of BluetoothPbap will return default error
-     * results once close() has been called. Multiple invocations of close()
-     * are ok.
-     *
-     * @hide
-     */
-    public synchronized void close() {
-        mProfileConnector.disconnect();
-    }
-
-    private IBluetoothPbap getService() {
-        return (IBluetoothPbap) mProfileConnector.getService();
-    }
-
-    /**
-     * {@inheritDoc}
-     *
-     * @hide
-     */
-    @Override
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
-    public List<BluetoothDevice> getConnectedDevices() {
-        log("getConnectedDevices()");
-        final IBluetoothPbap service = getService();
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            return new ArrayList<BluetoothDevice>();
-        }
-        try {
-            return Attributable.setAttributionSource(
-                    service.getConnectedDevices(mAttributionSource), mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, e.toString());
-        }
-        return new ArrayList<BluetoothDevice>();
-    }
-
-    /**
-     * {@inheritDoc}
-     *
-     * @hide
-     */
-    @SystemApi
-    @Override
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public @BtProfileState int getConnectionState(@NonNull BluetoothDevice device) {
-        log("getConnectionState: device=" + device);
-        try {
-            final IBluetoothPbap service = getService();
-            if (service != null && isEnabled() && isValidDevice(device)) {
-                return service.getConnectionState(device, mAttributionSource);
-            }
-            if (service == null) {
-                Log.w(TAG, "Proxy not attached to service");
-            }
-            return BluetoothProfile.STATE_DISCONNECTED;
-        } catch (RemoteException e) {
-            Log.e(TAG, e.toString());
-        }
-        return BluetoothProfile.STATE_DISCONNECTED;
-    }
-
-    /**
-     * {@inheritDoc}
-     *
-     * @hide
-     */
-    @Override
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
-    public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
-        log("getDevicesMatchingConnectionStates: states=" + Arrays.toString(states));
-        final IBluetoothPbap service = getService();
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            return new ArrayList<BluetoothDevice>();
-        }
-        try {
-            return Attributable.setAttributionSource(
-                    service.getDevicesMatchingConnectionStates(states, mAttributionSource),
-                    mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, e.toString());
-        }
-        return new ArrayList<BluetoothDevice>();
-    }
-
-    /**
-     * Set connection policy of the profile and tries to disconnect it if connectionPolicy is
-     * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}
-     *
-     * <p> The device should already be paired.
-     * Connection policy can be one of:
-     * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED},
-     * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN},
-     * {@link BluetoothProfile#CONNECTION_POLICY_UNKNOWN}
-     *
-     * @param device Paired bluetooth device
-     * @param connectionPolicy is the connection policy to set to for this profile
-     * @return true if connectionPolicy is set, false on error
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public boolean setConnectionPolicy(@NonNull BluetoothDevice device,
-            @ConnectionPolicy int connectionPolicy) {
-        if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
-        try {
-            final IBluetoothPbap service = getService();
-            if (service != null && isEnabled()
-                    && isValidDevice(device)) {
-                if (connectionPolicy != BluetoothProfile.CONNECTION_POLICY_FORBIDDEN
-                        && connectionPolicy != BluetoothProfile.CONNECTION_POLICY_ALLOWED) {
-                    return false;
-                }
-                return service.setConnectionPolicy(device, connectionPolicy, mAttributionSource);
-            }
-            if (service == null) Log.w(TAG, "Proxy not attached to service");
-            return false;
-        } catch (RemoteException e) {
-            Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
-            return false;
-        }
-    }
-
-    /**
-     * Disconnects the current Pbap client (PCE). Currently this call blocks,
-     * it may soon be made asynchronous. Returns false if this proxy object is
-     * not currently connected to the Pbap service.
-     *
-     * @hide
-     */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean disconnect(BluetoothDevice device) {
-        log("disconnect()");
-        final IBluetoothPbap service = getService();
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            return false;
-        }
-        try {
-            service.disconnect(device, mAttributionSource);
-            return true;
-        } catch (RemoteException e) {
-            Log.e(TAG, e.toString());
-        }
-        return false;
-    }
-
-    private boolean isEnabled() {
-        if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true;
-        return false;
-    }
-
-    private boolean isValidDevice(BluetoothDevice device) {
-        if (device == null) return false;
-
-        if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
-        return false;
-    }
-
-    private static void log(String msg) {
-        if (DBG) {
-            Log.d(TAG, msg);
-        }
-    }
-}
diff --git a/core/java/android/bluetooth/BluetoothPbapClient.java b/core/java/android/bluetooth/BluetoothPbapClient.java
deleted file mode 100644
index e096de8..0000000
--- a/core/java/android/bluetooth/BluetoothPbapClient.java
+++ /dev/null
@@ -1,405 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-import static android.bluetooth.BluetoothUtils.getSyncTimeout;
-
-import android.Manifest;
-import android.annotation.NonNull;
-import android.annotation.RequiresPermission;
-import android.annotation.SdkConstant;
-import android.annotation.SdkConstant.SdkConstantType;
-import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
-import android.content.AttributionSource;
-import android.content.Context;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.util.Log;
-
-import com.android.modules.utils.SynchronousResultReceiver;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.TimeoutException;
-
-/**
- * This class provides the APIs to control the Bluetooth PBAP Client Profile.
- *
- * @hide
- */
-public final class BluetoothPbapClient implements BluetoothProfile {
-
-    private static final String TAG = "BluetoothPbapClient";
-    private static final boolean DBG = false;
-    private static final boolean VDBG = false;
-
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_CONNECTION_STATE_CHANGED =
-            "android.bluetooth.pbapclient.profile.action.CONNECTION_STATE_CHANGED";
-
-    /** There was an error trying to obtain the state */
-    public static final int STATE_ERROR = -1;
-
-    public static final int RESULT_FAILURE = 0;
-    public static final int RESULT_SUCCESS = 1;
-    /** Connection canceled before completion. */
-    public static final int RESULT_CANCELED = 2;
-
-    private final BluetoothAdapter mAdapter;
-    private final AttributionSource mAttributionSource;
-    private final BluetoothProfileConnector<IBluetoothPbapClient> mProfileConnector =
-            new BluetoothProfileConnector(this, BluetoothProfile.PBAP_CLIENT,
-                    "BluetoothPbapClient", IBluetoothPbapClient.class.getName()) {
-                @Override
-                public IBluetoothPbapClient getServiceInterface(IBinder service) {
-                    return IBluetoothPbapClient.Stub.asInterface(service);
-                }
-    };
-
-    /**
-     * Create a BluetoothPbapClient proxy object.
-     */
-    BluetoothPbapClient(Context context, ServiceListener listener, BluetoothAdapter adapter) {
-        if (DBG) {
-            Log.d(TAG, "Create BluetoothPbapClient proxy object");
-        }
-        mAdapter = adapter;
-        mAttributionSource = adapter.getAttributionSource();
-        mProfileConnector.connect(context, listener);
-    }
-
-    protected void finalize() throws Throwable {
-        try {
-            close();
-        } finally {
-            super.finalize();
-        }
-    }
-
-    /**
-     * Close the connection to the backing service.
-     * Other public functions of BluetoothPbapClient will return default error
-     * results once close() has been called. Multiple invocations of close()
-     * are ok.
-     */
-    public synchronized void close() {
-        mProfileConnector.disconnect();
-    }
-
-    private IBluetoothPbapClient getService() {
-        return mProfileConnector.getService();
-    }
-
-    /**
-     * Initiate connection.
-     * Upon successful connection to remote PBAP server the Client will
-     * attempt to automatically download the users phonebook and call log.
-     *
-     * @param device a remote device we want connect to
-     * @return <code>true</code> if command has been issued successfully; <code>false</code>
-     * otherwise;
-     *
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public boolean connect(BluetoothDevice device) {
-        if (DBG) {
-            log("connect(" + device + ") for PBAP Client.");
-        }
-        final IBluetoothPbapClient service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.connect(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Initiate disconnect.
-     *
-     * @param device Remote Bluetooth Device
-     * @return false on error, true otherwise
-     *
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public boolean disconnect(BluetoothDevice device) {
-        if (DBG) {
-            log("disconnect(" + device + ")" + new Exception());
-        }
-        final IBluetoothPbapClient service = getService();
-        final boolean defaultValue = true;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.disconnect(device, mAttributionSource, recv);
-                recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-                return true;
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Get the list of connected devices.
-     * Currently at most one.
-     *
-     * @return list of connected devices
-     */
-    @Override
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
-    public List<BluetoothDevice> getConnectedDevices() {
-        if (DBG) {
-            log("getConnectedDevices()");
-        }
-        final IBluetoothPbapClient service = getService();
-        final List<BluetoothDevice> defaultValue = new ArrayList<BluetoothDevice>();
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<List<BluetoothDevice>> recv =
-                        new SynchronousResultReceiver();
-                service.getConnectedDevices(mAttributionSource, recv);
-                return Attributable.setAttributionSource(
-                        recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
-                        mAttributionSource);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Get the list of devices matching specified states. Currently at most one.
-     *
-     * @return list of matching devices
-     */
-    @Override
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
-    public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
-        if (DBG) {
-            log("getDevicesMatchingStates()");
-        }
-        final IBluetoothPbapClient service = getService();
-        final List<BluetoothDevice> defaultValue = new ArrayList<BluetoothDevice>();
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<List<BluetoothDevice>> recv =
-                        new SynchronousResultReceiver();
-                service.getDevicesMatchingConnectionStates(states, mAttributionSource, recv);
-                return Attributable.setAttributionSource(
-                        recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
-                        mAttributionSource);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Get connection state of device
-     *
-     * @return device connection state
-     */
-    @Override
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
-    public int getConnectionState(BluetoothDevice device) {
-        if (DBG) {
-            log("getConnectionState(" + device + ")");
-        }
-        final IBluetoothPbapClient service = getService();
-        final int defaultValue = BluetoothProfile.STATE_DISCONNECTED;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
-                service.getConnectionState(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    private static void log(String msg) {
-        Log.d(TAG, msg);
-    }
-
-    private boolean isEnabled() {
-        return mAdapter.isEnabled();
-    }
-
-    private static boolean isValidDevice(BluetoothDevice device) {
-        return device != null && BluetoothAdapter.checkBluetoothAddress(device.getAddress());
-    }
-
-    /**
-     * Set priority of the profile
-     *
-     * <p> The device should already be paired.
-     * Priority can be one of {@link #PRIORITY_ON} or {@link #PRIORITY_OFF},
-     *
-     * @param device Paired bluetooth device
-     * @param priority
-     * @return true if priority is set, false on error
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public boolean setPriority(BluetoothDevice device, int priority) {
-        if (DBG) log("setPriority(" + device + ", " + priority + ")");
-        return setConnectionPolicy(device, BluetoothAdapter.priorityToConnectionPolicy(priority));
-    }
-
-    /**
-     * Set connection policy of the profile
-     *
-     * <p> The device should already be paired.
-     * Connection policy can be one of {@link #CONNECTION_POLICY_ALLOWED},
-     * {@link #CONNECTION_POLICY_FORBIDDEN}, {@link #CONNECTION_POLICY_UNKNOWN}
-     *
-     * @param device Paired bluetooth device
-     * @param connectionPolicy is the connection policy to set to for this profile
-     * @return true if connectionPolicy is set, false on error
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public boolean setConnectionPolicy(@NonNull BluetoothDevice device,
-            @ConnectionPolicy int connectionPolicy) {
-        if (DBG) {
-            log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
-        }
-        final IBluetoothPbapClient service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)
-                && (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_FORBIDDEN
-                    || connectionPolicy == BluetoothProfile.CONNECTION_POLICY_ALLOWED)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.setConnectionPolicy(device, connectionPolicy, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Get the priority of the profile.
-     *
-     * <p> The priority can be any of:
-     * {@link #PRIORITY_OFF}, {@link #PRIORITY_ON}, {@link #PRIORITY_UNDEFINED}
-     *
-     * @param device Bluetooth device
-     * @return priority of the device
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public int getPriority(BluetoothDevice device) {
-        if (VDBG) log("getPriority(" + device + ")");
-        return BluetoothAdapter.connectionPolicyToPriority(getConnectionPolicy(device));
-    }
-
-    /**
-     * Get the connection policy of the profile.
-     *
-     * <p> The connection policy can be any of:
-     * {@link #CONNECTION_POLICY_ALLOWED}, {@link #CONNECTION_POLICY_FORBIDDEN},
-     * {@link #CONNECTION_POLICY_UNKNOWN}
-     *
-     * @param device Bluetooth device
-     * @return connection policy of the device
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public @ConnectionPolicy int getConnectionPolicy(@NonNull BluetoothDevice device) {
-        if (VDBG) {
-            log("getConnectionPolicy(" + device + ")");
-        }
-        final IBluetoothPbapClient service = getService();
-        final int defaultValue = BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
-                service.getConnectionPolicy(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-}
diff --git a/core/java/android/bluetooth/BluetoothProfile.java b/core/java/android/bluetooth/BluetoothProfile.java
deleted file mode 100644
index d0f74e9..0000000
--- a/core/java/android/bluetooth/BluetoothProfile.java
+++ /dev/null
@@ -1,459 +0,0 @@
-/*
- * Copyright (C) 2010-2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-import android.annotation.IntDef;
-import android.annotation.RequiresNoPermission;
-import android.annotation.SuppressLint;
-import android.annotation.SystemApi;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.os.Build;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.List;
-
-/**
- * Public APIs for the Bluetooth Profiles.
- *
- * <p> Clients should call {@link BluetoothAdapter#getProfileProxy},
- * to get the Profile Proxy. Each public profile implements this
- * interface.
- */
-public interface BluetoothProfile {
-
-    /**
-     * Extra for the connection state intents of the individual profiles.
-     *
-     * This extra represents the current connection state of the profile of the
-     * Bluetooth device.
-     */
-    @SuppressLint("ActionValue")
-    String EXTRA_STATE = "android.bluetooth.profile.extra.STATE";
-
-    /**
-     * Extra for the connection state intents of the individual profiles.
-     *
-     * This extra represents the previous connection state of the profile of the
-     * Bluetooth device.
-     */
-    @SuppressLint("ActionValue")
-    String EXTRA_PREVIOUS_STATE =
-            "android.bluetooth.profile.extra.PREVIOUS_STATE";
-
-    /** The profile is in disconnected state */
-    int STATE_DISCONNECTED = 0;
-    /** The profile is in connecting state */
-    int STATE_CONNECTING = 1;
-    /** The profile is in connected state */
-    int STATE_CONNECTED = 2;
-    /** The profile is in disconnecting state */
-    int STATE_DISCONNECTING = 3;
-
-    /** @hide */
-    @IntDef({
-            STATE_DISCONNECTED,
-            STATE_CONNECTING,
-            STATE_CONNECTED,
-            STATE_DISCONNECTING,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface BtProfileState {}
-
-    /**
-     * Headset and Handsfree profile
-     */
-    int HEADSET = 1;
-
-    /**
-     * A2DP profile.
-     */
-    int A2DP = 2;
-
-    /**
-     * Health Profile
-     *
-     * @deprecated Health Device Profile (HDP) and MCAP protocol are no longer used. New
-     * apps should use Bluetooth Low Energy based solutions such as {@link BluetoothGatt},
-     * {@link BluetoothAdapter#listenUsingL2capChannel()}, or
-     * {@link BluetoothDevice#createL2capChannel(int)}
-     */
-    @Deprecated
-    int HEALTH = 3;
-
-    /**
-     * HID Host
-     *
-     * @hide
-     */
-    int HID_HOST = 4;
-
-    /**
-     * PAN Profile
-     *
-     * @hide
-     */
-    @SystemApi
-    int PAN = 5;
-
-    /**
-     * PBAP
-     *
-     * @hide
-     */
-    int PBAP = 6;
-
-    /**
-     * GATT
-     */
-    int GATT = 7;
-
-    /**
-     * GATT_SERVER
-     */
-    int GATT_SERVER = 8;
-
-    /**
-     * MAP Profile
-     *
-     * @hide
-     */
-    int MAP = 9;
-
-    /*
-     * SAP Profile
-     * @hide
-     */
-    int SAP = 10;
-
-    /**
-     * A2DP Sink Profile
-     *
-     * @hide
-     */
-    @SystemApi
-    int A2DP_SINK = 11;
-
-    /**
-     * AVRCP Controller Profile
-     *
-     * @hide
-     */
-    @SystemApi
-    int AVRCP_CONTROLLER = 12;
-
-    /**
-     * AVRCP Target Profile
-     *
-     * @hide
-     */
-    int AVRCP = 13;
-
-    /**
-     * Headset Client - HFP HF Role
-     *
-     * @hide
-     */
-    @SystemApi
-    int HEADSET_CLIENT = 16;
-
-    /**
-     * PBAP Client
-     *
-     * @hide
-     */
-    @SystemApi
-    int PBAP_CLIENT = 17;
-
-    /**
-     * MAP Messaging Client Equipment (MCE)
-     *
-     * @hide
-     */
-    @SystemApi
-    int MAP_CLIENT = 18;
-
-    /**
-     * HID Device
-     */
-    int HID_DEVICE = 19;
-
-    /**
-     * Object Push Profile (OPP)
-     *
-     * @hide
-     */
-    int OPP = 20;
-
-    /**
-     * Hearing Aid Device
-     *
-     */
-    int HEARING_AID = 21;
-
-    /**
-     * LE Audio Device
-     *
-     */
-    int LE_AUDIO = 22;
-
-    /**
-     * Volume Control profile
-     *
-     * @hide
-     */
-    @SystemApi
-    int VOLUME_CONTROL = 23;
-
-    /**
-     * @hide
-     * Media Control Profile server
-     *
-     */
-    int MCP_SERVER = 24;
-
-    /**
-     * Coordinated Set Identification Profile set coordinator
-     *
-     */
-    int CSIP_SET_COORDINATOR = 25;
-
-    /**
-     * LE Audio Broadcast Source
-     *
-     * @hide
-     */
-    int LE_AUDIO_BROADCAST = 26;
-
-    /**
-     * @hide
-     * Telephone Bearer Service from Call Control Profile
-     *
-     */
-    int LE_CALL_CONTROL = 27;
-
-    /**
-     * Max profile ID. This value should be updated whenever a new profile is added to match
-     * the largest value assigned to a profile.
-     *
-     * @hide
-     */
-    int MAX_PROFILE_ID = 27;
-
-    /**
-     * Default priority for devices that we try to auto-connect to and
-     * and allow incoming connections for the profile
-     *
-     * @hide
-     **/
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    int PRIORITY_AUTO_CONNECT = 1000;
-
-    /**
-     * Default priority for devices that allow incoming
-     * and outgoing connections for the profile
-     *
-     * @hide
-     * @deprecated Replaced with {@link #CONNECTION_POLICY_ALLOWED}
-     **/
-    @Deprecated
-    @SystemApi
-    int PRIORITY_ON = 100;
-
-    /**
-     * Default priority for devices that does not allow incoming
-     * connections and outgoing connections for the profile.
-     *
-     * @hide
-     * @deprecated Replaced with {@link #CONNECTION_POLICY_FORBIDDEN}
-     **/
-    @Deprecated
-    @SystemApi
-    int PRIORITY_OFF = 0;
-
-    /**
-     * Default priority when not set or when the device is unpaired
-     *
-     * @hide
-     */
-    @UnsupportedAppUsage
-    int PRIORITY_UNDEFINED = -1;
-
-    /** @hide */
-    @IntDef(prefix = "CONNECTION_POLICY_", value = {CONNECTION_POLICY_ALLOWED,
-            CONNECTION_POLICY_FORBIDDEN, CONNECTION_POLICY_UNKNOWN})
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface ConnectionPolicy{}
-
-    /**
-     * Default connection policy for devices that allow incoming and outgoing connections
-     * for the profile
-     *
-     * @hide
-     **/
-    @SystemApi
-    int CONNECTION_POLICY_ALLOWED = 100;
-
-    /**
-     * Default connection policy for devices that do not allow incoming or outgoing connections
-     * for the profile.
-     *
-     * @hide
-     **/
-    @SystemApi
-    int CONNECTION_POLICY_FORBIDDEN = 0;
-
-    /**
-     * Default connection policy when not set or when the device is unpaired
-     *
-     * @hide
-     */
-    @SystemApi
-    int CONNECTION_POLICY_UNKNOWN = -1;
-
-    /**
-     * Get connected devices for this specific profile.
-     *
-     * <p> Return the set of devices which are in state {@link #STATE_CONNECTED}
-     *
-     * @return List of devices. The list will be empty on error.
-     */
-    public List<BluetoothDevice> getConnectedDevices();
-
-    /**
-     * Get a list of devices that match any of the given connection
-     * states.
-     *
-     * <p> If none of the devices match any of the given states,
-     * an empty list will be returned.
-     *
-     * @param states Array of states. States can be one of {@link #STATE_CONNECTED}, {@link
-     * #STATE_CONNECTING}, {@link #STATE_DISCONNECTED}, {@link #STATE_DISCONNECTING},
-     * @return List of devices. The list will be empty on error.
-     */
-    public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states);
-
-    /**
-     * Get the current connection state of the profile
-     *
-     * @param device Remote bluetooth device.
-     * @return State of the profile connection. One of {@link #STATE_CONNECTED}, {@link
-     * #STATE_CONNECTING}, {@link #STATE_DISCONNECTED}, {@link #STATE_DISCONNECTING}
-     */
-    @BtProfileState int getConnectionState(BluetoothDevice device);
-
-    /**
-     * An interface for notifying BluetoothProfile IPC clients when they have
-     * been connected or disconnected to the service.
-     */
-    public interface ServiceListener {
-        /**
-         * Called to notify the client when the proxy object has been
-         * connected to the service.
-         *
-         * @param profile - One of {@link #HEADSET} or {@link #A2DP}
-         * @param proxy - One of {@link BluetoothHeadset} or {@link BluetoothA2dp}
-         */
-        @RequiresNoPermission
-        public void onServiceConnected(int profile, BluetoothProfile proxy);
-
-        /**
-         * Called to notify the client that this proxy object has been
-         * disconnected from the service.
-         *
-         * @param profile - One of {@link #HEADSET} or {@link #A2DP}
-         */
-        @RequiresNoPermission
-        public void onServiceDisconnected(int profile);
-    }
-
-    /**
-     * Convert an integer value of connection state into human readable string
-     *
-     * @param connectionState - One of {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTING},
-     * {@link #STATE_CONNECTED}, or {@link #STATE_DISCONNECTED}
-     * @return a string representation of the connection state, STATE_UNKNOWN if the state
-     * is not defined
-     * @hide
-     */
-    static String getConnectionStateName(int connectionState) {
-        switch (connectionState) {
-            case STATE_DISCONNECTED:
-                return "STATE_DISCONNECTED";
-            case STATE_CONNECTING:
-                return "STATE_CONNECTING";
-            case STATE_CONNECTED:
-                return "STATE_CONNECTED";
-            case STATE_DISCONNECTING:
-                return "STATE_DISCONNECTING";
-            default:
-                return "STATE_UNKNOWN";
-        }
-    }
-
-    /**
-     * Convert an integer value of profile ID into human readable string
-     *
-     * @param profile profile ID
-     * @return profile name as String, UNKOWN_PROFILE if the profile ID is not defined.
-     * @hide
-     */
-    static String getProfileName(int profile) {
-        switch(profile) {
-            case HEADSET:
-                return "HEADSET";
-            case A2DP:
-                return "A2DP";
-            case HID_HOST:
-                return "HID_HOST";
-            case PAN:
-                return "PAN";
-            case PBAP:
-                return "PBAP";
-            case GATT:
-                return "GATT";
-            case GATT_SERVER:
-                return "GATT_SERVER";
-            case MAP:
-                return "MAP";
-            case SAP:
-                return "SAP";
-            case A2DP_SINK:
-                return "A2DP_SINK";
-            case AVRCP_CONTROLLER:
-                return "AVRCP_CONTROLLER";
-            case AVRCP:
-                return "AVRCP";
-            case HEADSET_CLIENT:
-                return "HEADSET_CLIENT";
-            case PBAP_CLIENT:
-                return "PBAP_CLIENT";
-            case MAP_CLIENT:
-                return "MAP_CLIENT";
-            case HID_DEVICE:
-                return "HID_DEVICE";
-            case OPP:
-                return "OPP";
-            case HEARING_AID:
-                return "HEARING_AID";
-            case LE_AUDIO:
-                return "LE_AUDIO";
-            default:
-                return "UNKNOWN_PROFILE";
-        }
-    }
-}
diff --git a/core/java/android/bluetooth/BluetoothProfileConnector.java b/core/java/android/bluetooth/BluetoothProfileConnector.java
deleted file mode 100644
index 79373f1a..0000000
--- a/core/java/android/bluetooth/BluetoothProfileConnector.java
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SuppressLint;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.os.Build;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.os.UserHandle;
-import android.util.CloseGuard;
-import android.util.Log;
-
-import java.util.List;
-/**
- * Connector for Bluetooth profile proxies to bind manager service and
- * profile services
- * @param <T> The Bluetooth profile interface for this connection.
- * @hide
- */
-@SuppressLint("AndroidFrameworkBluetoothPermission")
-public abstract class BluetoothProfileConnector<T> {
-    private final CloseGuard mCloseGuard = new CloseGuard();
-    private final int mProfileId;
-    private BluetoothProfile.ServiceListener mServiceListener;
-    private final BluetoothProfile mProfileProxy;
-    private Context mContext;
-    private final String mProfileName;
-    private final String mServiceName;
-    private volatile T mService;
-
-    private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
-            new IBluetoothStateChangeCallback.Stub() {
-        public void onBluetoothStateChange(boolean up) {
-            if (up) {
-                doBind();
-            } else {
-                doUnbind();
-            }
-        }
-    };
-
-    private @Nullable ComponentName resolveSystemService(@NonNull Intent intent,
-            @NonNull PackageManager pm, @PackageManager.ComponentInfoFlags int flags) {
-        List<ResolveInfo> results = pm.queryIntentServices(intent, flags);
-        if (results == null) {
-            return null;
-        }
-        ComponentName comp = null;
-        for (int i = 0; i < results.size(); i++) {
-            ResolveInfo ri = results.get(i);
-            if ((ri.serviceInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
-                continue;
-            }
-            ComponentName foundComp = new ComponentName(ri.serviceInfo.applicationInfo.packageName,
-                    ri.serviceInfo.name);
-            if (comp != null) {
-                throw new IllegalStateException("Multiple system services handle " + intent
-                        + ": " + comp + ", " + foundComp);
-            }
-            comp = foundComp;
-        }
-        return comp;
-    }
-
-    private final ServiceConnection mConnection = new ServiceConnection() {
-        public void onServiceConnected(ComponentName className, IBinder service) {
-            logDebug("Proxy object connected");
-            mService = getServiceInterface(service);
-
-            if (mServiceListener != null) {
-                mServiceListener.onServiceConnected(mProfileId, mProfileProxy);
-            }
-        }
-
-        public void onServiceDisconnected(ComponentName className) {
-            logDebug("Proxy object disconnected");
-            doUnbind();
-            if (mServiceListener != null) {
-                mServiceListener.onServiceDisconnected(mProfileId);
-            }
-        }
-    };
-
-    BluetoothProfileConnector(BluetoothProfile profile, int profileId, String profileName,
-            String serviceName) {
-        mProfileId = profileId;
-        mProfileProxy = profile;
-        mProfileName = profileName;
-        mServiceName = serviceName;
-    }
-
-    /** {@hide} */
-    @Override
-    public void finalize() {
-        mCloseGuard.warnIfOpen();
-        doUnbind();
-    }
-
-    @SuppressLint("AndroidFrameworkRequiresPermission")
-    private boolean doBind() {
-        synchronized (mConnection) {
-            if (mService == null) {
-                logDebug("Binding service...");
-                mCloseGuard.open("doUnbind");
-                try {
-                    Intent intent = new Intent(mServiceName);
-                    ComponentName comp = resolveSystemService(intent, mContext.getPackageManager(),
-                            0);
-                    intent.setComponent(comp);
-                    if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
-                            UserHandle.CURRENT)) {
-                        logError("Could not bind to Bluetooth Service with " + intent);
-                        return false;
-                    }
-                } catch (SecurityException se) {
-                    logError("Failed to bind service. " + se);
-                    return false;
-                }
-            }
-        }
-        return true;
-    }
-
-    private void doUnbind() {
-        synchronized (mConnection) {
-            if (mService != null) {
-                logDebug("Unbinding service...");
-                mCloseGuard.close();
-                try {
-                    mContext.unbindService(mConnection);
-                } catch (IllegalArgumentException ie) {
-                    logError("Unable to unbind service: " + ie);
-                } finally {
-                    mService = null;
-                }
-            }
-        }
-    }
-
-    void connect(Context context, BluetoothProfile.ServiceListener listener) {
-        mContext = context;
-        mServiceListener = listener;
-        IBluetoothManager mgr = BluetoothAdapter.getDefaultAdapter().getBluetoothManager();
-
-        // Preserve legacy compatibility where apps were depending on
-        // registerStateChangeCallback() performing a permissions check which
-        // has been relaxed in modern platform versions
-        if (context.getApplicationInfo().targetSdkVersion <= Build.VERSION_CODES.R
-                && context.checkSelfPermission(android.Manifest.permission.BLUETOOTH)
-                        != PackageManager.PERMISSION_GRANTED) {
-            throw new SecurityException("Need BLUETOOTH permission");
-        }
-
-        if (mgr != null) {
-            try {
-                mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
-            } catch (RemoteException re) {
-                logError("Failed to register state change callback. " + re);
-            }
-        }
-        doBind();
-    }
-
-    void disconnect() {
-        mServiceListener = null;
-        IBluetoothManager mgr = BluetoothAdapter.getDefaultAdapter().getBluetoothManager();
-        if (mgr != null) {
-            try {
-                mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
-            } catch (RemoteException re) {
-                logError("Failed to unregister state change callback" + re);
-            }
-        }
-        doUnbind();
-    }
-
-    T getService() {
-        return mService;
-    }
-
-    /**
-     * This abstract function is used to implement method to get the
-     * connected Bluetooth service interface.
-     * @param service the connected binder service.
-     * @return T the binder interface of {@code service}.
-     * @hide
-     */
-    public abstract T getServiceInterface(IBinder service);
-
-    private void logDebug(String log) {
-        Log.d(mProfileName, log);
-    }
-
-    private void logError(String log) {
-        Log.e(mProfileName, log);
-    }
-}
diff --git a/core/java/android/bluetooth/BluetoothSap.java b/core/java/android/bluetooth/BluetoothSap.java
deleted file mode 100644
index 808fa39..0000000
--- a/core/java/android/bluetooth/BluetoothSap.java
+++ /dev/null
@@ -1,491 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-import static android.bluetooth.BluetoothUtils.getSyncTimeout;
-
-import android.Manifest;
-import android.annotation.RequiresNoPermission;
-import android.annotation.RequiresPermission;
-import android.annotation.SdkConstant;
-import android.annotation.SdkConstant.SdkConstantType;
-import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
-import android.bluetooth.annotations.RequiresLegacyBluetoothPermission;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.content.AttributionSource;
-import android.content.Context;
-import android.os.Build;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.util.Log;
-
-import com.android.modules.utils.SynchronousResultReceiver;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.TimeoutException;
-
-/**
- * This class provides the APIs to control the Bluetooth SIM
- * Access Profile (SAP).
- *
- * <p>BluetoothSap is a proxy object for controlling the Bluetooth
- * Service via IPC. Use {@link BluetoothAdapter#getProfileProxy} to get
- * the BluetoothSap proxy object.
- *
- * <p>Each method is protected with its appropriate permission.
- *
- * @hide
- */
-public final class BluetoothSap implements BluetoothProfile {
-
-    private static final String TAG = "BluetoothSap";
-    private static final boolean DBG = true;
-    private static final boolean VDBG = false;
-
-    /**
-     * Intent used to broadcast the change in connection state of the profile.
-     *
-     * <p>This intent will have 4 extras:
-     * <ul>
-     * <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
-     * <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li>
-     * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
-     * </ul>
-     *
-     * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
-     * {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTING},
-     * {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTING}.
-     *
-     * @hide
-     */
-    @RequiresLegacyBluetoothPermission
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_CONNECTION_STATE_CHANGED =
-            "android.bluetooth.sap.profile.action.CONNECTION_STATE_CHANGED";
-
-    /**
-     * There was an error trying to obtain the state.
-     *
-     * @hide
-     */
-    public static final int STATE_ERROR = -1;
-
-    /**
-     * Connection state change succceeded.
-     *
-     * @hide
-     */
-    public static final int RESULT_SUCCESS = 1;
-
-    /**
-     * Connection canceled before completion.
-     *
-     * @hide
-     */
-    public static final int RESULT_CANCELED = 2;
-
-    private final BluetoothAdapter mAdapter;
-    private final AttributionSource mAttributionSource;
-    private final BluetoothProfileConnector<IBluetoothSap> mProfileConnector =
-            new BluetoothProfileConnector(this, BluetoothProfile.SAP,
-                    "BluetoothSap", IBluetoothSap.class.getName()) {
-                @Override
-                public IBluetoothSap getServiceInterface(IBinder service) {
-                    return IBluetoothSap.Stub.asInterface(service);
-                }
-    };
-
-    /**
-     * Create a BluetoothSap proxy object.
-     */
-    /* package */ BluetoothSap(Context context, ServiceListener listener,
-            BluetoothAdapter adapter) {
-        if (DBG) Log.d(TAG, "Create BluetoothSap proxy object");
-        mAdapter = adapter;
-        mAttributionSource = adapter.getAttributionSource();
-        mProfileConnector.connect(context, listener);
-    }
-
-    protected void finalize() throws Throwable {
-        try {
-            close();
-        } finally {
-            super.finalize();
-        }
-    }
-
-    /**
-     * Close the connection to the backing service.
-     * Other public functions of BluetoothSap will return default error
-     * results once close() has been called. Multiple invocations of close()
-     * are ok.
-     *
-     * @hide
-     */
-    public synchronized void close() {
-        mProfileConnector.disconnect();
-    }
-
-    private IBluetoothSap getService() {
-        return mProfileConnector.getService();
-    }
-
-    /**
-     * Get the current state of the BluetoothSap service.
-     *
-     * @return One of the STATE_ return codes, or STATE_ERROR if this proxy object is currently not
-     * connected to the Sap service.
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public int getState() {
-        if (VDBG) log("getState()");
-        final IBluetoothSap service = getService();
-        final int defaultValue = BluetoothSap.STATE_ERROR;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
-                service.getState(mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Get the currently connected remote Bluetooth device (PCE).
-     *
-     * @return The remote Bluetooth device, or null if not in connected or connecting state, or if
-     * this proxy object is not connected to the Sap service.
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public BluetoothDevice getClient() {
-        if (VDBG) log("getClient()");
-        final IBluetoothSap service = getService();
-        final BluetoothDevice defaultValue = null;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<BluetoothDevice> recv =
-                        new SynchronousResultReceiver();
-                service.getClient(mAttributionSource, recv);
-                return Attributable.setAttributionSource(
-                        recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
-                        mAttributionSource);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Returns true if the specified Bluetooth device is connected.
-     * Returns false if not connected, or if this proxy object is not
-     * currently connected to the Sap service.
-     *
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean isConnected(BluetoothDevice device) {
-        if (VDBG) log("isConnected(" + device + ")");
-        final IBluetoothSap service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.isConnected(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Initiate connection. Initiation of outgoing connections is not
-     * supported for SAP server.
-     *
-     * @hide
-     */
-    @RequiresNoPermission
-    public boolean connect(BluetoothDevice device) {
-        if (DBG) log("connect(" + device + ")" + "not supported for SAPS");
-        return false;
-    }
-
-    /**
-     * Initiate disconnect.
-     *
-     * @param device Remote Bluetooth Device
-     * @return false on error, true otherwise
-     * @hide
-     */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public boolean disconnect(BluetoothDevice device) {
-        if (DBG) log("disconnect(" + device + ")");
-        final IBluetoothSap service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.disconnect(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Get the list of connected devices. Currently at most one.
-     *
-     * @return list of connected devices
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
-    public List<BluetoothDevice> getConnectedDevices() {
-        if (DBG) log("getConnectedDevices()");
-        final IBluetoothSap service = getService();
-        final List<BluetoothDevice> defaultValue = new ArrayList<BluetoothDevice>();
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<List<BluetoothDevice>> recv =
-                        new SynchronousResultReceiver();
-                service.getConnectedDevices(mAttributionSource, recv);
-                return Attributable.setAttributionSource(
-                        recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
-                        mAttributionSource);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Get the list of devices matching specified states. Currently at most one.
-     *
-     * @return list of matching devices
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
-    public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
-        if (DBG) log("getDevicesMatchingStates()");
-        final IBluetoothSap service = getService();
-        final List<BluetoothDevice> defaultValue = new ArrayList<BluetoothDevice>();
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<List<BluetoothDevice>> recv =
-                        new SynchronousResultReceiver();
-                service.getDevicesMatchingConnectionStates(states, mAttributionSource, recv);
-                return Attributable.setAttributionSource(
-                        recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
-                        mAttributionSource);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Get connection state of device
-     *
-     * @return device connection state
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
-    public int getConnectionState(BluetoothDevice device) {
-        if (DBG) log("getConnectionState(" + device + ")");
-        final IBluetoothSap service = getService();
-        final int defaultValue = BluetoothProfile.STATE_DISCONNECTED;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
-                service.getConnectionState(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Set priority of the profile
-     *
-     * <p> The device should already be paired.
-     * Priority can be one of {@link #PRIORITY_ON} or {@link #PRIORITY_OFF},
-     *
-     * @param device Paired bluetooth device
-     * @param priority
-     * @return true if priority is set, false on error
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public boolean setPriority(BluetoothDevice device, int priority) {
-        if (DBG) log("setPriority(" + device + ", " + priority + ")");
-        return setConnectionPolicy(device, BluetoothAdapter.priorityToConnectionPolicy(priority));
-    }
-
-    /**
-     * Set connection policy of the profile
-     *
-     * <p> The device should already be paired.
-     * Connection policy can be one of {@link #CONNECTION_POLICY_ALLOWED},
-     * {@link #CONNECTION_POLICY_FORBIDDEN}, {@link #CONNECTION_POLICY_UNKNOWN}
-     *
-     * @param device Paired bluetooth device
-     * @param connectionPolicy is the connection policy to set to for this profile
-     * @return true if connectionPolicy is set, false on error
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public boolean setConnectionPolicy(BluetoothDevice device,
-            @ConnectionPolicy int connectionPolicy) {
-        if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
-        final IBluetoothSap service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)
-                && (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_FORBIDDEN
-                    || connectionPolicy == BluetoothProfile.CONNECTION_POLICY_ALLOWED)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.setConnectionPolicy(device, connectionPolicy, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Get the priority of the profile.
-     *
-     * <p> The priority can be any of:
-     * {@link #PRIORITY_OFF}, {@link #PRIORITY_ON}, {@link #PRIORITY_UNDEFINED}
-     *
-     * @param device Bluetooth device
-     * @return priority of the device
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public int getPriority(BluetoothDevice device) {
-        if (VDBG) log("getPriority(" + device + ")");
-        return BluetoothAdapter.connectionPolicyToPriority(getConnectionPolicy(device));
-    }
-
-    /**
-     * Get the connection policy of the profile.
-     *
-     * <p> The connection policy can be any of:
-     * {@link #CONNECTION_POLICY_ALLOWED}, {@link #CONNECTION_POLICY_FORBIDDEN},
-     * {@link #CONNECTION_POLICY_UNKNOWN}
-     *
-     * @param device Bluetooth device
-     * @return connection policy of the device
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public @ConnectionPolicy int getConnectionPolicy(BluetoothDevice device) {
-        if (VDBG) log("getConnectionPolicy(" + device + ")");
-        final IBluetoothSap service = getService();
-        final int defaultValue = BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
-                service.getConnectionPolicy(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    private static void log(String msg) {
-        Log.d(TAG, msg);
-    }
-
-    private boolean isEnabled() {
-        return mAdapter.isEnabled();
-    }
-
-    private static boolean isValidDevice(BluetoothDevice device) {
-        return device != null && BluetoothAdapter.checkBluetoothAddress(device.getAddress());
-    }
-}
diff --git a/core/java/android/bluetooth/BluetoothServerSocket.java b/core/java/android/bluetooth/BluetoothServerSocket.java
deleted file mode 100644
index bb4e354..0000000
--- a/core/java/android/bluetooth/BluetoothServerSocket.java
+++ /dev/null
@@ -1,266 +0,0 @@
-/*
- * Copyright (C) 2009 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.bluetooth;
-
-import android.annotation.SuppressLint;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.os.Handler;
-import android.os.ParcelUuid;
-import android.util.Log;
-
-import java.io.Closeable;
-import java.io.IOException;
-
-/**
- * A listening Bluetooth socket.
- *
- * <p>The interface for Bluetooth Sockets is similar to that of TCP sockets:
- * {@link java.net.Socket} and {@link java.net.ServerSocket}. On the server
- * side, use a {@link BluetoothServerSocket} to create a listening server
- * socket. When a connection is accepted by the {@link BluetoothServerSocket},
- * it will return a new {@link BluetoothSocket} to manage the connection.
- * On the client side, use a single {@link BluetoothSocket} to both initiate
- * an outgoing connection and to manage the connection.
- *
- * <p>For Bluetooth BR/EDR, the most common type of socket is RFCOMM, which is the type supported by
- * the Android APIs. RFCOMM is a connection-oriented, streaming transport over Bluetooth BR/EDR. It
- * is also known as the Serial Port Profile (SPP). To create a listening
- * {@link BluetoothServerSocket} that's ready for incoming Bluetooth BR/EDR connections, use {@link
- * BluetoothAdapter#listenUsingRfcommWithServiceRecord
- * BluetoothAdapter.listenUsingRfcommWithServiceRecord()}.
- *
- * <p>For Bluetooth LE, the socket uses LE Connection-oriented Channel (CoC). LE CoC is a
- * connection-oriented, streaming transport over Bluetooth LE and has a credit-based flow control.
- * Correspondingly, use {@link BluetoothAdapter#listenUsingL2capChannel
- * BluetoothAdapter.listenUsingL2capChannel()} to create a listening {@link BluetoothServerSocket}
- * that's ready for incoming Bluetooth LE CoC connections. For LE CoC, you can use {@link #getPsm()}
- * to get the protocol/service multiplexer (PSM) value that the peer needs to use to connect to your
- * socket.
- *
- * <p> After the listening {@link BluetoothServerSocket} is created, call {@link #accept()} to
- * listen for incoming connection requests. This call will block until a connection is established,
- * at which point, it will return a {@link BluetoothSocket} to manage the connection. Once the
- * {@link BluetoothSocket} is acquired, it's a good idea to call {@link #close()} on the {@link
- * BluetoothServerSocket} when it's no longer needed for accepting
- * connections. Closing the {@link BluetoothServerSocket} will <em>not</em> close the returned
- * {@link BluetoothSocket}.
- *
- * <p>{@link BluetoothServerSocket} is thread
- * safe. In particular, {@link #close} will always immediately abort ongoing
- * operations and close the server socket.
- *
- * <div class="special reference">
- * <h3>Developer Guides</h3>
- * <p>For more information about using Bluetooth, read the
- * <a href="{@docRoot}guide/topics/connectivity/bluetooth.html">Bluetooth</a> developer guide.</p>
- * </div>
- *
- * {@see BluetoothSocket}
- */
-@SuppressLint("AndroidFrameworkBluetoothPermission")
-public final class BluetoothServerSocket implements Closeable {
-
-    private static final String TAG = "BluetoothServerSocket";
-    private static final boolean DBG = false;
-    @UnsupportedAppUsage(publicAlternatives = "Use public {@link BluetoothServerSocket} API "
-            + "instead.")
-    /*package*/ final BluetoothSocket mSocket;
-    private Handler mHandler;
-    private int mMessage;
-    private int mChannel;
-
-    /**
-     * Construct a socket for incoming connections.
-     *
-     * @param type type of socket
-     * @param auth require the remote device to be authenticated
-     * @param encrypt require the connection to be encrypted
-     * @param port remote port
-     * @throws IOException On error, for example Bluetooth not available, or insufficient
-     * privileges
-     */
-    /*package*/ BluetoothServerSocket(int type, boolean auth, boolean encrypt, int port)
-            throws IOException {
-        mChannel = port;
-        mSocket = new BluetoothSocket(type, -1, auth, encrypt, null, port, null);
-        if (port == BluetoothAdapter.SOCKET_CHANNEL_AUTO_STATIC_NO_SDP) {
-            mSocket.setExcludeSdp(true);
-        }
-    }
-
-    /**
-     * Construct a socket for incoming connections.
-     *
-     * @param type type of socket
-     * @param auth require the remote device to be authenticated
-     * @param encrypt require the connection to be encrypted
-     * @param port remote port
-     * @param mitm enforce person-in-the-middle protection for authentication.
-     * @param min16DigitPin enforce a minimum length of 16 digits for a sec mode 2 connection
-     * @throws IOException On error, for example Bluetooth not available, or insufficient
-     * privileges
-     */
-    /*package*/ BluetoothServerSocket(int type, boolean auth, boolean encrypt, int port,
-            boolean mitm, boolean min16DigitPin)
-            throws IOException {
-        mChannel = port;
-        mSocket = new BluetoothSocket(type, -1, auth, encrypt, null, port, null, mitm,
-                min16DigitPin);
-        if (port == BluetoothAdapter.SOCKET_CHANNEL_AUTO_STATIC_NO_SDP) {
-            mSocket.setExcludeSdp(true);
-        }
-    }
-
-    /**
-     * Construct a socket for incoming connections.
-     *
-     * @param type type of socket
-     * @param auth require the remote device to be authenticated
-     * @param encrypt require the connection to be encrypted
-     * @param uuid uuid
-     * @throws IOException On error, for example Bluetooth not available, or insufficient
-     * privileges
-     */
-    /*package*/ BluetoothServerSocket(int type, boolean auth, boolean encrypt, ParcelUuid uuid)
-            throws IOException {
-        mSocket = new BluetoothSocket(type, -1, auth, encrypt, null, -1, uuid);
-        // TODO: This is the same as mChannel = -1 - is this intentional?
-        mChannel = mSocket.getPort();
-    }
-
-
-    /**
-     * Block until a connection is established.
-     * <p>Returns a connected {@link BluetoothSocket} on successful connection.
-     * <p>Once this call returns, it can be called again to accept subsequent
-     * incoming connections.
-     * <p>{@link #close} can be used to abort this call from another thread.
-     *
-     * @return a connected {@link BluetoothSocket}
-     * @throws IOException on error, for example this call was aborted, or timeout
-     */
-    public BluetoothSocket accept() throws IOException {
-        return accept(-1);
-    }
-
-    /**
-     * Block until a connection is established, with timeout.
-     * <p>Returns a connected {@link BluetoothSocket} on successful connection.
-     * <p>Once this call returns, it can be called again to accept subsequent
-     * incoming connections.
-     * <p>{@link #close} can be used to abort this call from another thread.
-     *
-     * @return a connected {@link BluetoothSocket}
-     * @throws IOException on error, for example this call was aborted, or timeout
-     */
-    public BluetoothSocket accept(int timeout) throws IOException {
-        return mSocket.accept(timeout);
-    }
-
-    /**
-     * Immediately close this socket, and release all associated resources.
-     * <p>Causes blocked calls on this socket in other threads to immediately
-     * throw an IOException.
-     * <p>Closing the {@link BluetoothServerSocket} will <em>not</em>
-     * close any {@link BluetoothSocket} received from {@link #accept()}.
-     */
-    public void close() throws IOException {
-        if (DBG) Log.d(TAG, "BluetoothServerSocket:close() called. mChannel=" + mChannel);
-        synchronized (this) {
-            if (mHandler != null) {
-                mHandler.obtainMessage(mMessage).sendToTarget();
-            }
-        }
-        mSocket.close();
-    }
-
-    /*package*/
-    synchronized void setCloseHandler(Handler handler, int message) {
-        mHandler = handler;
-        mMessage = message;
-    }
-
-    /*package*/ void setServiceName(String serviceName) {
-        mSocket.setServiceName(serviceName);
-    }
-
-    /**
-     * Returns the channel on which this socket is bound.
-     *
-     * @hide
-     */
-    public int getChannel() {
-        return mChannel;
-    }
-
-    /**
-     * Returns the assigned dynamic protocol/service multiplexer (PSM) value for the listening L2CAP
-     * Connection-oriented Channel (CoC) server socket. This server socket must be returned by the
-     * {@link BluetoothAdapter#listenUsingL2capChannel()} or {@link
-     * BluetoothAdapter#listenUsingInsecureL2capChannel()}. The returned value is undefined if this
-     * method is called on non-L2CAP server sockets.
-     *
-     * @return the assigned PSM or LE_PSM value depending on transport
-     */
-    public int getPsm() {
-        return mChannel;
-    }
-
-    /**
-     * Sets the channel on which future sockets are bound.
-     * Currently used only when a channel is auto generated.
-     */
-    /*package*/ void setChannel(int newChannel) {
-        /* TODO: From a design/architecture perspective this is wrong.
-         *       The bind operation should be conducted through this class
-         *       and the resulting port should be kept in mChannel, and
-         *       not set from BluetoothAdapter. */
-        if (mSocket != null) {
-            if (mSocket.getPort() != newChannel) {
-                Log.w(TAG, "The port set is different that the underlying port. mSocket.getPort(): "
-                        + mSocket.getPort() + " requested newChannel: " + newChannel);
-            }
-        }
-        mChannel = newChannel;
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-        sb.append("ServerSocket: Type: ");
-        switch (mSocket.getConnectionType()) {
-            case BluetoothSocket.TYPE_RFCOMM: {
-                sb.append("TYPE_RFCOMM");
-                break;
-            }
-            case BluetoothSocket.TYPE_L2CAP: {
-                sb.append("TYPE_L2CAP");
-                break;
-            }
-            case BluetoothSocket.TYPE_L2CAP_LE: {
-                sb.append("TYPE_L2CAP_LE");
-                break;
-            }
-            case BluetoothSocket.TYPE_SCO: {
-                sb.append("TYPE_SCO");
-                break;
-            }
-        }
-        sb.append(" Channel: ").append(mChannel);
-        return sb.toString();
-    }
-}
diff --git a/core/java/android/bluetooth/BluetoothSocket.java b/core/java/android/bluetooth/BluetoothSocket.java
deleted file mode 100644
index db5b751..0000000
--- a/core/java/android/bluetooth/BluetoothSocket.java
+++ /dev/null
@@ -1,809 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-import android.annotation.RequiresNoPermission;
-import android.annotation.RequiresPermission;
-import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.net.LocalSocket;
-import android.os.Build;
-import android.os.ParcelFileDescriptor;
-import android.os.ParcelUuid;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.io.Closeable;
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.Arrays;
-import java.util.Locale;
-import java.util.UUID;
-
-/**
- * A connected or connecting Bluetooth socket.
- *
- * <p>The interface for Bluetooth Sockets is similar to that of TCP sockets:
- * {@link java.net.Socket} and {@link java.net.ServerSocket}. On the server
- * side, use a {@link BluetoothServerSocket} to create a listening server
- * socket. When a connection is accepted by the {@link BluetoothServerSocket},
- * it will return a new {@link BluetoothSocket} to manage the connection.
- * On the client side, use a single {@link BluetoothSocket} to both initiate
- * an outgoing connection and to manage the connection.
- *
- * <p>The most common type of Bluetooth socket is RFCOMM, which is the type
- * supported by the Android APIs. RFCOMM is a connection-oriented, streaming
- * transport over Bluetooth. It is also known as the Serial Port Profile (SPP).
- *
- * <p>To create a {@link BluetoothSocket} for connecting to a known device, use
- * {@link BluetoothDevice#createRfcommSocketToServiceRecord
- * BluetoothDevice.createRfcommSocketToServiceRecord()}.
- * Then call {@link #connect()} to attempt a connection to the remote device.
- * This call will block until a connection is established or the connection
- * fails.
- *
- * <p>To create a {@link BluetoothSocket} as a server (or "host"), see the
- * {@link BluetoothServerSocket} documentation.
- *
- * <p>Once the socket is connected, whether initiated as a client or accepted
- * as a server, open the IO streams by calling {@link #getInputStream} and
- * {@link #getOutputStream} in order to retrieve {@link java.io.InputStream}
- * and {@link java.io.OutputStream} objects, respectively, which are
- * automatically connected to the socket.
- *
- * <p>{@link BluetoothSocket} is thread
- * safe. In particular, {@link #close} will always immediately abort ongoing
- * operations and close the socket.
- *
- * <div class="special reference">
- * <h3>Developer Guides</h3>
- * <p>For more information about using Bluetooth, read the
- * <a href="{@docRoot}guide/topics/connectivity/bluetooth.html">Bluetooth</a> developer guide.</p>
- * </div>
- *
- * {@see BluetoothServerSocket}
- * {@see java.io.InputStream}
- * {@see java.io.OutputStream}
- */
-public final class BluetoothSocket implements Closeable {
-    private static final String TAG = "BluetoothSocket";
-    private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG);
-    private static final boolean VDBG = Log.isLoggable(TAG, Log.VERBOSE);
-
-    /** @hide */
-    public static final int MAX_RFCOMM_CHANNEL = 30;
-    /*package*/ static final int MAX_L2CAP_PACKAGE_SIZE = 0xFFFF;
-
-    /** RFCOMM socket */
-    public static final int TYPE_RFCOMM = 1;
-
-    /** SCO socket */
-    public static final int TYPE_SCO = 2;
-
-    /** L2CAP socket */
-    public static final int TYPE_L2CAP = 3;
-
-    /** L2CAP socket on BR/EDR transport
-     * @hide
-     */
-    public static final int TYPE_L2CAP_BREDR = TYPE_L2CAP;
-
-    /** L2CAP socket on LE transport
-     * @hide
-     */
-    public static final int TYPE_L2CAP_LE = 4;
-
-    /*package*/ static final int EBADFD = 77;
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    /*package*/ static final int EADDRINUSE = 98;
-
-    /*package*/ static final int SEC_FLAG_ENCRYPT = 1;
-    /*package*/ static final int SEC_FLAG_AUTH = 1 << 1;
-    /*package*/ static final int BTSOCK_FLAG_NO_SDP = 1 << 2;
-    /*package*/ static final int SEC_FLAG_AUTH_MITM = 1 << 3;
-    /*package*/ static final int SEC_FLAG_AUTH_16_DIGIT = 1 << 4;
-
-    private final int mType;  /* one of TYPE_RFCOMM etc */
-    private BluetoothDevice mDevice;    /* remote device */
-    private String mAddress;    /* remote address */
-    private final boolean mAuth;
-    private final boolean mEncrypt;
-    private final BluetoothInputStream mInputStream;
-    private final BluetoothOutputStream mOutputStream;
-    private final ParcelUuid mUuid;
-    /** when true no SPP SDP record will be created */
-    private boolean mExcludeSdp = false;
-    /** when true Person-in-the-middle protection will be enabled */
-    private boolean mAuthMitm = false;
-    /** Minimum 16 digit pin for sec mode 2 connections */
-    private boolean mMin16DigitPin = false;
-    @UnsupportedAppUsage(publicAlternatives = "Use {@link BluetoothSocket} public API instead.")
-    private ParcelFileDescriptor mPfd;
-    @UnsupportedAppUsage
-    private LocalSocket mSocket;
-    private InputStream mSocketIS;
-    private OutputStream mSocketOS;
-    @UnsupportedAppUsage
-    private int mPort;  /* RFCOMM channel or L2CAP psm */
-    private int mFd;
-    private String mServiceName;
-    private static final int PROXY_CONNECTION_TIMEOUT = 5000;
-
-    private static final int SOCK_SIGNAL_SIZE = 20;
-
-    private ByteBuffer mL2capBuffer = null;
-    private int mMaxTxPacketSize = 0; // The l2cap maximum packet size supported by the peer.
-    private int mMaxRxPacketSize = 0; // The l2cap maximum packet size that can be received.
-
-    private enum SocketState {
-        INIT,
-        CONNECTED,
-        LISTENING,
-        CLOSED,
-    }
-
-    /** prevents all native calls after destroyNative() */
-    private volatile SocketState mSocketState;
-
-    /** protects mSocketState */
-    //private final ReentrantReadWriteLock mLock;
-
-    /**
-     * Construct a BluetoothSocket.
-     *
-     * @param type type of socket
-     * @param fd fd to use for connected socket, or -1 for a new socket
-     * @param auth require the remote device to be authenticated
-     * @param encrypt require the connection to be encrypted
-     * @param device remote device that this socket can connect to
-     * @param port remote port
-     * @param uuid SDP uuid
-     * @throws IOException On error, for example Bluetooth not available, or insufficient
-     * privileges
-     */
-    /*package*/ BluetoothSocket(int type, int fd, boolean auth, boolean encrypt,
-            BluetoothDevice device, int port, ParcelUuid uuid) throws IOException {
-        this(type, fd, auth, encrypt, device, port, uuid, false, false);
-    }
-
-    /**
-     * Construct a BluetoothSocket.
-     *
-     * @param type type of socket
-     * @param fd fd to use for connected socket, or -1 for a new socket
-     * @param auth require the remote device to be authenticated
-     * @param encrypt require the connection to be encrypted
-     * @param device remote device that this socket can connect to
-     * @param port remote port
-     * @param uuid SDP uuid
-     * @param mitm enforce person-in-the-middle protection.
-     * @param min16DigitPin enforce a minimum length of 16 digits for a sec mode 2 connection
-     * @throws IOException On error, for example Bluetooth not available, or insufficient
-     * privileges
-     */
-    /*package*/ BluetoothSocket(int type, int fd, boolean auth, boolean encrypt,
-            BluetoothDevice device, int port, ParcelUuid uuid, boolean mitm, boolean min16DigitPin)
-            throws IOException {
-        if (VDBG) Log.d(TAG, "Creating new BluetoothSocket of type: " + type);
-        if (type == BluetoothSocket.TYPE_RFCOMM && uuid == null && fd == -1
-                && port != BluetoothAdapter.SOCKET_CHANNEL_AUTO_STATIC_NO_SDP) {
-            if (port < 1 || port > MAX_RFCOMM_CHANNEL) {
-                throw new IOException("Invalid RFCOMM channel: " + port);
-            }
-        }
-        if (uuid != null) {
-            mUuid = uuid;
-        } else {
-            mUuid = new ParcelUuid(new UUID(0, 0));
-        }
-        mType = type;
-        mAuth = auth;
-        mAuthMitm = mitm;
-        mMin16DigitPin = min16DigitPin;
-        mEncrypt = encrypt;
-        mDevice = device;
-        mPort = port;
-        mFd = fd;
-
-        mSocketState = SocketState.INIT;
-
-        if (device == null) {
-            // Server socket
-            mAddress = BluetoothAdapter.getDefaultAdapter().getAddress();
-        } else {
-            // Remote socket
-            mAddress = device.getAddress();
-        }
-        mInputStream = new BluetoothInputStream(this);
-        mOutputStream = new BluetoothOutputStream(this);
-    }
-
-    private BluetoothSocket(BluetoothSocket s) {
-        if (VDBG) Log.d(TAG, "Creating new Private BluetoothSocket of type: " + s.mType);
-        mUuid = s.mUuid;
-        mType = s.mType;
-        mAuth = s.mAuth;
-        mEncrypt = s.mEncrypt;
-        mPort = s.mPort;
-        mInputStream = new BluetoothInputStream(this);
-        mOutputStream = new BluetoothOutputStream(this);
-        mMaxRxPacketSize = s.mMaxRxPacketSize;
-        mMaxTxPacketSize = s.mMaxTxPacketSize;
-
-        mServiceName = s.mServiceName;
-        mExcludeSdp = s.mExcludeSdp;
-        mAuthMitm = s.mAuthMitm;
-        mMin16DigitPin = s.mMin16DigitPin;
-    }
-
-    private BluetoothSocket acceptSocket(String remoteAddr) throws IOException {
-        BluetoothSocket as = new BluetoothSocket(this);
-        as.mSocketState = SocketState.CONNECTED;
-        FileDescriptor[] fds = mSocket.getAncillaryFileDescriptors();
-        if (DBG) Log.d(TAG, "socket fd passed by stack fds: " + Arrays.toString(fds));
-        if (fds == null || fds.length != 1) {
-            Log.e(TAG, "socket fd passed from stack failed, fds: " + Arrays.toString(fds));
-            as.close();
-            throw new IOException("bt socket acept failed");
-        }
-
-        as.mPfd = ParcelFileDescriptor.dup(fds[0]);
-        as.mSocket = LocalSocket.createConnectedLocalSocket(fds[0]);
-        as.mSocketIS = as.mSocket.getInputStream();
-        as.mSocketOS = as.mSocket.getOutputStream();
-        as.mAddress = remoteAddr;
-        as.mDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(remoteAddr);
-        return as;
-    }
-
-    /**
-     * Construct a BluetoothSocket from address. Used by native code.
-     *
-     * @param type type of socket
-     * @param fd fd to use for connected socket, or -1 for a new socket
-     * @param auth require the remote device to be authenticated
-     * @param encrypt require the connection to be encrypted
-     * @param address remote device that this socket can connect to
-     * @param port remote port
-     * @throws IOException On error, for example Bluetooth not available, or insufficient
-     * privileges
-     */
-    private BluetoothSocket(int type, int fd, boolean auth, boolean encrypt, String address,
-            int port) throws IOException {
-        this(type, fd, auth, encrypt, new BluetoothDevice(address), port, null, false, false);
-    }
-
-    /** @hide */
-    @Override
-    protected void finalize() throws Throwable {
-        try {
-            close();
-        } finally {
-            super.finalize();
-        }
-    }
-
-    private int getSecurityFlags() {
-        int flags = 0;
-        if (mAuth) {
-            flags |= SEC_FLAG_AUTH;
-        }
-        if (mEncrypt) {
-            flags |= SEC_FLAG_ENCRYPT;
-        }
-        if (mExcludeSdp) {
-            flags |= BTSOCK_FLAG_NO_SDP;
-        }
-        if (mAuthMitm) {
-            flags |= SEC_FLAG_AUTH_MITM;
-        }
-        if (mMin16DigitPin) {
-            flags |= SEC_FLAG_AUTH_16_DIGIT;
-        }
-        return flags;
-    }
-
-    /**
-     * Get the remote device this socket is connecting, or connected, to.
-     *
-     * @return remote device
-     */
-    @RequiresNoPermission
-    public BluetoothDevice getRemoteDevice() {
-        return mDevice;
-    }
-
-    /**
-     * Get the input stream associated with this socket.
-     * <p>The input stream will be returned even if the socket is not yet
-     * connected, but operations on that stream will throw IOException until
-     * the associated socket is connected.
-     *
-     * @return InputStream
-     */
-    @RequiresNoPermission
-    public InputStream getInputStream() throws IOException {
-        return mInputStream;
-    }
-
-    /**
-     * Get the output stream associated with this socket.
-     * <p>The output stream will be returned even if the socket is not yet
-     * connected, but operations on that stream will throw IOException until
-     * the associated socket is connected.
-     *
-     * @return OutputStream
-     */
-    @RequiresNoPermission
-    public OutputStream getOutputStream() throws IOException {
-        return mOutputStream;
-    }
-
-    /**
-     * Get the connection status of this socket, ie, whether there is an active connection with
-     * remote device.
-     *
-     * @return true if connected false if not connected
-     */
-    @RequiresNoPermission
-    public boolean isConnected() {
-        return mSocketState == SocketState.CONNECTED;
-    }
-
-    /*package*/ void setServiceName(String name) {
-        mServiceName = name;
-    }
-
-    /**
-     * Attempt to connect to a remote device.
-     * <p>This method will block until a connection is made or the connection
-     * fails. If this method returns without an exception then this socket
-     * is now connected.
-     * <p>Creating new connections to
-     * remote Bluetooth devices should not be attempted while device discovery
-     * is in progress. Device discovery is a heavyweight procedure on the
-     * Bluetooth adapter and will significantly slow a device connection.
-     * Use {@link BluetoothAdapter#cancelDiscovery()} to cancel an ongoing
-     * discovery. Discovery is not managed by the Activity,
-     * but is run as a system service, so an application should always call
-     * {@link BluetoothAdapter#cancelDiscovery()} even if it
-     * did not directly request a discovery, just to be sure.
-     * <p>{@link #close} can be used to abort this call from another thread.
-     *
-     * @throws IOException on error, for example connection failure
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public void connect() throws IOException {
-        if (mDevice == null) throw new IOException("Connect is called on null device");
-
-        try {
-            if (mSocketState == SocketState.CLOSED) throw new IOException("socket closed");
-            IBluetooth bluetoothProxy =
-                    BluetoothAdapter.getDefaultAdapter().getBluetoothService();
-            if (bluetoothProxy == null) throw new IOException("Bluetooth is off");
-            mPfd = bluetoothProxy.getSocketManager().connectSocket(mDevice, mType,
-                    mUuid, mPort, getSecurityFlags());
-            synchronized (this) {
-                if (DBG) Log.d(TAG, "connect(), SocketState: " + mSocketState + ", mPfd: " + mPfd);
-                if (mSocketState == SocketState.CLOSED) throw new IOException("socket closed");
-                if (mPfd == null) throw new IOException("bt socket connect failed");
-                FileDescriptor fd = mPfd.getFileDescriptor();
-                mSocket = LocalSocket.createConnectedLocalSocket(fd);
-                mSocketIS = mSocket.getInputStream();
-                mSocketOS = mSocket.getOutputStream();
-            }
-            int channel = readInt(mSocketIS);
-            if (channel <= 0) {
-                throw new IOException("bt socket connect failed");
-            }
-            mPort = channel;
-            waitSocketSignal(mSocketIS);
-            synchronized (this) {
-                if (mSocketState == SocketState.CLOSED) {
-                    throw new IOException("bt socket closed");
-                }
-                mSocketState = SocketState.CONNECTED;
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, Log.getStackTraceString(new Throwable()));
-            throw new IOException("unable to send RPC: " + e.getMessage());
-        }
-    }
-
-    /**
-     * Currently returns unix errno instead of throwing IOException,
-     * so that BluetoothAdapter can check the error code for EADDRINUSE
-     */
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    /*package*/ int bindListen() {
-        int ret;
-        if (mSocketState == SocketState.CLOSED) return EBADFD;
-        IBluetooth bluetoothProxy = BluetoothAdapter.getDefaultAdapter().getBluetoothService();
-        if (bluetoothProxy == null) {
-            Log.e(TAG, "bindListen fail, reason: bluetooth is off");
-            return -1;
-        }
-        try {
-            if (DBG) Log.d(TAG, "bindListen(): mPort=" + mPort + ", mType=" + mType);
-            mPfd = bluetoothProxy.getSocketManager().createSocketChannel(mType, mServiceName,
-                    mUuid, mPort, getSecurityFlags());
-        } catch (RemoteException e) {
-            Log.e(TAG, Log.getStackTraceString(new Throwable()));
-            return -1;
-        }
-
-        // read out port number
-        try {
-            synchronized (this) {
-                if (DBG) {
-                    Log.d(TAG, "bindListen(), SocketState: " + mSocketState + ", mPfd: " + mPfd);
-                }
-                if (mSocketState != SocketState.INIT) return EBADFD;
-                if (mPfd == null) return -1;
-                FileDescriptor fd = mPfd.getFileDescriptor();
-                if (fd == null) {
-                    Log.e(TAG, "bindListen(), null file descriptor");
-                    return -1;
-                }
-
-                if (DBG) Log.d(TAG, "bindListen(), Create LocalSocket");
-                mSocket = LocalSocket.createConnectedLocalSocket(fd);
-                if (DBG) Log.d(TAG, "bindListen(), new LocalSocket.getInputStream()");
-                mSocketIS = mSocket.getInputStream();
-                mSocketOS = mSocket.getOutputStream();
-            }
-            if (DBG) Log.d(TAG, "bindListen(), readInt mSocketIS: " + mSocketIS);
-            int channel = readInt(mSocketIS);
-            synchronized (this) {
-                if (mSocketState == SocketState.INIT) {
-                    mSocketState = SocketState.LISTENING;
-                }
-            }
-            if (DBG) Log.d(TAG, "bindListen(): channel=" + channel + ", mPort=" + mPort);
-            if (mPort <= -1) {
-                mPort = channel;
-            } // else ASSERT(mPort == channel)
-            ret = 0;
-        } catch (IOException e) {
-            if (mPfd != null) {
-                try {
-                    mPfd.close();
-                } catch (IOException e1) {
-                    Log.e(TAG, "bindListen, close mPfd: " + e1);
-                }
-                mPfd = null;
-            }
-            Log.e(TAG, "bindListen, fail to get port number, exception: " + e);
-            return -1;
-        }
-        return ret;
-    }
-
-    /*package*/ BluetoothSocket accept(int timeout) throws IOException {
-        BluetoothSocket acceptedSocket;
-        if (mSocketState != SocketState.LISTENING) {
-            throw new IOException("bt socket is not in listen state");
-        }
-        if (timeout > 0) {
-            Log.d(TAG, "accept() set timeout (ms):" + timeout);
-            mSocket.setSoTimeout(timeout);
-        }
-        String RemoteAddr = waitSocketSignal(mSocketIS);
-        if (timeout > 0) {
-            mSocket.setSoTimeout(0);
-        }
-        synchronized (this) {
-            if (mSocketState != SocketState.LISTENING) {
-                throw new IOException("bt socket is not in listen state");
-            }
-            acceptedSocket = acceptSocket(RemoteAddr);
-            //quick drop the reference of the file handle
-        }
-        return acceptedSocket;
-    }
-
-    /*package*/ int available() throws IOException {
-        if (VDBG) Log.d(TAG, "available: " + mSocketIS);
-        return mSocketIS.available();
-    }
-
-    /*package*/ int read(byte[] b, int offset, int length) throws IOException {
-        int ret = 0;
-        if (VDBG) Log.d(TAG, "read in:  " + mSocketIS + " len: " + length);
-        if ((mType == TYPE_L2CAP) || (mType == TYPE_L2CAP_LE)) {
-            int bytesToRead = length;
-            if (VDBG) {
-                Log.v(TAG, "l2cap: read(): offset: " + offset + " length:" + length
-                        + "mL2capBuffer= " + mL2capBuffer);
-            }
-            if (mL2capBuffer == null) {
-                createL2capRxBuffer();
-            }
-            if (mL2capBuffer.remaining() == 0) {
-                if (VDBG) Log.v(TAG, "l2cap buffer empty, refilling...");
-                if (fillL2capRxBuffer() == -1) {
-                    return -1;
-                }
-            }
-            if (bytesToRead > mL2capBuffer.remaining()) {
-                bytesToRead = mL2capBuffer.remaining();
-            }
-            if (VDBG) {
-                Log.v(TAG, "get(): offset: " + offset
-                        + " bytesToRead: " + bytesToRead);
-            }
-            mL2capBuffer.get(b, offset, bytesToRead);
-            ret = bytesToRead;
-        } else {
-            if (VDBG) Log.v(TAG, "default: read(): offset: " + offset + " length:" + length);
-            ret = mSocketIS.read(b, offset, length);
-        }
-        if (ret < 0) {
-            throw new IOException("bt socket closed, read return: " + ret);
-        }
-        if (VDBG) Log.d(TAG, "read out:  " + mSocketIS + " ret: " + ret);
-        return ret;
-    }
-
-    /*package*/ int write(byte[] b, int offset, int length) throws IOException {
-
-        //TODO: Since bindings can exist between the SDU size and the
-        //      protocol, we might need to throw an exception instead of just
-        //      splitting the write into multiple smaller writes.
-        //      Rfcomm uses dynamic allocation, and should not have any bindings
-        //      to the actual message length.
-        if (VDBG) Log.d(TAG, "write: " + mSocketOS + " length: " + length);
-        if ((mType == TYPE_L2CAP) || (mType == TYPE_L2CAP_LE)) {
-            if (length <= mMaxTxPacketSize) {
-                mSocketOS.write(b, offset, length);
-            } else {
-                if (DBG) {
-                    Log.w(TAG, "WARNING: Write buffer larger than L2CAP packet size!\n"
-                            + "Packet will be divided into SDU packets of size "
-                            + mMaxTxPacketSize);
-                }
-                int tmpOffset = offset;
-                int bytesToWrite = length;
-                while (bytesToWrite > 0) {
-                    int tmpLength = (bytesToWrite > mMaxTxPacketSize)
-                            ? mMaxTxPacketSize
-                            : bytesToWrite;
-                    mSocketOS.write(b, tmpOffset, tmpLength);
-                    tmpOffset += tmpLength;
-                    bytesToWrite -= tmpLength;
-                }
-            }
-        } else {
-            mSocketOS.write(b, offset, length);
-        }
-        // There is no good way to confirm since the entire process is asynchronous anyway
-        if (VDBG) Log.d(TAG, "write out: " + mSocketOS + " length: " + length);
-        return length;
-    }
-
-    @Override
-    public void close() throws IOException {
-        Log.d(TAG, "close() this: " + this + ", channel: " + mPort + ", mSocketIS: " + mSocketIS
-                + ", mSocketOS: " + mSocketOS + "mSocket: " + mSocket + ", mSocketState: "
-                + mSocketState);
-        if (mSocketState == SocketState.CLOSED) {
-            return;
-        } else {
-            synchronized (this) {
-                if (mSocketState == SocketState.CLOSED) {
-                    return;
-                }
-                mSocketState = SocketState.CLOSED;
-                if (mSocket != null) {
-                    if (DBG) Log.d(TAG, "Closing mSocket: " + mSocket);
-                    mSocket.shutdownInput();
-                    mSocket.shutdownOutput();
-                    mSocket.close();
-                    mSocket = null;
-                }
-                if (mPfd != null) {
-                    mPfd.close();
-                    mPfd = null;
-                }
-            }
-        }
-    }
-
-    /*package */ void removeChannel() {
-    }
-
-    /*package */ int getPort() {
-        return mPort;
-    }
-
-    /**
-     * Get the maximum supported Transmit packet size for the underlying transport.
-     * Use this to optimize the writes done to the output socket, to avoid sending
-     * half full packets.
-     *
-     * @return the maximum supported Transmit packet size for the underlying transport.
-     */
-    @RequiresNoPermission
-    public int getMaxTransmitPacketSize() {
-        return mMaxTxPacketSize;
-    }
-
-    /**
-     * Get the maximum supported Receive packet size for the underlying transport.
-     * Use this to optimize the reads done on the input stream, as any call to read
-     * will return a maximum of this amount of bytes - or for some transports a
-     * multiple of this value.
-     *
-     * @return the maximum supported Receive packet size for the underlying transport.
-     */
-    @RequiresNoPermission
-    public int getMaxReceivePacketSize() {
-        return mMaxRxPacketSize;
-    }
-
-    /**
-     * Get the type of the underlying connection.
-     *
-     * @return one of {@link #TYPE_RFCOMM}, {@link #TYPE_SCO} or {@link #TYPE_L2CAP}
-     */
-    @RequiresNoPermission
-    public int getConnectionType() {
-        if (mType == TYPE_L2CAP_LE) {
-            // Treat the LE CoC to be the same type as L2CAP.
-            return TYPE_L2CAP;
-        }
-        return mType;
-    }
-
-    /**
-     * Change if a SDP entry should be automatically created.
-     * Must be called before calling .bind, for the call to have any effect.
-     *
-     * @param excludeSdp <li>TRUE - do not auto generate SDP record. <li>FALSE - default - auto
-     * generate SPP SDP record.
-     * @hide
-     */
-    @RequiresNoPermission
-    public void setExcludeSdp(boolean excludeSdp) {
-        mExcludeSdp = excludeSdp;
-    }
-
-    /**
-     * Set the LE Transmit Data Length to be the maximum that the BT Controller is capable of. This
-     * parameter is used by the BT Controller to set the maximum transmission packet size on this
-     * connection. This function is currently used for testing only.
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public void requestMaximumTxDataLength() throws IOException {
-        if (mDevice == null) {
-            throw new IOException("requestMaximumTxDataLength is called on null device");
-        }
-
-        try {
-            if (mSocketState == SocketState.CLOSED) {
-                throw new IOException("socket closed");
-            }
-            IBluetooth bluetoothProxy =
-                    BluetoothAdapter.getDefaultAdapter().getBluetoothService();
-            if (bluetoothProxy == null) {
-                throw new IOException("Bluetooth is off");
-            }
-
-            if (DBG) Log.d(TAG, "requestMaximumTxDataLength");
-            bluetoothProxy.getSocketManager().requestMaximumTxDataLength(mDevice);
-        } catch (RemoteException e) {
-            Log.e(TAG, Log.getStackTraceString(new Throwable()));
-            throw new IOException("unable to send RPC: " + e.getMessage());
-        }
-    }
-
-    private String convertAddr(final byte[] addr) {
-        return String.format(Locale.US, "%02X:%02X:%02X:%02X:%02X:%02X",
-                addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
-    }
-
-    private String waitSocketSignal(InputStream is) throws IOException {
-        byte[] sig = new byte[SOCK_SIGNAL_SIZE];
-        int ret = readAll(is, sig);
-        if (VDBG) {
-            Log.d(TAG, "waitSocketSignal read " + SOCK_SIGNAL_SIZE + " bytes signal ret: " + ret);
-        }
-        ByteBuffer bb = ByteBuffer.wrap(sig);
-        /* the struct in native is decorated with __attribute__((packed)), hence this is possible */
-        bb.order(ByteOrder.nativeOrder());
-        int size = bb.getShort();
-        if (size != SOCK_SIGNAL_SIZE) {
-            throw new IOException("Connection failure, wrong signal size: " + size);
-        }
-        byte[] addr = new byte[6];
-        bb.get(addr);
-        int channel = bb.getInt();
-        int status = bb.getInt();
-        mMaxTxPacketSize = (bb.getShort() & 0xffff); // Convert to unsigned value
-        mMaxRxPacketSize = (bb.getShort() & 0xffff); // Convert to unsigned value
-        String RemoteAddr = convertAddr(addr);
-        if (VDBG) {
-            Log.d(TAG, "waitSocketSignal: sig size: " + size + ", remote addr: "
-                    + RemoteAddr + ", channel: " + channel + ", status: " + status
-                    + " MaxRxPktSize: " + mMaxRxPacketSize + " MaxTxPktSize: " + mMaxTxPacketSize);
-        }
-        if (status != 0) {
-            throw new IOException("Connection failure, status: " + status);
-        }
-        return RemoteAddr;
-    }
-
-    private void createL2capRxBuffer() {
-        if ((mType == TYPE_L2CAP) || (mType == TYPE_L2CAP_LE)) {
-            // Allocate the buffer to use for reads.
-            if (VDBG) Log.v(TAG, "  Creating mL2capBuffer: mMaxPacketSize: " + mMaxRxPacketSize);
-            mL2capBuffer = ByteBuffer.wrap(new byte[mMaxRxPacketSize]);
-            if (VDBG) Log.v(TAG, "mL2capBuffer.remaining()" + mL2capBuffer.remaining());
-            mL2capBuffer.limit(0); // Ensure we do a real read at the first read-request
-            if (VDBG) {
-                Log.v(TAG, "mL2capBuffer.remaining() after limit(0):" + mL2capBuffer.remaining());
-            }
-        }
-    }
-
-    private int readAll(InputStream is, byte[] b) throws IOException {
-        int left = b.length;
-        while (left > 0) {
-            int ret = is.read(b, b.length - left, left);
-            if (ret <= 0) {
-                throw new IOException("read failed, socket might closed or timeout, read ret: "
-                        + ret);
-            }
-            left -= ret;
-            if (left != 0) {
-                Log.w(TAG, "readAll() looping, read partial size: " + (b.length - left)
-                        + ", expect size: " + b.length);
-            }
-        }
-        return b.length;
-    }
-
-    private int readInt(InputStream is) throws IOException {
-        byte[] ibytes = new byte[4];
-        int ret = readAll(is, ibytes);
-        if (VDBG) Log.d(TAG, "inputStream.read ret: " + ret);
-        ByteBuffer bb = ByteBuffer.wrap(ibytes);
-        bb.order(ByteOrder.nativeOrder());
-        return bb.getInt();
-    }
-
-    private int fillL2capRxBuffer() throws IOException {
-        mL2capBuffer.rewind();
-        int ret = mSocketIS.read(mL2capBuffer.array());
-        if (ret == -1) {
-            // reached end of stream - return -1
-            mL2capBuffer.limit(0);
-            return -1;
-        }
-        mL2capBuffer.limit(ret);
-        return ret;
-    }
-
-
-}
diff --git a/core/java/android/bluetooth/BluetoothStatusCodes.java b/core/java/android/bluetooth/BluetoothStatusCodes.java
deleted file mode 100644
index 9dafa07..0000000
--- a/core/java/android/bluetooth/BluetoothStatusCodes.java
+++ /dev/null
@@ -1,292 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-import android.annotation.SystemApi;
-
-/**
- * A class with constants representing possible return values for Bluetooth APIs. General return
- * values occupy the range 0 to 99. Profile-specific return values occupy the range 100-999.
- * API-specific return values start at 1000. The exception to this is the "UNKNOWN" error code which
- * occupies the max integer value.
- */
-public final class BluetoothStatusCodes {
-
-    private BluetoothStatusCodes() {}
-
-    /**
-     * Indicates that the API call was successful
-     */
-    public static final int SUCCESS = 0;
-
-    /**
-     * Error code indicating that Bluetooth is not enabled
-     */
-    public static final int ERROR_BLUETOOTH_NOT_ENABLED = 1;
-
-    /**
-     * Error code indicating that the API call was initiated by neither the system nor the active
-     * Zuser
-     */
-    public static final int ERROR_BLUETOOTH_NOT_ALLOWED = 2;
-
-    /**
-     * Error code indicating that the Bluetooth Device specified is not bonded
-     */
-    public static final int ERROR_DEVICE_NOT_BONDED = 3;
-
-    /**
-     * Error code indicating that the Bluetooth Device specified is not connected, but is bonded
-     *
-     * @hide
-     */
-    public static final int ERROR_DEVICE_NOT_CONNECTED = 4;
-
-    /**
-     * Error code indicating that the caller does not have the
-     * {@link android.Manifest.permission#BLUETOOTH_ADVERTISE} permission
-     *
-     * @hide
-     */
-    public static final int ERROR_MISSING_BLUETOOTH_ADVERTISE_PERMISSION = 5;
-
-    /**
-     * Error code indicating that the caller does not have the
-     * {@link android.Manifest.permission#BLUETOOTH_CONNECT} permission
-     */
-    public static final int ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION = 6;
-
-    /**
-     * Error code indicating that the caller does not have the
-     * {@link android.Manifest.permission#BLUETOOTH_SCAN} permission
-     *
-     * @hide
-     */
-    public static final int ERROR_MISSING_BLUETOOTH_SCAN_PERMISSION = 7;
-
-    /**
-     * Error code indicating that the caller does not have the
-     * {@link android.Manifest.permission#BLUETOOTH_PRIVILEGED} permission
-     */
-    public static final int ERROR_MISSING_BLUETOOTH_PRIVILEGED_PERMISSION = 8;
-
-    /**
-     * Error code indicating that the profile service is not bound. You can bind a profile service
-     * by calling {@link BluetoothAdapter#getProfileProxy}
-     */
-    public static final int ERROR_PROFILE_SERVICE_NOT_BOUND = 9;
-
-    /**
-     * Error code indicating that the feature is not supported.
-     */
-    public static final int ERROR_FEATURE_NOT_SUPPORTED = 10;
-
-    /**
-     * A GATT writeCharacteristic request is not permitted on the remote device.
-     */
-    public static final int ERROR_GATT_WRITE_NOT_ALLOWED = 101;
-
-    /**
-     * A GATT writeCharacteristic request is issued to a busy remote device.
-     */
-    public static final int ERROR_GATT_WRITE_REQUEST_BUSY = 102;
-
-    /**
-     * If another application has already requested {@link OobData} then another fetch will be
-     * disallowed until the callback is removed.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int ERROR_ANOTHER_ACTIVE_OOB_REQUEST = 1000;
-
-    /**
-     * Indicates that the ACL disconnected due to an explicit request from the local device.
-     * <p>
-     * Example cause: This is a normal disconnect reason, e.g., user/app initiates
-     * disconnection.
-     *
-     * @hide
-     */
-    public static final int ERROR_DISCONNECT_REASON_LOCAL_REQUEST = 1100;
-
-    /**
-     * Indicates that the ACL disconnected due to an explicit request from the remote device.
-     * <p>
-     * Example cause: This is a normal disconnect reason, e.g., user/app initiates
-     * disconnection.
-     * <p>
-     * Example solution: The app can also prompt the user to check their remote device.
-     *
-     * @hide
-     */
-    public static final int ERROR_DISCONNECT_REASON_REMOTE_REQUEST = 1101;
-
-    /**
-     * Generic disconnect reason indicating the ACL disconnected due to an error on the local
-     * device.
-     * <p>
-     * Example solution: Prompt the user to check their local device (e.g., phone, car
-     * headunit).
-     *
-     * @hide
-     */
-    public static final int ERROR_DISCONNECT_REASON_LOCAL = 1102;
-
-    /**
-     * Generic disconnect reason indicating the ACL disconnected due to an error on the remote
-     * device.
-     * <p>
-     * Example solution: Prompt the user to check their remote device (e.g., headset, car
-     * headunit, watch).
-     *
-     * @hide
-     */
-    public static final int ERROR_DISCONNECT_REASON_REMOTE = 1103;
-
-    /**
-     * Indicates that the ACL disconnected due to a timeout.
-     * <p>
-     * Example cause: remote device might be out of range.
-     * <p>
-     * Example solution: Prompt user to verify their remote device is on or in
-     * connection/pairing mode.
-     *
-     * @hide
-     */
-    public static final int ERROR_DISCONNECT_REASON_TIMEOUT = 1104;
-
-    /**
-     * Indicates that the ACL disconnected due to link key issues.
-     * <p>
-     * Example cause: Devices are either unpaired or remote device is refusing our pairing
-     * request.
-     * <p>
-     * Example solution: Prompt user to unpair and pair again.
-     *
-     * @hide
-     */
-    public static final int ERROR_DISCONNECT_REASON_SECURITY = 1105;
-
-    /**
-     * Indicates that the ACL disconnected due to the local device's system policy.
-     * <p>
-     * Example cause: privacy policy, power management policy, permissions, etc.
-     * <p>
-     * Example solution: Prompt the user to check settings, or check with their system
-     * administrator (e.g. some corp-managed devices do not allow OPP connection).
-     *
-     * @hide
-     */
-    public static final int ERROR_DISCONNECT_REASON_SYSTEM_POLICY = 1106;
-
-    /**
-     * Indicates that the ACL disconnected due to resource constraints, either on the local
-     * device or the remote device.
-     * <p>
-     * Example cause: controller is busy, memory limit reached, maximum number of connections
-     * reached.
-     * <p>
-     * Example solution: The app should wait and try again. If still failing, prompt the user
-     * to disconnect some devices, or toggle Bluetooth on the local and/or the remote device.
-     *
-     * @hide
-     */
-    public static final int ERROR_DISCONNECT_REASON_RESOURCE_LIMIT_REACHED = 1107;
-
-    /**
-     * Indicates that the ACL disconnected because another ACL connection already exists.
-     *
-     * @hide
-     */
-    public static final int ERROR_DISCONNECT_REASON_CONNECTION_ALREADY_EXISTS = 1108;
-
-    /**
-     * Indicates that the ACL disconnected due to incorrect parameters passed in from the app.
-     * <p>
-     * Example solution: Change parameters and try again. If error persists, the app can report
-     * telemetry and/or log the error in a bugreport.
-     *
-     * @hide
-     */
-    public static final int ERROR_DISCONNECT_REASON_BAD_PARAMETERS = 1109;
-
-    /**
-     * Indicates that setting the LE Audio Broadcast mode failed.
-     * <p>
-     * Example solution: Change parameters and try again. If error persists, the app can report
-     * telemetry and/or log the error in a bugreport.
-     *
-     * @hide
-     */
-    public static final int ERROR_LE_AUDIO_BROADCAST_SOURCE_SET_BROADCAST_MODE_FAILED = 1110;
-
-    /**
-     * Indicates that setting a new encryption key for Bluetooth LE Audio Broadcast Source failed.
-     * <p>
-     * Example solution: Change parameters and try again. If error persists, the app can report
-     * telemetry and/or log the error in a bugreport.
-     *
-     * @hide
-     */
-    public static final int ERROR_LE_AUDIO_BROADCAST_SOURCE_SET_ENCRYPTION_KEY_FAILED = 1111;
-
-    /**
-     * Indicates that connecting to a remote Broadcast Audio Scan Service failed.
-     * <p>
-     * Example solution: Change parameters and try again. If error persists, the app can report
-     * telemetry and/or log the error in a bugreport.
-     *
-     * @hide
-     */
-    public static final int ERROR_LE_AUDIO_BROADCAST_AUDIO_SCAN_SERVICE_CONNECT_FAILED = 1112;
-
-    /**
-     * Indicates that disconnecting from a remote Broadcast Audio Scan Service failed.
-     * <p>
-     * Example solution: Change parameters and try again. If error persists, the app can report
-     * telemetry and/or log the error in a bugreport.
-     *
-     * @hide
-     */
-    public static final int ERROR_LE_AUDIO_BROADCAST_AUDIO_SCAN_SERVICE_DISCONNECT_FAILED = 1113;
-
-    /**
-     * Indicates that enabling LE Audio Broadcast encryption failed
-     * <p>
-     * Example solution: Change parameters and try again. If error persists, the app can report
-     * telemetry and/or log the error in a bugreport.
-     *
-     * @hide
-     */
-    public static final int ERROR_LE_AUDIO_BROADCAST_SOURCE_ENABLE_ENCRYPTION_FAILED = 1114;
-
-    /**
-     * Indicates that disabling LE Audio Broadcast encryption failed
-     * <p>
-     * Example solution: Change parameters and try again. If error persists, the app can report
-     * telemetry and/or log the error in a bugreport.
-     *
-     * @hide
-     */
-    public static final int ERROR_LE_AUDIO_BROADCAST_SOURCE_DISABLE_ENCRYPTION_FAILED = 1115;
-
-    /**
-     * Indicates that an unknown error has occurred has occurred.
-     */
-    public static final int ERROR_UNKNOWN = Integer.MAX_VALUE;
-}
diff --git a/core/java/android/bluetooth/BluetoothUtils.java b/core/java/android/bluetooth/BluetoothUtils.java
deleted file mode 100644
index 8674692..0000000
--- a/core/java/android/bluetooth/BluetoothUtils.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-import java.time.Duration;
-
-/**
- * {@hide}
- */
-public final class BluetoothUtils {
-    /**
-     * This utility class cannot be instantiated
-     */
-    private BluetoothUtils() {}
-
-    /**
-     * Timeout value for synchronous binder call
-     */
-    private static final Duration SYNC_CALLS_TIMEOUT = Duration.ofSeconds(5);
-
-    /**
-     * @return timeout value for synchronous binder call
-     */
-    static Duration getSyncTimeout() {
-        return SYNC_CALLS_TIMEOUT;
-    }
-}
diff --git a/core/java/android/bluetooth/BluetoothUuid.java b/core/java/android/bluetooth/BluetoothUuid.java
deleted file mode 100644
index 2a8ff51..0000000
--- a/core/java/android/bluetooth/BluetoothUuid.java
+++ /dev/null
@@ -1,394 +0,0 @@
-/*
- * Copyright (C) 2009 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.bluetooth;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SuppressLint;
-import android.annotation.SystemApi;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.os.ParcelUuid;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.UUID;
-
-/**
- * Static helper methods and constants to decode the ParcelUuid of remote devices.
- *
- * @hide
- */
-@SystemApi
-@SuppressLint("AndroidFrameworkBluetoothPermission")
-public final class BluetoothUuid {
-
-    /* See Bluetooth Assigned Numbers document - SDP section, to get the values of UUIDs
-     * for the various services.
-     *
-     * The following 128 bit values are calculated as:
-     *  uuid * 2^96 + BASE_UUID
-     */
-
-    /** @hide */
-    @NonNull
-    @SystemApi
-    public static final ParcelUuid A2DP_SINK =
-            ParcelUuid.fromString("0000110B-0000-1000-8000-00805F9B34FB");
-    /** @hide */
-    @NonNull
-    @SystemApi
-    public static final ParcelUuid A2DP_SOURCE =
-            ParcelUuid.fromString("0000110A-0000-1000-8000-00805F9B34FB");
-    /** @hide */
-    @NonNull
-    @SystemApi
-    public static final ParcelUuid ADV_AUDIO_DIST =
-            ParcelUuid.fromString("0000110D-0000-1000-8000-00805F9B34FB");
-    /** @hide */
-    @NonNull
-    @SystemApi
-    public static final ParcelUuid HSP =
-            ParcelUuid.fromString("00001108-0000-1000-8000-00805F9B34FB");
-    /** @hide */
-    @NonNull
-    @SystemApi
-    public static final ParcelUuid HSP_AG =
-            ParcelUuid.fromString("00001112-0000-1000-8000-00805F9B34FB");
-    /** @hide */
-    @NonNull
-    @SystemApi
-    public static final ParcelUuid HFP =
-            ParcelUuid.fromString("0000111E-0000-1000-8000-00805F9B34FB");
-    /** @hide */
-    @NonNull
-    @SystemApi
-    public static final ParcelUuid HFP_AG =
-            ParcelUuid.fromString("0000111F-0000-1000-8000-00805F9B34FB");
-    /** @hide */
-    @NonNull
-    @SystemApi
-    public static final ParcelUuid AVRCP_CONTROLLER =
-            ParcelUuid.fromString("0000110E-0000-1000-8000-00805F9B34FB");
-    /** @hide */
-    @NonNull
-    @SystemApi
-    public static final ParcelUuid AVRCP_TARGET =
-            ParcelUuid.fromString("0000110C-0000-1000-8000-00805F9B34FB");
-    /** @hide */
-    @NonNull
-    @SystemApi
-    public static final ParcelUuid OBEX_OBJECT_PUSH =
-            ParcelUuid.fromString("00001105-0000-1000-8000-00805f9b34fb");
-    /** @hide */
-    @NonNull
-    @SystemApi
-    public static final ParcelUuid HID =
-            ParcelUuid.fromString("00001124-0000-1000-8000-00805f9b34fb");
-    /** @hide */
-    @NonNull
-    @SystemApi
-    public static final ParcelUuid HOGP =
-            ParcelUuid.fromString("00001812-0000-1000-8000-00805f9b34fb");
-    /** @hide */
-    @NonNull
-    @SystemApi
-    public static final ParcelUuid PANU =
-            ParcelUuid.fromString("00001115-0000-1000-8000-00805F9B34FB");
-    /** @hide */
-    @NonNull
-    @SystemApi
-    public static final ParcelUuid NAP =
-            ParcelUuid.fromString("00001116-0000-1000-8000-00805F9B34FB");
-    /** @hide */
-    @NonNull
-    @SystemApi
-    public static final ParcelUuid BNEP =
-            ParcelUuid.fromString("0000000f-0000-1000-8000-00805F9B34FB");
-    /** @hide */
-    @NonNull
-    @SystemApi
-    public static final ParcelUuid PBAP_PCE =
-            ParcelUuid.fromString("0000112e-0000-1000-8000-00805F9B34FB");
-    /** @hide */
-    @NonNull
-    @SystemApi
-    public static final ParcelUuid PBAP_PSE =
-            ParcelUuid.fromString("0000112f-0000-1000-8000-00805F9B34FB");
-    /** @hide */
-    @NonNull
-    @SystemApi
-    public static final ParcelUuid MAP =
-            ParcelUuid.fromString("00001134-0000-1000-8000-00805F9B34FB");
-    /** @hide */
-    @NonNull
-    @SystemApi
-    public static final ParcelUuid MNS =
-            ParcelUuid.fromString("00001133-0000-1000-8000-00805F9B34FB");
-    /** @hide */
-    @NonNull
-    @SystemApi
-    public static final ParcelUuid MAS =
-            ParcelUuid.fromString("00001132-0000-1000-8000-00805F9B34FB");
-    /** @hide */
-    @NonNull
-    @SystemApi
-    public static final ParcelUuid SAP =
-            ParcelUuid.fromString("0000112D-0000-1000-8000-00805F9B34FB");
-    /** @hide */
-    @NonNull
-    @SystemApi
-    public static final ParcelUuid HEARING_AID =
-            ParcelUuid.fromString("0000FDF0-0000-1000-8000-00805f9b34fb");
-    /** @hide */
-    @NonNull
-    @SystemApi
-    public static final ParcelUuid LE_AUDIO =
-            ParcelUuid.fromString("0000184E-0000-1000-8000-00805F9B34FB");
-    /** @hide */
-    @NonNull
-    @SystemApi
-    public static final ParcelUuid DIP =
-            ParcelUuid.fromString("00001200-0000-1000-8000-00805F9B34FB");
-    /** @hide */
-    @NonNull
-    @SystemApi
-    public static final ParcelUuid VOLUME_CONTROL =
-            ParcelUuid.fromString("00001844-0000-1000-8000-00805F9B34FB");
-    /** @hide */
-    @NonNull
-    @SystemApi
-    public static final ParcelUuid GENERIC_MEDIA_CONTROL =
-            ParcelUuid.fromString("00001849-0000-1000-8000-00805F9B34FB");
-    /** @hide */
-    @NonNull
-    @SystemApi
-    public static final ParcelUuid MEDIA_CONTROL =
-            ParcelUuid.fromString("00001848-0000-1000-8000-00805F9B34FB");
-    /** @hide */
-    @NonNull
-    @SystemApi
-    public static final ParcelUuid COORDINATED_SET =
-            ParcelUuid.fromString("00001846-0000-1000-8000-00805F9B34FB");
-    /** @hide */
-    @NonNull
-    @SystemApi
-    public static final ParcelUuid CAP =
-            ParcelUuid.fromString("00001853-0000-1000-8000-00805F9B34FB");
-    /** @hide */
-    @NonNull
-    @SystemApi
-    public static final ParcelUuid BASE_UUID =
-            ParcelUuid.fromString("00000000-0000-1000-8000-00805F9B34FB");
-
-    /**
-     * Length of bytes for 16 bit UUID
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int UUID_BYTES_16_BIT = 2;
-    /**
-     * Length of bytes for 32 bit UUID
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int UUID_BYTES_32_BIT = 4;
-    /**
-     * Length of bytes for 128 bit UUID
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int UUID_BYTES_128_BIT = 16;
-
-    /**
-     * Returns true if there any common ParcelUuids in uuidA and uuidB.
-     *
-     * @param uuidA - List of ParcelUuids
-     * @param uuidB - List of ParcelUuids
-     *
-     * @hide
-     */
-    @SystemApi
-    public static boolean containsAnyUuid(@Nullable ParcelUuid[] uuidA,
-            @Nullable ParcelUuid[] uuidB) {
-        if (uuidA == null && uuidB == null) return true;
-
-        if (uuidA == null) {
-            return uuidB.length == 0;
-        }
-
-        if (uuidB == null) {
-            return uuidA.length == 0;
-        }
-
-        HashSet<ParcelUuid> uuidSet = new HashSet<ParcelUuid>(Arrays.asList(uuidA));
-        for (ParcelUuid uuid : uuidB) {
-            if (uuidSet.contains(uuid)) return true;
-        }
-        return false;
-    }
-
-    /**
-     * Extract the Service Identifier or the actual uuid from the Parcel Uuid.
-     * For example, if 0000110B-0000-1000-8000-00805F9B34FB is the parcel Uuid,
-     * this function will return 110B
-     *
-     * @param parcelUuid
-     * @return the service identifier.
-     */
-    private static int getServiceIdentifierFromParcelUuid(ParcelUuid parcelUuid) {
-        UUID uuid = parcelUuid.getUuid();
-        long value = (uuid.getMostSignificantBits() & 0xFFFFFFFF00000000L) >>> 32;
-        return (int) value;
-    }
-
-    /**
-     * Parse UUID from bytes. The {@code uuidBytes} can represent a 16-bit, 32-bit or 128-bit UUID,
-     * but the returned UUID is always in 128-bit format.
-     * Note UUID is little endian in Bluetooth.
-     *
-     * @param uuidBytes Byte representation of uuid.
-     * @return {@link ParcelUuid} parsed from bytes.
-     * @throws IllegalArgumentException If the {@code uuidBytes} cannot be parsed.
-     *
-     * @hide
-     */
-    @NonNull
-    @SystemApi
-    public static ParcelUuid parseUuidFrom(@Nullable byte[] uuidBytes) {
-        if (uuidBytes == null) {
-            throw new IllegalArgumentException("uuidBytes cannot be null");
-        }
-        int length = uuidBytes.length;
-        if (length != UUID_BYTES_16_BIT && length != UUID_BYTES_32_BIT
-                && length != UUID_BYTES_128_BIT) {
-            throw new IllegalArgumentException("uuidBytes length invalid - " + length);
-        }
-
-        // Construct a 128 bit UUID.
-        if (length == UUID_BYTES_128_BIT) {
-            ByteBuffer buf = ByteBuffer.wrap(uuidBytes).order(ByteOrder.LITTLE_ENDIAN);
-            long msb = buf.getLong(8);
-            long lsb = buf.getLong(0);
-            return new ParcelUuid(new UUID(msb, lsb));
-        }
-
-        // For 16 bit and 32 bit UUID we need to convert them to 128 bit value.
-        // 128_bit_value = uuid * 2^96 + BASE_UUID
-        long shortUuid;
-        if (length == UUID_BYTES_16_BIT) {
-            shortUuid = uuidBytes[0] & 0xFF;
-            shortUuid += (uuidBytes[1] & 0xFF) << 8;
-        } else {
-            shortUuid = uuidBytes[0] & 0xFF;
-            shortUuid += (uuidBytes[1] & 0xFF) << 8;
-            shortUuid += (uuidBytes[2] & 0xFF) << 16;
-            shortUuid += (uuidBytes[3] & 0xFF) << 24;
-        }
-        long msb = BASE_UUID.getUuid().getMostSignificantBits() + (shortUuid << 32);
-        long lsb = BASE_UUID.getUuid().getLeastSignificantBits();
-        return new ParcelUuid(new UUID(msb, lsb));
-    }
-
-    /**
-     * Parse UUID to bytes. The returned value is shortest representation, a 16-bit, 32-bit or
-     * 128-bit UUID, Note returned value is little endian (Bluetooth).
-     *
-     * @param uuid uuid to parse.
-     * @return shortest representation of {@code uuid} as bytes.
-     * @throws IllegalArgumentException If the {@code uuid} is null.
-     *
-     * @hide
-     */
-    public static byte[] uuidToBytes(ParcelUuid uuid) {
-        if (uuid == null) {
-            throw new IllegalArgumentException("uuid cannot be null");
-        }
-
-        if (is16BitUuid(uuid)) {
-            byte[] uuidBytes = new byte[UUID_BYTES_16_BIT];
-            int uuidVal = getServiceIdentifierFromParcelUuid(uuid);
-            uuidBytes[0] = (byte) (uuidVal & 0xFF);
-            uuidBytes[1] = (byte) ((uuidVal & 0xFF00) >> 8);
-            return uuidBytes;
-        }
-
-        if (is32BitUuid(uuid)) {
-            byte[] uuidBytes = new byte[UUID_BYTES_32_BIT];
-            int uuidVal = getServiceIdentifierFromParcelUuid(uuid);
-            uuidBytes[0] = (byte) (uuidVal & 0xFF);
-            uuidBytes[1] = (byte) ((uuidVal & 0xFF00) >> 8);
-            uuidBytes[2] = (byte) ((uuidVal & 0xFF0000) >> 16);
-            uuidBytes[3] = (byte) ((uuidVal & 0xFF000000) >> 24);
-            return uuidBytes;
-        }
-
-        // Construct a 128 bit UUID.
-        long msb = uuid.getUuid().getMostSignificantBits();
-        long lsb = uuid.getUuid().getLeastSignificantBits();
-
-        byte[] uuidBytes = new byte[UUID_BYTES_128_BIT];
-        ByteBuffer buf = ByteBuffer.wrap(uuidBytes).order(ByteOrder.LITTLE_ENDIAN);
-        buf.putLong(8, msb);
-        buf.putLong(0, lsb);
-        return uuidBytes;
-    }
-
-    /**
-     * Check whether the given parcelUuid can be converted to 16 bit bluetooth uuid.
-     *
-     * @param parcelUuid
-     * @return true if the parcelUuid can be converted to 16 bit uuid, false otherwise.
-     *
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public static boolean is16BitUuid(ParcelUuid parcelUuid) {
-        UUID uuid = parcelUuid.getUuid();
-        if (uuid.getLeastSignificantBits() != BASE_UUID.getUuid().getLeastSignificantBits()) {
-            return false;
-        }
-        return ((uuid.getMostSignificantBits() & 0xFFFF0000FFFFFFFFL) == 0x1000L);
-    }
-
-
-    /**
-     * Check whether the given parcelUuid can be converted to 32 bit bluetooth uuid.
-     *
-     * @param parcelUuid
-     * @return true if the parcelUuid can be converted to 32 bit uuid, false otherwise.
-     *
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public static boolean is32BitUuid(ParcelUuid parcelUuid) {
-        UUID uuid = parcelUuid.getUuid();
-        if (uuid.getLeastSignificantBits() != BASE_UUID.getUuid().getLeastSignificantBits()) {
-            return false;
-        }
-        if (is16BitUuid(parcelUuid)) {
-            return false;
-        }
-        return ((uuid.getMostSignificantBits() & 0xFFFFFFFFL) == 0x1000L);
-    }
-
-    private BluetoothUuid() {}
-}
diff --git a/core/java/android/bluetooth/BluetoothVolumeControl.java b/core/java/android/bluetooth/BluetoothVolumeControl.java
deleted file mode 100644
index 27532aa..0000000
--- a/core/java/android/bluetooth/BluetoothVolumeControl.java
+++ /dev/null
@@ -1,337 +0,0 @@
-/*
- * Copyright 2021 HIMSA II K/S - www.himsa.com.
- * Represented by EHIMA - www.ehima.com
- *
- * 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.bluetooth;
-
-import static android.bluetooth.BluetoothUtils.getSyncTimeout;
-
-import android.Manifest;
-import android.annotation.IntRange;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.RequiresPermission;
-import android.annotation.SdkConstant;
-import android.annotation.SdkConstant.SdkConstantType;
-import android.annotation.SuppressLint;
-import android.annotation.SystemApi;
-import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
-import android.content.AttributionSource;
-import android.content.Context;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.util.CloseGuard;
-import android.util.Log;
-
-import com.android.modules.utils.SynchronousResultReceiver;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.TimeoutException;
-
-/**
- * This class provides the public APIs to control the Bluetooth Volume Control service.
- *
- * <p>BluetoothVolumeControl is a proxy object for controlling the Bluetooth VC
- * Service via IPC. Use {@link BluetoothAdapter#getProfileProxy} to get
- * the BluetoothVolumeControl proxy object.
- * @hide
- */
-@SystemApi
-public final class BluetoothVolumeControl implements BluetoothProfile, AutoCloseable {
-    private static final String TAG = "BluetoothVolumeControl";
-    private static final boolean DBG = true;
-    private static final boolean VDBG = false;
-
-    private CloseGuard mCloseGuard;
-
-    /**
-     * Intent used to broadcast the change in connection state of the Volume Control
-     * profile.
-     *
-     * <p>This intent will have 3 extras:
-     * <ul>
-     * <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
-     * <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li>
-     * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
-     * </ul>
-     *
-     * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
-     * {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTING},
-     * {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTING}.
-     *
-     * @hide
-     */
-    @SystemApi
-    @SuppressLint("ActionValue")
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_CONNECTION_STATE_CHANGED =
-            "android.bluetooth.volume-control.profile.action.CONNECTION_STATE_CHANGED";
-
-    private BluetoothAdapter mAdapter;
-    private final AttributionSource mAttributionSource;
-    private final BluetoothProfileConnector<IBluetoothVolumeControl> mProfileConnector =
-            new BluetoothProfileConnector(this, BluetoothProfile.VOLUME_CONTROL, TAG,
-                    IBluetoothVolumeControl.class.getName()) {
-                @Override
-                public IBluetoothVolumeControl getServiceInterface(IBinder service) {
-                    return IBluetoothVolumeControl.Stub.asInterface(service);
-                }
-            };
-
-    /**
-     * Create a BluetoothVolumeControl proxy object for interacting with the local
-     * Bluetooth Volume Control service.
-     */
-    /*package*/ BluetoothVolumeControl(Context context, ServiceListener listener,
-            BluetoothAdapter adapter) {
-        mAdapter = adapter;
-        mAttributionSource = adapter.getAttributionSource();
-        mProfileConnector.connect(context, listener);
-        mCloseGuard = new CloseGuard();
-        mCloseGuard.open("close");
-    }
-
-    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
-    protected void finalize() {
-        if (mCloseGuard != null) {
-            mCloseGuard.warnIfOpen();
-        }
-        close();
-    }
-
-    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
-    public void close() {
-        mProfileConnector.disconnect();
-    }
-
-    private IBluetoothVolumeControl getService() { return mProfileConnector.getService(); }
-
-    /**
-     * Get the list of connected devices. Currently at most one.
-     *
-     * @return list of connected devices
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public @NonNull List<BluetoothDevice> getConnectedDevices() {
-        if (DBG) log("getConnectedDevices()");
-        final IBluetoothVolumeControl service = getService();
-        final List<BluetoothDevice> defaultValue = new ArrayList<BluetoothDevice>();
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<List<BluetoothDevice>> recv =
-                        new SynchronousResultReceiver();
-                service.getConnectedDevices(mAttributionSource, recv);
-                return Attributable.setAttributionSource(
-                        recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
-                        mAttributionSource);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Get the list of devices matching specified states. Currently at most one.
-     *
-     * @return list of matching devices
-     *
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
-    public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
-        if (DBG) log("getDevicesMatchingStates()");
-        final IBluetoothVolumeControl service = getService();
-        final List<BluetoothDevice> defaultValue = new ArrayList<BluetoothDevice>();
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver<List<BluetoothDevice>> recv =
-                        new SynchronousResultReceiver();
-                service.getDevicesMatchingConnectionStates(states, mAttributionSource, recv);
-                return Attributable.setAttributionSource(
-                        recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
-                        mAttributionSource);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Get connection state of device
-     *
-     * @return device connection state
-     *
-     * @hide
-     */
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
-    public int getConnectionState(BluetoothDevice device) {
-        if (DBG) log("getConnectionState(" + device + ")");
-        final IBluetoothVolumeControl service = getService();
-        final int defaultValue = BluetoothProfile.STATE_DISCONNECTED;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
-                service.getConnectionState(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Tells remote device to set an absolute volume.
-     *
-     * @param volume Absolute volume to be set on remote device.
-     *               Minimum value is 0 and maximum value is 255
-     * @hide
-     */
-    @SystemApi
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public void setVolume(@Nullable BluetoothDevice device,
-            @IntRange(from = 0, to = 255) int volume) {
-        if (DBG) log("setVolume(" + volume + ")");
-        final IBluetoothVolumeControl service = getService();
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled()) {
-            try {
-                final SynchronousResultReceiver recv = new SynchronousResultReceiver();
-                service.setVolume(device, volume, mAttributionSource, recv);
-                recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(null);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-    }
-
-    /**
-     * Set connection policy of the profile
-     *
-     * <p> The device should already be paired.
-     * Connection policy can be one of {@link #CONNECTION_POLICY_ALLOWED},
-     * {@link #CONNECTION_POLICY_FORBIDDEN}, {@link #CONNECTION_POLICY_UNKNOWN}
-     *
-     * @param device Paired bluetooth device
-     * @param connectionPolicy is the connection policy to set to for this profile
-     * @return true if connectionPolicy is set, false on error
-     * @hide
-     */
-    @SystemApi
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public boolean setConnectionPolicy(@NonNull BluetoothDevice device,
-            @ConnectionPolicy int connectionPolicy) {
-        if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
-        final IBluetoothVolumeControl service = getService();
-        final boolean defaultValue = false;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)
-                && (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_FORBIDDEN
-                    || connectionPolicy == BluetoothProfile.CONNECTION_POLICY_ALLOWED)) {
-            try {
-                final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
-                service.setConnectionPolicy(device, connectionPolicy, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Get the connection policy of the profile.
-     *
-     * <p> The connection policy can be any of:
-     * {@link #CONNECTION_POLICY_ALLOWED}, {@link #CONNECTION_POLICY_FORBIDDEN},
-     * {@link #CONNECTION_POLICY_UNKNOWN}
-     *
-     * @param device Bluetooth device
-     * @return connection policy of the device
-     * @hide
-     */
-    @SystemApi
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public @ConnectionPolicy int getConnectionPolicy(@NonNull BluetoothDevice device) {
-        if (VDBG) log("getConnectionPolicy(" + device + ")");
-        final IBluetoothVolumeControl service = getService();
-        final int defaultValue = BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
-        if (service == null) {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) log(Log.getStackTraceString(new Throwable()));
-        } else if (isEnabled() && isValidDevice(device)) {
-            try {
-                final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
-                service.getConnectionPolicy(device, mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException | TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-            }
-        }
-        return defaultValue;
-    }
-
-    private boolean isEnabled() {
-        return mAdapter.getState() == BluetoothAdapter.STATE_ON;
-    }
-
-    private static boolean isValidDevice(@Nullable BluetoothDevice device) {
-        return device != null && BluetoothAdapter.checkBluetoothAddress(device.getAddress());
-    }
-
-    private static void log(String msg) {
-        Log.d(TAG, msg);
-    }
-}
diff --git a/core/java/android/bluetooth/BufferConstraint.java b/core/java/android/bluetooth/BufferConstraint.java
deleted file mode 100644
index cbffc78..0000000
--- a/core/java/android/bluetooth/BufferConstraint.java
+++ /dev/null
@@ -1,105 +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.
- */
-
-package android.bluetooth;
-
-import android.annotation.NonNull;
-import android.annotation.SystemApi;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Stores a codec's constraints on buffering length in milliseconds.
- *
- * {@hide}
- */
-@SystemApi
-public final class BufferConstraint implements Parcelable {
-
-    private static final String TAG = "BufferConstraint";
-    private int mDefaultMillis;
-    private int mMaxMillis;
-    private int mMinMillis;
-
-    public BufferConstraint(int defaultMillis, int maxMillis,
-            int minMillis) {
-        mDefaultMillis = defaultMillis;
-        mMaxMillis = maxMillis;
-        mMinMillis = minMillis;
-    }
-
-    BufferConstraint(Parcel in) {
-        mDefaultMillis = in.readInt();
-        mMaxMillis = in.readInt();
-        mMinMillis = in.readInt();
-    }
-
-    public static final @NonNull Parcelable.Creator<BufferConstraint> CREATOR =
-            new Parcelable.Creator<BufferConstraint>() {
-                public BufferConstraint createFromParcel(Parcel in) {
-                    return new BufferConstraint(in);
-                }
-
-                public BufferConstraint[] newArray(int size) {
-                    return new BufferConstraint[size];
-                }
-            };
-
-    @Override
-    public void writeToParcel(@NonNull Parcel out, int flags) {
-        out.writeInt(mDefaultMillis);
-        out.writeInt(mMaxMillis);
-        out.writeInt(mMinMillis);
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    /**
-     * Get the default buffer millis
-     *
-     * @return default buffer millis
-     * @hide
-     */
-    @SystemApi
-    public int getDefaultMillis() {
-        return mDefaultMillis;
-    }
-
-    /**
-     * Get the maximum buffer millis
-     *
-     * @return maximum buffer millis
-     * @hide
-     */
-    @SystemApi
-    public int getMaxMillis() {
-        return mMaxMillis;
-    }
-
-    /**
-     * Get the minimum buffer millis
-     *
-     * @return minimum buffer millis
-     * @hide
-     */
-    @SystemApi
-    public int getMinMillis() {
-        return mMinMillis;
-    }
-}
diff --git a/core/java/android/bluetooth/BufferConstraints.java b/core/java/android/bluetooth/BufferConstraints.java
deleted file mode 100644
index 97d9723..0000000
--- a/core/java/android/bluetooth/BufferConstraints.java
+++ /dev/null
@@ -1,96 +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.
- */
-
-package android.bluetooth;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-
-/**
- * A parcelable collection of buffer constraints by codec type.
- *
- * {@hide}
- */
-@SystemApi
-public final class BufferConstraints implements Parcelable {
-    public static final int BUFFER_CODEC_MAX_NUM = 32;
-
-    private static final String TAG = "BufferConstraints";
-
-    private Map<Integer, BufferConstraint> mBufferConstraints;
-    private List<BufferConstraint> mBufferConstraintList;
-
-    public BufferConstraints(@NonNull List<BufferConstraint>
-            bufferConstraintList) {
-
-        mBufferConstraintList = new ArrayList<BufferConstraint>(bufferConstraintList);
-        mBufferConstraints = new HashMap<Integer, BufferConstraint>();
-        for (int i = 0; i < BUFFER_CODEC_MAX_NUM; i++) {
-            mBufferConstraints.put(i, bufferConstraintList.get(i));
-        }
-    }
-
-    BufferConstraints(Parcel in) {
-        mBufferConstraintList = new ArrayList<BufferConstraint>();
-        mBufferConstraints = new HashMap<Integer, BufferConstraint>();
-        in.readList(mBufferConstraintList, BufferConstraint.class.getClassLoader());
-        for (int i = 0; i < mBufferConstraintList.size(); i++) {
-            mBufferConstraints.put(i, mBufferConstraintList.get(i));
-        }
-    }
-
-    public static final @NonNull Parcelable.Creator<BufferConstraints> CREATOR =
-            new Parcelable.Creator<BufferConstraints>() {
-                public BufferConstraints createFromParcel(Parcel in) {
-                    return new BufferConstraints(in);
-                }
-
-                public BufferConstraints[] newArray(int size) {
-                    return new BufferConstraints[size];
-                }
-            };
-
-    @Override
-    public void writeToParcel(@NonNull Parcel out, int flags) {
-        out.writeList(mBufferConstraintList);
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    /**
-     * Get the buffer constraints by codec type.
-     *
-     * @param codec Audio codec
-     * @return buffer constraints by codec type.
-     * @hide
-     */
-    @SystemApi
-    public @Nullable BufferConstraint forCodec(@BluetoothCodecConfig.SourceCodecType int codec) {
-        return mBufferConstraints.get(codec);
-    }
-}
diff --git a/core/java/android/bluetooth/OWNERS b/core/java/android/bluetooth/OWNERS
deleted file mode 100644
index fbee577..0000000
--- a/core/java/android/bluetooth/OWNERS
+++ /dev/null
@@ -1,6 +0,0 @@
-# Bug component: 27441
-
-rahulsabnis@google.com
-sattiraju@google.com
-siyuanh@google.com
-zachoverflow@google.com
diff --git a/core/java/android/bluetooth/OobData.java b/core/java/android/bluetooth/OobData.java
deleted file mode 100644
index bb0b956..0000000
--- a/core/java/android/bluetooth/OobData.java
+++ /dev/null
@@ -1,958 +0,0 @@
-/**
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-import static java.util.Objects.requireNonNull;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Out Of Band Data for Bluetooth device pairing.
- *
- * <p>This object represents optional data obtained from a remote device through
- * an out-of-band channel (eg. NFC, QR).
- *
- * <p>References:
- * NFC AD Forum SSP 1.1 (AD)
- * {@link https://members.nfc-forum.org//apps/group_public/download.php/24620/NFCForum-AD-BTSSP_1_1.pdf}
- * Core Specification Supplement (CSS) V9
- *
- * <p>There are several BR/EDR Examples
- *
- * <p>Negotiated Handover:
- *   Bluetooth Carrier Configuration Record:
- *    - OOB Data Length
- *    - Device Address
- *    - Class of Device
- *    - Simple Pairing Hash C
- *    - Simple Pairing Randomizer R
- *    - Service Class UUID
- *    - Bluetooth Local Name
- *
- * <p>Static Handover:
- *   Bluetooth Carrier Configuration Record:
- *    - OOB Data Length
- *    - Device Address
- *    - Class of Device
- *    - Service Class UUID
- *    - Bluetooth Local Name
- *
- * <p>Simplified Tag Format for Single BT Carrier:
- *   Bluetooth OOB Data Record:
- *    - OOB Data Length
- *    - Device Address
- *    - Class of Device
- *    - Service Class UUID
- *    - Bluetooth Local Name
- *
- * @hide
- */
-@SystemApi
-public final class OobData implements Parcelable {
-
-    private static final String TAG = "OobData";
-    /** The {@link OobData#mClassicLength} may be. (AD 3.1.1) (CSS 1.6.2) @hide */
-    @SystemApi
-    public static final int OOB_LENGTH_OCTETS = 2;
-    /**
-     * The length for the {@link OobData#mDeviceAddressWithType}(6) and Address Type(1).
-     * (AD 3.1.2) (CSS 1.6.2)
-     * @hide
-     */
-    @SystemApi
-    public static final int DEVICE_ADDRESS_OCTETS = 7;
-    /** The Class of Device is 3 octets. (AD 3.1.3) (CSS 1.6.2) @hide */
-    @SystemApi
-    public static final int CLASS_OF_DEVICE_OCTETS = 3;
-    /** The Confirmation data must be 16 octets. (AD 3.2.2) (CSS 1.6.2) @hide */
-    @SystemApi
-    public static final int CONFIRMATION_OCTETS = 16;
-    /** The Randomizer data must be 16 octets. (AD 3.2.3) (CSS 1.6.2) @hide */
-    @SystemApi
-    public static final int RANDOMIZER_OCTETS = 16;
-    /** The LE Device Role length is 1 octet. (AD 3.3.2) (CSS 1.17) @hide */
-    @SystemApi
-    public static final int LE_DEVICE_ROLE_OCTETS = 1;
-    /** The {@link OobData#mLeTemporaryKey} length. (3.4.1) @hide */
-    @SystemApi
-    public static final int LE_TK_OCTETS = 16;
-    /** The {@link OobData#mLeAppearance} length. (3.4.1) @hide */
-    @SystemApi
-    public static final int LE_APPEARANCE_OCTETS = 2;
-    /** The {@link OobData#mLeFlags} length. (3.4.1) @hide */
-    @SystemApi
-    public static final int LE_DEVICE_FLAG_OCTETS = 1; // 1 octet to hold the 0-4 value.
-
-    // Le Roles
-    /** @hide */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(
-        prefix = { "LE_DEVICE_ROLE_" },
-        value = {
-            LE_DEVICE_ROLE_PERIPHERAL_ONLY,
-            LE_DEVICE_ROLE_CENTRAL_ONLY,
-            LE_DEVICE_ROLE_BOTH_PREFER_PERIPHERAL,
-            LE_DEVICE_ROLE_BOTH_PREFER_CENTRAL
-        }
-    )
-    public @interface LeRole {}
-
-    /** @hide */
-    @SystemApi
-    public static final int LE_DEVICE_ROLE_PERIPHERAL_ONLY = 0x00;
-    /** @hide */
-    @SystemApi
-    public static final int LE_DEVICE_ROLE_CENTRAL_ONLY = 0x01;
-    /** @hide */
-    @SystemApi
-    public static final int LE_DEVICE_ROLE_BOTH_PREFER_PERIPHERAL = 0x02;
-    /** @hide */
-    @SystemApi
-    public static final int LE_DEVICE_ROLE_BOTH_PREFER_CENTRAL = 0x03;
-
-    // Le Flags
-    /** @hide */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(
-        prefix = { "LE_FLAG_" },
-        value = {
-            LE_FLAG_LIMITED_DISCOVERY_MODE,
-            LE_FLAG_GENERAL_DISCOVERY_MODE,
-            LE_FLAG_BREDR_NOT_SUPPORTED,
-            LE_FLAG_SIMULTANEOUS_CONTROLLER,
-            LE_FLAG_SIMULTANEOUS_HOST
-        }
-    )
-    public @interface LeFlag {}
-
-    /** @hide */
-    @SystemApi
-    public static final int LE_FLAG_LIMITED_DISCOVERY_MODE = 0x00;
-    /** @hide */
-    @SystemApi
-    public static final int LE_FLAG_GENERAL_DISCOVERY_MODE = 0x01;
-    /** @hide */
-    @SystemApi
-    public static final int LE_FLAG_BREDR_NOT_SUPPORTED = 0x02;
-    /** @hide */
-    @SystemApi
-    public static final int LE_FLAG_SIMULTANEOUS_CONTROLLER = 0x03;
-    /** @hide */
-    @SystemApi
-    public static final int LE_FLAG_SIMULTANEOUS_HOST = 0x04;
-
-    /**
-     * Builds an {@link OobData} object and validates that the required combination
-     * of values are present to create the LE specific OobData type.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final class LeBuilder {
-
-        /**
-         * It is recommended that this Hash C is generated anew for each
-         * pairing.
-         *
-         * <p>It should be noted that on passive NFC this isn't possible as the data is static
-         * and immutable.
-         */
-        private byte[] mConfirmationHash = null;
-
-        /**
-         * Optional, but adds more validity to the pairing.
-         *
-         * <p>If not present a value of 0 is assumed.
-         */
-        private byte[] mRandomizerHash = new byte[] {
-            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-        };
-
-        /**
-         * The Bluetooth Device user-friendly name presented over Bluetooth Technology.
-         *
-         * <p>This is the name that may be displayed to the device user as part of the UI.
-         */
-        private byte[] mDeviceName = null;
-
-        /**
-         * Sets the Bluetooth Device name to be used for UI purposes.
-         *
-         * <p>Optional attribute.
-         *
-         * @param deviceName byte array representing the name, may be 0 in length, not null.
-         *
-         * @return {@link OobData#ClassicBuilder}
-         *
-         * @throws NullPointerException if deviceName is null.
-         *
-         * @hide
-         */
-        @NonNull
-        @SystemApi
-        public LeBuilder setDeviceName(@NonNull byte[] deviceName) {
-            requireNonNull(deviceName);
-            this.mDeviceName = deviceName;
-            return this;
-        }
-
-        /**
-         * The Bluetooth Device Address is the address to which the OOB data belongs.
-         *
-         * <p>The length MUST be {@link OobData#DEVICE_ADDRESS_OCTETS} octets.
-         *
-         * <p> Address is encoded in Little Endian order.
-         *
-         * <p>e.g. 00:01:02:03:04:05 would be x05x04x03x02x01x00
-         */
-        private final byte[] mDeviceAddressWithType;
-
-        /**
-         * During an LE connection establishment, one must be in the Peripheral mode and the other
-         * in the Central role.
-         *
-         * <p>Possible Values:
-         * {@link LE_DEVICE_ROLE_PERIPHERAL_ONLY} Only Peripheral supported
-         * {@link LE_DEVICE_ROLE_CENTRAL_ONLY} Only Central supported
-         * {@link LE_DEVICE_ROLE_BOTH_PREFER_PERIPHERAL} Central & Peripheral supported;
-         * Peripheral Preferred
-         * {@link LE_DEVICE_ROLE_BOTH_PREFER_CENTRAL} Only peripheral supported; Central Preferred
-         * 0x04 - 0xFF Reserved
-         */
-        private final @LeRole int mLeDeviceRole;
-
-        /**
-         * Temporary key value from the Security Manager.
-         *
-         * <p> Must be {@link LE_TK_OCTETS} in size
-         */
-        private byte[] mLeTemporaryKey = null;
-
-        /**
-         * Defines the representation of the external appearance of the device.
-         *
-         * <p>For example, a mouse, remote control, or keyboard.
-         *
-         * <p>Used for visual on discovering device to represent icon/string/etc...
-         */
-        private byte[] mLeAppearance = null;
-
-        /**
-         * Contains which discoverable mode to use, BR/EDR support and capability.
-         *
-         * <p>Possible LE Flags:
-         * {@link LE_FLAG_LIMITED_DISCOVERY_MODE} LE Limited Discoverable Mode.
-         * {@link LE_FLAG_GENERAL_DISCOVERY_MODE} LE General Discoverable Mode.
-         * {@link LE_FLAG_BREDR_NOT_SUPPORTED} BR/EDR Not Supported. Bit 37 of
-         * LMP Feature Mask Definitions.
-         * {@link LE_FLAG_SIMULTANEOUS_CONTROLLER} Simultaneous LE and BR/EDR to
-         * Same Device Capable (Controller).
-         * Bit 49 of LMP Feature Mask Definitions.
-         * {@link LE_FLAG_SIMULTANEOUS_HOST} Simultaneous LE and BR/EDR to
-         * Same Device Capable (Host).
-         * Bit 55 of LMP Feature Mask Definitions.
-         * <b>0x05- 0x07 Reserved</b>
-         */
-        private @LeFlag int mLeFlags = LE_FLAG_GENERAL_DISCOVERY_MODE; // Invalid default
-
-        /**
-         * Main creation method for creating a LE version of {@link OobData}.
-         *
-         * <p>This object will allow the caller to call {@link LeBuilder#build()}
-         * to build the data object or add any option information to the builder.
-         *
-         * @param deviceAddressWithType the LE device address plus the address type (7 octets);
-         * not null.
-         * @param leDeviceRole whether the device supports Peripheral, Central,
-         * Both including preference; not null. (1 octet)
-         * @param confirmationHash Array consisting of {@link OobData#CONFIRMATION_OCTETS} octets
-         * of data. Data is derived from controller/host stack and is
-         * required for pairing OOB.
-         *
-         * <p>Possible Values:
-         * {@link LE_DEVICE_ROLE_PERIPHERAL_ONLY} Only Peripheral supported
-         * {@link LE_DEVICE_ROLE_CENTRAL_ONLY} Only Central supported
-         * {@link LE_DEVICE_ROLE_BOTH_PREFER_PERIPHERAL} Central & Peripheral supported;
-         * Peripheral Preferred
-         * {@link LE_DEVICE_ROLE_BOTH_PREFER_CENTRAL} Only peripheral supported; Central Preferred
-         * 0x04 - 0xFF Reserved
-         *
-         * @throws IllegalArgumentException if any of the values fail to be set.
-         * @throws NullPointerException if any argument is null.
-         *
-         * @hide
-         */
-        @SystemApi
-        public LeBuilder(@NonNull byte[] confirmationHash, @NonNull byte[] deviceAddressWithType,
-                @LeRole int leDeviceRole) {
-            requireNonNull(confirmationHash);
-            requireNonNull(deviceAddressWithType);
-            if (confirmationHash.length != OobData.CONFIRMATION_OCTETS) {
-                throw new IllegalArgumentException("confirmationHash must be "
-                    + OobData.CONFIRMATION_OCTETS + " octets in length.");
-            }
-            this.mConfirmationHash = confirmationHash;
-            if (deviceAddressWithType.length != OobData.DEVICE_ADDRESS_OCTETS) {
-                throw new IllegalArgumentException("confirmationHash must be "
-                    + OobData.DEVICE_ADDRESS_OCTETS+ " octets in length.");
-            }
-            this.mDeviceAddressWithType = deviceAddressWithType;
-            if (leDeviceRole < LE_DEVICE_ROLE_PERIPHERAL_ONLY
-                    || leDeviceRole > LE_DEVICE_ROLE_BOTH_PREFER_CENTRAL) {
-                throw new IllegalArgumentException("leDeviceRole must be a valid value.");
-            }
-            this.mLeDeviceRole = leDeviceRole;
-        }
-
-        /**
-         * Sets the Temporary Key value to be used by the LE Security Manager during
-         * LE pairing.
-         *
-         * @param leTemporaryKey byte array that shall be 16 bytes. Please see Bluetooth CSSv6,
-         * Part A 1.8 for a detailed description.
-         *
-         * @return {@link OobData#Builder}
-         *
-         * @throws IllegalArgumentException if the leTemporaryKey is an invalid format.
-         * @throws NullinterException if leTemporaryKey is null.
-         *
-         * @hide
-         */
-        @NonNull
-        @SystemApi
-        public LeBuilder setLeTemporaryKey(@NonNull byte[] leTemporaryKey) {
-            requireNonNull(leTemporaryKey);
-            if (leTemporaryKey.length != LE_TK_OCTETS) {
-                throw new IllegalArgumentException("leTemporaryKey must be "
-                        + LE_TK_OCTETS + " octets in length.");
-            }
-            this.mLeTemporaryKey = leTemporaryKey;
-            return this;
-        }
-
-        /**
-         * @param randomizerHash byte array consisting of {@link OobData#RANDOMIZER_OCTETS} octets
-         * of data. Data is derived from controller/host stack and is required for pairing OOB.
-         * Also, randomizerHash may be all 0s or null in which case it becomes all 0s.
-         *
-         * @throws IllegalArgumentException if null or incorrect length randomizerHash was passed.
-         * @throws NullPointerException if randomizerHash is null.
-         *
-         * @hide
-         */
-        @NonNull
-        @SystemApi
-        public LeBuilder setRandomizerHash(@NonNull byte[] randomizerHash) {
-            requireNonNull(randomizerHash);
-            if (randomizerHash.length != OobData.RANDOMIZER_OCTETS) {
-                throw new IllegalArgumentException("randomizerHash must be "
-                    + OobData.RANDOMIZER_OCTETS + " octets in length.");
-            }
-            this.mRandomizerHash = randomizerHash;
-            return this;
-        }
-
-        /**
-         * Sets the LE Flags necessary for the pairing scenario or discovery mode.
-         *
-         * @param leFlags enum value representing the 1 octet of data about discovery modes.
-         *
-         * <p>Possible LE Flags:
-         * {@link LE_FLAG_LIMITED_DISCOVERY_MODE} LE Limited Discoverable Mode.
-         * {@link LE_FLAG_GENERAL_DISCOVERY_MODE} LE General Discoverable Mode.
-         * {@link LE_FLAG_BREDR_NOT_SUPPORTED} BR/EDR Not Supported. Bit 37 of
-         * LMP Feature Mask Definitions.
-         * {@link LE_FLAG_SIMULTANEOUS_CONTROLLER} Simultaneous LE and BR/EDR to
-         * Same Device Capable (Controller) Bit 49 of LMP Feature Mask Definitions.
-         * {@link LE_FLAG_SIMULTANEOUS_HOST} Simultaneous LE and BR/EDR to
-         * Same Device Capable (Host).
-         * Bit 55 of LMP Feature Mask Definitions.
-         * 0x05- 0x07 Reserved
-         *
-         * @throws IllegalArgumentException for invalid flag
-         * @hide
-         */
-        @NonNull
-        @SystemApi
-        public LeBuilder setLeFlags(@LeFlag int leFlags) {
-            if (leFlags < LE_FLAG_LIMITED_DISCOVERY_MODE || leFlags > LE_FLAG_SIMULTANEOUS_HOST) {
-                throw new IllegalArgumentException("leFlags must be a valid value.");
-            }
-            this.mLeFlags = leFlags;
-            return this;
-        }
-
-        /**
-         * Validates and builds the {@link OobData} object for LE Security.
-         *
-         * @return {@link OobData} with given builder values
-         *
-         * @throws IllegalStateException if either of the 2 required fields were not set.
-         *
-         * @hide
-         */
-        @NonNull
-        @SystemApi
-        public OobData build() {
-            final OobData oob =
-                    new OobData(this.mDeviceAddressWithType, this.mLeDeviceRole,
-                            this.mConfirmationHash);
-
-            // If we have values, set them, otherwise use default
-            oob.mLeTemporaryKey =
-                    (this.mLeTemporaryKey != null) ? this.mLeTemporaryKey : oob.mLeTemporaryKey;
-            oob.mLeAppearance = (this.mLeAppearance != null)
-                    ? this.mLeAppearance : oob.mLeAppearance;
-            oob.mLeFlags = (this.mLeFlags != 0xF) ? this.mLeFlags : oob.mLeFlags;
-            oob.mDeviceName = (this.mDeviceName != null) ? this.mDeviceName : oob.mDeviceName;
-            oob.mRandomizerHash = this.mRandomizerHash;
-            return oob;
-        }
-    }
-
-    /**
-     * Builds an {@link OobData} object and validates that the required combination
-     * of values are present to create the Classic specific OobData type.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final class ClassicBuilder {
-        // Used by both Classic and LE
-        /**
-         * It is recommended that this Hash C is generated anew for each
-         * pairing.
-         *
-         * <p>It should be noted that on passive NFC this isn't possible as the data is static
-         * and immutable.
-         *
-         * @hide
-         */
-        private byte[] mConfirmationHash = null;
-
-        /**
-         * Optional, but adds more validity to the pairing.
-         *
-         * <p>If not present a value of 0 is assumed.
-         *
-         * @hide
-         */
-        private byte[] mRandomizerHash = new byte[] {
-            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-        };
-
-        /**
-         * The Bluetooth Device user-friendly name presented over Bluetooth Technology.
-         *
-         * <p>This is the name that may be displayed to the device user as part of the UI.
-         *
-         * @hide
-         */
-        private byte[] mDeviceName = null;
-
-        /**
-         * This length value provides the absolute length of total OOB data block used for
-         * Bluetooth BR/EDR
-         *
-         * <p>OOB communication, which includes the length field itself and the Bluetooth
-         * Device Address.
-         *
-         * <p>The minimum length that may be represented in this field is 8.
-         *
-         * @hide
-         */
-        private final byte[] mClassicLength;
-
-        /**
-         * The Bluetooth Device Address is the address to which the OOB data belongs.
-         *
-         * <p>The length MUST be {@link OobData#DEVICE_ADDRESS_OCTETS} octets.
-         *
-         * <p> Address is encoded in Little Endian order.
-         *
-         * <p>e.g. 00:01:02:03:04:05 would be x05x04x03x02x01x00
-         *
-         * @hide
-         */
-        private final byte[] mDeviceAddressWithType;
-
-        /**
-         * Class of Device information is to be used to provide a graphical representation
-         * to the user as part of UI involving operations.
-         *
-         * <p>This is not to be used to determine a particular service can be used.
-         *
-         * <p>The length MUST be {@link OobData#CLASS_OF_DEVICE_OCTETS} octets.
-         *
-         * @hide
-         */
-        private byte[] mClassOfDevice = null;
-
-        /**
-         * Main creation method for creating a Classic version of {@link OobData}.
-         *
-         * <p>This object will allow the caller to call {@link ClassicBuilder#build()}
-         * to build the data object or add any option information to the builder.
-         *
-         * @param confirmationHash byte array consisting of {@link OobData#CONFIRMATION_OCTETS}
-         * octets of data. Data is derived from controller/host stack and is required for pairing
-         * OOB.
-         * @param classicLength byte array representing the length of data from 8-65535 across 2
-         * octets (0xXXXX).
-         * @param deviceAddressWithType byte array representing the Bluetooth Address of the device
-         * that owns the OOB data. (i.e. the originator) [6 octets]
-         *
-         * @throws IllegalArgumentException if any of the values fail to be set.
-         * @throws NullPointerException if any argument is null.
-         *
-         * @hide
-         */
-        @SystemApi
-        public ClassicBuilder(@NonNull byte[] confirmationHash, @NonNull byte[] classicLength,
-                @NonNull byte[] deviceAddressWithType) {
-            requireNonNull(confirmationHash);
-            requireNonNull(classicLength);
-            requireNonNull(deviceAddressWithType);
-            if (confirmationHash.length != OobData.CONFIRMATION_OCTETS) {
-                throw new IllegalArgumentException("confirmationHash must be "
-                    + OobData.CONFIRMATION_OCTETS + " octets in length.");
-            }
-            this.mConfirmationHash = confirmationHash;
-            if (classicLength.length != OOB_LENGTH_OCTETS) {
-                throw new IllegalArgumentException("classicLength must be "
-                        + OOB_LENGTH_OCTETS + " octets in length.");
-            }
-            this.mClassicLength = classicLength;
-            if (deviceAddressWithType.length != DEVICE_ADDRESS_OCTETS) {
-                throw new IllegalArgumentException("deviceAddressWithType must be "
-                        + DEVICE_ADDRESS_OCTETS + " octets in length.");
-            }
-            this.mDeviceAddressWithType = deviceAddressWithType;
-        }
-
-        /**
-         * @param randomizerHash byte array consisting of {@link OobData#RANDOMIZER_OCTETS} octets
-         * of data. Data is derived from controller/host stack and is required for pairing OOB.
-         * Also, randomizerHash may be all 0s or null in which case it becomes all 0s.
-         *
-         * @throws IllegalArgumentException if null or incorrect length randomizerHash was passed.
-         * @throws NullPointerException if randomizerHash is null.
-         *
-         * @hide
-         */
-        @NonNull
-        @SystemApi
-        public ClassicBuilder setRandomizerHash(@NonNull byte[] randomizerHash) {
-            requireNonNull(randomizerHash);
-            if (randomizerHash.length != OobData.RANDOMIZER_OCTETS) {
-                throw new IllegalArgumentException("randomizerHash must be "
-                    + OobData.RANDOMIZER_OCTETS + " octets in length.");
-            }
-            this.mRandomizerHash = randomizerHash;
-            return this;
-        }
-
-        /**
-         * Sets the Bluetooth Device name to be used for UI purposes.
-         *
-         * <p>Optional attribute.
-         *
-         * @param deviceName byte array representing the name, may be 0 in length, not null.
-         *
-         * @return {@link OobData#ClassicBuilder}
-         *
-         * @throws NullPointerException if deviceName is null
-         *
-         * @hide
-         */
-        @NonNull
-        @SystemApi
-        public ClassicBuilder setDeviceName(@NonNull byte[] deviceName) {
-            requireNonNull(deviceName);
-            this.mDeviceName = deviceName;
-            return this;
-        }
-
-        /**
-         * Sets the Bluetooth Class of Device; used for UI purposes only.
-         *
-         * <p>Not an indicator of available services!
-         *
-         * <p>Optional attribute.
-         *
-         * @param classOfDevice byte array of {@link OobData#CLASS_OF_DEVICE_OCTETS} octets.
-         *
-         * @return {@link OobData#ClassicBuilder}
-         *
-         * @throws IllegalArgumentException if length is not equal to
-         * {@link OobData#CLASS_OF_DEVICE_OCTETS} octets.
-         * @throws NullPointerException if classOfDevice is null.
-         *
-         * @hide
-         */
-        @NonNull
-        @SystemApi
-        public ClassicBuilder setClassOfDevice(@NonNull byte[] classOfDevice) {
-            requireNonNull(classOfDevice);
-            if (classOfDevice.length != OobData.CLASS_OF_DEVICE_OCTETS) {
-                throw new IllegalArgumentException("classOfDevice must be "
-                        + OobData.CLASS_OF_DEVICE_OCTETS + " octets in length.");
-            }
-            this.mClassOfDevice = classOfDevice;
-            return this;
-        }
-
-        /**
-         * Validates and builds the {@link OobDat object for Classic Security.
-         *
-         * @return {@link OobData} with previously given builder values.
-         *
-         * @hide
-         */
-        @NonNull
-        @SystemApi
-        public OobData build() {
-            final OobData oob =
-                    new OobData(this.mClassicLength, this.mDeviceAddressWithType,
-                            this.mConfirmationHash);
-            // If we have values, set them, otherwise use default
-            oob.mDeviceName = (this.mDeviceName != null) ? this.mDeviceName : oob.mDeviceName;
-            oob.mClassOfDevice = (this.mClassOfDevice != null)
-                    ? this.mClassOfDevice : oob.mClassOfDevice;
-            oob.mRandomizerHash = this.mRandomizerHash;
-            return oob;
-        }
-    }
-
-    // Members (Defaults for Optionals must be set or Parceling fails on NPE)
-    // Both
-    private final byte[] mDeviceAddressWithType;
-    private final byte[] mConfirmationHash;
-    private byte[] mRandomizerHash = new byte[] {
-        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-    };
-    // Default the name to "Bluetooth Device"
-    private byte[] mDeviceName = new byte[] {
-        // Bluetooth
-        0x42, 0x6c, 0x75, 0x65, 0x74, 0x6f, 0x6f, 0x74, 0x68,
-        // <space>Device
-        0x20, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65
-    };
-
-    // Classic
-    private final byte[] mClassicLength;
-    private byte[] mClassOfDevice = new byte[CLASS_OF_DEVICE_OCTETS];
-
-    // LE
-    private final @LeRole int mLeDeviceRole;
-    private byte[] mLeTemporaryKey = new byte[LE_TK_OCTETS];
-    private byte[] mLeAppearance = new byte[LE_APPEARANCE_OCTETS];
-    private @LeFlag int mLeFlags = LE_FLAG_LIMITED_DISCOVERY_MODE;
-
-    /**
-     * @return byte array representing the MAC address of a bluetooth device.
-     * The Address is 6 octets long with a 1 octet address type associated with the address.
-     *
-     * <p>For classic this will be 6 byte address plus the default of PUBLIC_ADDRESS Address Type.
-     * For LE there are more choices for Address Type.
-     *
-     * @hide
-     */
-    @NonNull
-    @SystemApi
-    public byte[] getDeviceAddressWithType() {
-        return mDeviceAddressWithType;
-    }
-
-    /**
-     * @return byte array representing the confirmationHash value
-     * which is used to confirm the identity to the controller.
-     *
-     * @hide
-     */
-    @NonNull
-    @SystemApi
-    public byte[] getConfirmationHash() {
-        return mConfirmationHash;
-    }
-
-    /**
-     * @return byte array representing the randomizerHash value
-     * which is used to verify the identity of the controller.
-     *
-     * @hide
-     */
-    @NonNull
-    @SystemApi
-    public byte[] getRandomizerHash() {
-        return mRandomizerHash;
-    }
-
-    /**
-     * @return Device Name used for displaying name in UI.
-     *
-     * <p>Also, this will be populated with the LE Local Name if the data is for LE.
-     *
-     * @hide
-     */
-    @Nullable
-    @SystemApi
-    public byte[] getDeviceName() {
-        return mDeviceName;
-    }
-
-    /**
-     * @return byte array representing the oob data length which is the length
-     * of all of the data including these octets.
-     *
-     * @hide
-     */
-    @NonNull
-    @SystemApi
-    public byte[] getClassicLength() {
-        return mClassicLength;
-    }
-
-    /**
-     * @return byte array representing the class of device for UI display.
-     *
-     * <p>Does not indicate services available; for display only.
-     *
-     * @hide
-     */
-    @NonNull
-    @SystemApi
-    public byte[] getClassOfDevice() {
-        return mClassOfDevice;
-    }
-
-    /**
-     * @return Temporary Key used for LE pairing.
-     *
-     * @hide
-     */
-    @Nullable
-    @SystemApi
-    public byte[] getLeTemporaryKey() {
-        return mLeTemporaryKey;
-    }
-
-    /**
-     * @return Appearance used for LE pairing. For use in UI situations
-     * when determining what sort of icons or text to display regarding
-     * the device.
-     *
-     * @hide
-     */
-    @Nullable
-    @SystemApi
-    public byte[] getLeAppearance() {
-        return mLeAppearance;
-    }
-
-    /**
-     * @return Flags used to determing discoverable mode to use, BR/EDR Support, and Capability.
-     *
-     * <p>Possible LE Flags:
-     * {@link LE_FLAG_LIMITED_DISCOVERY_MODE} LE Limited Discoverable Mode.
-     * {@link LE_FLAG_GENERAL_DISCOVERY_MODE} LE General Discoverable Mode.
-     * {@link LE_FLAG_BREDR_NOT_SUPPORTED} BR/EDR Not Supported. Bit 37 of
-     * LMP Feature Mask Definitions.
-     * {@link LE_FLAG_SIMULTANEOUS_CONTROLLER} Simultaneous LE and BR/EDR to
-     * Same Device Capable (Controller).
-     * Bit 49 of LMP Feature Mask Definitions.
-     * {@link LE_FLAG_SIMULTANEOUS_HOST} Simultaneous LE and BR/EDR to
-     * Same Device Capable (Host).
-     * Bit 55 of LMP Feature Mask Definitions.
-     * <b>0x05- 0x07 Reserved</b>
-     *
-     * @hide
-     */
-    @NonNull
-    @SystemApi
-    @LeFlag
-    public int getLeFlags() {
-        return mLeFlags;
-    }
-
-    /**
-     * @return the supported and preferred roles of the LE device.
-     *
-     * <p>Possible Values:
-     * {@link LE_DEVICE_ROLE_PERIPHERAL_ONLY} Only Peripheral supported
-     * {@link LE_DEVICE_ROLE_CENTRAL_ONLY} Only Central supported
-     * {@link LE_DEVICE_ROLE_BOTH_PREFER_PERIPHERAL} Central & Peripheral supported;
-     * Peripheral Preferred
-     * {@link LE_DEVICE_ROLE_BOTH_PREFER_CENTRAL} Only peripheral supported; Central Preferred
-     * 0x04 - 0xFF Reserved
-     *
-     * @hide
-     */
-    @NonNull
-    @SystemApi
-    @LeRole
-    public int getLeDeviceRole() {
-        return mLeDeviceRole;
-    }
-
-    /**
-     * Classic Security Constructor
-     */
-    private OobData(@NonNull byte[] classicLength, @NonNull byte[] deviceAddressWithType,
-            @NonNull byte[] confirmationHash) {
-        mClassicLength = classicLength;
-        mDeviceAddressWithType = deviceAddressWithType;
-        mConfirmationHash = confirmationHash;
-        mLeDeviceRole = -1; // Satisfy final
-    }
-
-    /**
-     * LE Security Constructor
-     */
-    private OobData(@NonNull byte[] deviceAddressWithType, @LeRole int leDeviceRole,
-            @NonNull byte[] confirmationHash) {
-        mDeviceAddressWithType = deviceAddressWithType;
-        mLeDeviceRole = leDeviceRole;
-        mConfirmationHash = confirmationHash;
-        mClassicLength = new byte[OOB_LENGTH_OCTETS]; // Satisfy final
-    }
-
-    private OobData(Parcel in) {
-        // Both
-        mDeviceAddressWithType = in.createByteArray();
-        mConfirmationHash = in.createByteArray();
-        mRandomizerHash = in.createByteArray();
-        mDeviceName = in.createByteArray();
-
-        // Classic
-        mClassicLength = in.createByteArray();
-        mClassOfDevice = in.createByteArray();
-
-        // LE
-        mLeDeviceRole = in.readInt();
-        mLeTemporaryKey = in.createByteArray();
-        mLeAppearance = in.createByteArray();
-        mLeFlags = in.readInt();
-    }
-
-    /**
-     * @hide
-     */
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    /**
-     * @hide
-     */
-    @Override
-    public void writeToParcel(@NonNull Parcel out, int flags) {
-        // Both
-        // Required
-        out.writeByteArray(mDeviceAddressWithType);
-        // Required
-        out.writeByteArray(mConfirmationHash);
-        // Optional
-        out.writeByteArray(mRandomizerHash);
-        // Optional
-        out.writeByteArray(mDeviceName);
-
-        // Classic
-        // Required
-        out.writeByteArray(mClassicLength);
-        // Optional
-        out.writeByteArray(mClassOfDevice);
-
-        // LE
-        // Required
-        out.writeInt(mLeDeviceRole);
-        // Required
-        out.writeByteArray(mLeTemporaryKey);
-        // Optional
-        out.writeByteArray(mLeAppearance);
-        // Optional
-        out.writeInt(mLeFlags);
-    }
-
-    // For Parcelable
-    public static final @android.annotation.NonNull Parcelable.Creator<OobData> CREATOR =
-            new Parcelable.Creator<OobData>() {
-        public OobData createFromParcel(Parcel in) {
-            return new OobData(in);
-        }
-
-        public OobData[] newArray(int size) {
-            return new OobData[size];
-        }
-    };
-
-    /**
-     * @return a {@link String} representation of the OobData object.
-     *
-     * @hide
-     */
-    @Override
-    @NonNull
-    public String toString() {
-        return "OobData: \n\t"
-            // Both
-            + "Device Address With Type: " +  toHexString(mDeviceAddressWithType) + "\n\t"
-            + "Confirmation: " + toHexString(mConfirmationHash) + "\n\t"
-            + "Randomizer: " + toHexString(mRandomizerHash) + "\n\t"
-            + "Device Name: " + toHexString(mDeviceName) + "\n\t"
-            // Classic
-            + "OobData Length: " +  toHexString(mClassicLength) + "\n\t"
-            + "Class of Device: " +  toHexString(mClassOfDevice) + "\n\t"
-            // LE
-            + "LE Device Role: " + toHexString(mLeDeviceRole) + "\n\t"
-            + "LE Temporary Key: " + toHexString(mLeTemporaryKey) + "\n\t"
-            + "LE Appearance: " + toHexString(mLeAppearance) + "\n\t"
-            + "LE Flags: " + toHexString(mLeFlags) + "\n\t";
-    }
-
-    @NonNull
-    private String toHexString(int b) {
-        return toHexString(new byte[] {(byte) b});
-    }
-
-    @NonNull
-    private String toHexString(byte b) {
-        return toHexString(new byte[] {b});
-    }
-
-    @NonNull
-    private String toHexString(byte[] array) {
-        if (array == null) return "null";
-        StringBuilder builder = new StringBuilder(array.length * 2);
-        for (byte b: array) {
-            builder.append(String.format("%02x", b));
-        }
-        return builder.toString();
-    }
-}
diff --git a/core/java/android/bluetooth/SdpDipRecord.java b/core/java/android/bluetooth/SdpDipRecord.java
deleted file mode 100644
index 84b0eef..0000000
--- a/core/java/android/bluetooth/SdpDipRecord.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
-* Copyright (C) 2015 Samsung System LSI
-* 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.bluetooth;
-
-import java.util.Arrays;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Data representation of a Object Push Profile Server side SDP record.
- */
-/** @hide */
-public class SdpDipRecord implements Parcelable {
-    private final int mSpecificationId;
-    private final int mVendorId;
-    private final int mVendorIdSource;
-    private final int mProductId;
-    private final int mVersion;
-    private final boolean mPrimaryRecord;
-
-    public SdpDipRecord(int specificationId,
-            int vendorId, int vendorIdSource,
-            int productId, int version,
-            boolean primaryRecord) {
-        super();
-        this.mSpecificationId = specificationId;
-        this.mVendorId = vendorId;
-        this.mVendorIdSource = vendorIdSource;
-        this.mProductId = productId;
-        this.mVersion = version;
-        this.mPrimaryRecord = primaryRecord;
-    }
-
-    public SdpDipRecord(Parcel in) {
-        this.mSpecificationId = in.readInt();
-        this.mVendorId = in.readInt();
-        this.mVendorIdSource = in.readInt();
-        this.mProductId = in.readInt();
-        this.mVersion = in.readInt();
-        this.mPrimaryRecord = in.readBoolean();
-    }
-
-    public int getSpecificationId() {
-        return mSpecificationId;
-    }
-
-    public int getVendorId() {
-        return mVendorId;
-    }
-
-    public int getVendorIdSource() {
-        return mVendorIdSource;
-    }
-
-    public int getProductId() {
-        return mProductId;
-    }
-
-    public int getVersion() {
-        return mVersion;
-    }
-
-    public boolean getPrimaryRecord() {
-        return mPrimaryRecord;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(mSpecificationId);
-        dest.writeInt(mVendorId);
-        dest.writeInt(mVendorIdSource);
-        dest.writeInt(mProductId);
-        dest.writeInt(mVersion);
-        dest.writeBoolean(mPrimaryRecord);
-    }
-
-    @Override
-    public int describeContents() {
-        /* No special objects */
-        return 0;
-    }
-
-    public static  final Parcelable.Creator CREATOR = new Parcelable.Creator() {
-        public SdpDipRecord createFromParcel(Parcel in) {
-            return new SdpDipRecord(in);
-        }
-        public SdpDipRecord[] newArray(int size) {
-            return new SdpDipRecord[size];
-        }
-    };
-}
diff --git a/core/java/android/bluetooth/SdpMasRecord.java b/core/java/android/bluetooth/SdpMasRecord.java
deleted file mode 100644
index 72d4938..0000000
--- a/core/java/android/bluetooth/SdpMasRecord.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
-* Copyright (C) 2015 Samsung System LSI
-* 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.bluetooth;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/** @hide */
-public class SdpMasRecord implements Parcelable {
-    private final int mMasInstanceId;
-    private final int mL2capPsm;
-    private final int mRfcommChannelNumber;
-    private final int mProfileVersion;
-    private final int mSupportedFeatures;
-    private final int mSupportedMessageTypes;
-    private final String mServiceName;
-
-    /** Message type */
-    public static final class MessageType {
-        public static final int EMAIL = 0x01;
-        public static final int SMS_GSM = 0x02;
-        public static final int SMS_CDMA = 0x04;
-        public static final int MMS = 0x08;
-    }
-
-    public SdpMasRecord(int masInstanceId,
-            int l2capPsm,
-            int rfcommChannelNumber,
-            int profileVersion,
-            int supportedFeatures,
-            int supportedMessageTypes,
-            String serviceName) {
-        mMasInstanceId = masInstanceId;
-        mL2capPsm = l2capPsm;
-        mRfcommChannelNumber = rfcommChannelNumber;
-        mProfileVersion = profileVersion;
-        mSupportedFeatures = supportedFeatures;
-        mSupportedMessageTypes = supportedMessageTypes;
-        mServiceName = serviceName;
-    }
-
-    public SdpMasRecord(Parcel in) {
-        mMasInstanceId = in.readInt();
-        mL2capPsm = in.readInt();
-        mRfcommChannelNumber = in.readInt();
-        mProfileVersion = in.readInt();
-        mSupportedFeatures = in.readInt();
-        mSupportedMessageTypes = in.readInt();
-        mServiceName = in.readString();
-    }
-
-    @Override
-    public int describeContents() {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    public int getMasInstanceId() {
-        return mMasInstanceId;
-    }
-
-    public int getL2capPsm() {
-        return mL2capPsm;
-    }
-
-    public int getRfcommCannelNumber() {
-        return mRfcommChannelNumber;
-    }
-
-    public int getProfileVersion() {
-        return mProfileVersion;
-    }
-
-    public int getSupportedFeatures() {
-        return mSupportedFeatures;
-    }
-
-    public int getSupportedMessageTypes() {
-        return mSupportedMessageTypes;
-    }
-
-    public boolean msgSupported(int msg) {
-        return (mSupportedMessageTypes & msg) != 0;
-    }
-
-    public String getServiceName() {
-        return mServiceName;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(mMasInstanceId);
-        dest.writeInt(mL2capPsm);
-        dest.writeInt(mRfcommChannelNumber);
-        dest.writeInt(mProfileVersion);
-        dest.writeInt(mSupportedFeatures);
-        dest.writeInt(mSupportedMessageTypes);
-        dest.writeString(mServiceName);
-    }
-
-    @Override
-    public String toString() {
-        String ret = "Bluetooth MAS SDP Record:\n";
-
-        if (mMasInstanceId != -1) {
-            ret += "Mas Instance Id: " + mMasInstanceId + "\n";
-        }
-        if (mRfcommChannelNumber != -1) {
-            ret += "RFCOMM Chan Number: " + mRfcommChannelNumber + "\n";
-        }
-        if (mL2capPsm != -1) {
-            ret += "L2CAP PSM: " + mL2capPsm + "\n";
-        }
-        if (mServiceName != null) {
-            ret += "Service Name: " + mServiceName + "\n";
-        }
-        if (mProfileVersion != -1) {
-            ret += "Profile version: " + mProfileVersion + "\n";
-        }
-        if (mSupportedMessageTypes != -1) {
-            ret += "Supported msg types: " + mSupportedMessageTypes + "\n";
-        }
-        if (mSupportedFeatures != -1) {
-            ret += "Supported features: " + mSupportedFeatures + "\n";
-        }
-        return ret;
-    }
-
-    public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
-        public SdpMasRecord createFromParcel(Parcel in) {
-            return new SdpMasRecord(in);
-        }
-
-        public SdpRecord[] newArray(int size) {
-            return new SdpRecord[size];
-        }
-    };
-}
diff --git a/core/java/android/bluetooth/SdpMnsRecord.java b/core/java/android/bluetooth/SdpMnsRecord.java
deleted file mode 100644
index a781d5d..0000000
--- a/core/java/android/bluetooth/SdpMnsRecord.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
-* Copyright (C) 2015 Samsung System LSI
-* 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.bluetooth;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/** @hide */
-public class SdpMnsRecord implements Parcelable {
-    private final int mL2capPsm;
-    private final int mRfcommChannelNumber;
-    private final int mSupportedFeatures;
-    private final int mProfileVersion;
-    private final String mServiceName;
-
-    public SdpMnsRecord(int l2capPsm,
-            int rfcommChannelNumber,
-            int profileVersion,
-            int supportedFeatures,
-            String serviceName) {
-        mL2capPsm = l2capPsm;
-        mRfcommChannelNumber = rfcommChannelNumber;
-        mSupportedFeatures = supportedFeatures;
-        mServiceName = serviceName;
-        mProfileVersion = profileVersion;
-    }
-
-    public SdpMnsRecord(Parcel in) {
-        mRfcommChannelNumber = in.readInt();
-        mL2capPsm = in.readInt();
-        mServiceName = in.readString();
-        mSupportedFeatures = in.readInt();
-        mProfileVersion = in.readInt();
-    }
-
-    @Override
-    public int describeContents() {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-
-    public int getL2capPsm() {
-        return mL2capPsm;
-    }
-
-    public int getRfcommChannelNumber() {
-        return mRfcommChannelNumber;
-    }
-
-    public int getSupportedFeatures() {
-        return mSupportedFeatures;
-    }
-
-    public String getServiceName() {
-        return mServiceName;
-    }
-
-    public int getProfileVersion() {
-        return mProfileVersion;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(mRfcommChannelNumber);
-        dest.writeInt(mL2capPsm);
-        dest.writeString(mServiceName);
-        dest.writeInt(mSupportedFeatures);
-        dest.writeInt(mProfileVersion);
-    }
-
-    public String toString() {
-        String ret = "Bluetooth MNS SDP Record:\n";
-
-        if (mRfcommChannelNumber != -1) {
-            ret += "RFCOMM Chan Number: " + mRfcommChannelNumber + "\n";
-        }
-        if (mL2capPsm != -1) {
-            ret += "L2CAP PSM: " + mL2capPsm + "\n";
-        }
-        if (mServiceName != null) {
-            ret += "Service Name: " + mServiceName + "\n";
-        }
-        if (mSupportedFeatures != -1) {
-            ret += "Supported features: " + mSupportedFeatures + "\n";
-        }
-        if (mProfileVersion != -1) {
-            ret += "Profile_version: " + mProfileVersion + "\n";
-        }
-        return ret;
-    }
-
-    public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
-        public SdpMnsRecord createFromParcel(Parcel in) {
-            return new SdpMnsRecord(in);
-        }
-
-        public SdpMnsRecord[] newArray(int size) {
-            return new SdpMnsRecord[size];
-        }
-    };
-}
diff --git a/core/java/android/bluetooth/SdpOppOpsRecord.java b/core/java/android/bluetooth/SdpOppOpsRecord.java
deleted file mode 100644
index e30745b8..0000000
--- a/core/java/android/bluetooth/SdpOppOpsRecord.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
-* Copyright (C) 2015 Samsung System LSI
-* 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.bluetooth;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.Arrays;
-
-/**
- * Data representation of a Object Push Profile Server side SDP record.
- */
-
-/** @hide */
-public class SdpOppOpsRecord implements Parcelable {
-
-    private final String mServiceName;
-    private final int mRfcommChannel;
-    private final int mL2capPsm;
-    private final int mProfileVersion;
-    private final byte[] mFormatsList;
-
-    public SdpOppOpsRecord(String serviceName, int rfcommChannel,
-            int l2capPsm, int version, byte[] formatsList) {
-        super();
-        mServiceName = serviceName;
-        mRfcommChannel = rfcommChannel;
-        mL2capPsm = l2capPsm;
-        mProfileVersion = version;
-        mFormatsList = formatsList;
-    }
-
-    public String getServiceName() {
-        return mServiceName;
-    }
-
-    public int getRfcommChannel() {
-        return mRfcommChannel;
-    }
-
-    public int getL2capPsm() {
-        return mL2capPsm;
-    }
-
-    public int getProfileVersion() {
-        return mProfileVersion;
-    }
-
-    public byte[] getFormatsList() {
-        return mFormatsList;
-    }
-
-    @Override
-    public int describeContents() {
-        /* No special objects */
-        return 0;
-    }
-
-    public SdpOppOpsRecord(Parcel in) {
-        mRfcommChannel = in.readInt();
-        mL2capPsm = in.readInt();
-        mProfileVersion = in.readInt();
-        mServiceName = in.readString();
-        int arrayLength = in.readInt();
-        if (arrayLength > 0) {
-            byte[] bytes = new byte[arrayLength];
-            in.readByteArray(bytes);
-            mFormatsList = bytes;
-        } else {
-            mFormatsList = null;
-        }
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(mRfcommChannel);
-        dest.writeInt(mL2capPsm);
-        dest.writeInt(mProfileVersion);
-        dest.writeString(mServiceName);
-        if (mFormatsList != null && mFormatsList.length > 0) {
-            dest.writeInt(mFormatsList.length);
-            dest.writeByteArray(mFormatsList);
-        } else {
-            dest.writeInt(0);
-        }
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder sb = new StringBuilder("Bluetooth OPP Server SDP Record:\n");
-        sb.append("  RFCOMM Chan Number: ").append(mRfcommChannel);
-        sb.append("\n  L2CAP PSM: ").append(mL2capPsm);
-        sb.append("\n  Profile version: ").append(mProfileVersion);
-        sb.append("\n  Service Name: ").append(mServiceName);
-        sb.append("\n  Formats List: ").append(Arrays.toString(mFormatsList));
-        return sb.toString();
-    }
-
-    public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
-        public SdpOppOpsRecord createFromParcel(Parcel in) {
-            return new SdpOppOpsRecord(in);
-        }
-
-        public SdpOppOpsRecord[] newArray(int size) {
-            return new SdpOppOpsRecord[size];
-        }
-    };
-
-}
diff --git a/core/java/android/bluetooth/SdpPseRecord.java b/core/java/android/bluetooth/SdpPseRecord.java
deleted file mode 100644
index 72249d0..0000000
--- a/core/java/android/bluetooth/SdpPseRecord.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
-* Copyright (C) 2015 Samsung System LSI
-* 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.bluetooth;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/** @hide */
-public class SdpPseRecord implements Parcelable {
-    private final int mL2capPsm;
-    private final int mRfcommChannelNumber;
-    private final int mProfileVersion;
-    private final int mSupportedFeatures;
-    private final int mSupportedRepositories;
-    private final String mServiceName;
-
-    public SdpPseRecord(int l2capPsm,
-            int rfcommChannelNumber,
-            int profileVersion,
-            int supportedFeatures,
-            int supportedRepositories,
-            String serviceName) {
-        mL2capPsm = l2capPsm;
-        mRfcommChannelNumber = rfcommChannelNumber;
-        mProfileVersion = profileVersion;
-        mSupportedFeatures = supportedFeatures;
-        mSupportedRepositories = supportedRepositories;
-        mServiceName = serviceName;
-    }
-
-    public SdpPseRecord(Parcel in) {
-        mRfcommChannelNumber = in.readInt();
-        mL2capPsm = in.readInt();
-        mProfileVersion = in.readInt();
-        mSupportedFeatures = in.readInt();
-        mSupportedRepositories = in.readInt();
-        mServiceName = in.readString();
-    }
-
-    @Override
-    public int describeContents() {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    public int getL2capPsm() {
-        return mL2capPsm;
-    }
-
-    public int getRfcommChannelNumber() {
-        return mRfcommChannelNumber;
-    }
-
-    public int getSupportedFeatures() {
-        return mSupportedFeatures;
-    }
-
-    public String getServiceName() {
-        return mServiceName;
-    }
-
-    public int getProfileVersion() {
-        return mProfileVersion;
-    }
-
-    public int getSupportedRepositories() {
-        return mSupportedRepositories;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(mRfcommChannelNumber);
-        dest.writeInt(mL2capPsm);
-        dest.writeInt(mProfileVersion);
-        dest.writeInt(mSupportedFeatures);
-        dest.writeInt(mSupportedRepositories);
-        dest.writeString(mServiceName);
-
-    }
-
-    @Override
-    public String toString() {
-        String ret = "Bluetooth MNS SDP Record:\n";
-
-        if (mRfcommChannelNumber != -1) {
-            ret += "RFCOMM Chan Number: " + mRfcommChannelNumber + "\n";
-        }
-        if (mL2capPsm != -1) {
-            ret += "L2CAP PSM: " + mL2capPsm + "\n";
-        }
-        if (mProfileVersion != -1) {
-            ret += "profile version: " + mProfileVersion + "\n";
-        }
-        if (mServiceName != null) {
-            ret += "Service Name: " + mServiceName + "\n";
-        }
-        if (mSupportedFeatures != -1) {
-            ret += "Supported features: " + mSupportedFeatures + "\n";
-        }
-        if (mSupportedRepositories != -1) {
-            ret += "Supported repositories: " + mSupportedRepositories + "\n";
-        }
-
-        return ret;
-    }
-
-    public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
-        public SdpPseRecord createFromParcel(Parcel in) {
-            return new SdpPseRecord(in);
-        }
-
-        public SdpPseRecord[] newArray(int size) {
-            return new SdpPseRecord[size];
-        }
-    };
-}
diff --git a/core/java/android/bluetooth/SdpRecord.java b/core/java/android/bluetooth/SdpRecord.java
deleted file mode 100644
index 730862e..0000000
--- a/core/java/android/bluetooth/SdpRecord.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
-* Copyright (C) 2015 Samsung System LSI
-* 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.bluetooth;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.Arrays;
-
-/** @hide */
-public class SdpRecord implements Parcelable {
-
-    private final byte[] mRawData;
-    private final int mRawSize;
-
-    @Override
-    public String toString() {
-        return "BluetoothSdpRecord [rawData=" + Arrays.toString(mRawData)
-                + ", rawSize=" + mRawSize + "]";
-    }
-
-    public SdpRecord(int sizeRecord, byte[] record) {
-        mRawData = record;
-        mRawSize = sizeRecord;
-    }
-
-    public SdpRecord(Parcel in) {
-        mRawSize = in.readInt();
-        mRawData = new byte[mRawSize];
-        in.readByteArray(mRawData);
-
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(mRawSize);
-        dest.writeByteArray(mRawData);
-
-
-    }
-
-    public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
-        public SdpRecord createFromParcel(Parcel in) {
-            return new SdpRecord(in);
-        }
-
-        public SdpRecord[] newArray(int size) {
-            return new SdpRecord[size];
-        }
-    };
-
-    public byte[] getRawData() {
-        return mRawData;
-    }
-
-    public int getRawSize() {
-        return mRawSize;
-    }
-}
diff --git a/core/java/android/bluetooth/SdpSapsRecord.java b/core/java/android/bluetooth/SdpSapsRecord.java
deleted file mode 100644
index a1e2f7b..0000000
--- a/core/java/android/bluetooth/SdpSapsRecord.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/** @hide */
-public class SdpSapsRecord implements Parcelable {
-    private final int mRfcommChannelNumber;
-    private final int mProfileVersion;
-    private final String mServiceName;
-
-    public SdpSapsRecord(int rfcommChannelNumber, int profileVersion, String serviceName) {
-        mRfcommChannelNumber = rfcommChannelNumber;
-        mProfileVersion = profileVersion;
-        mServiceName = serviceName;
-    }
-
-    public SdpSapsRecord(Parcel in) {
-        mRfcommChannelNumber = in.readInt();
-        mProfileVersion = in.readInt();
-        mServiceName = in.readString();
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    public int getRfcommCannelNumber() {
-        return mRfcommChannelNumber;
-    }
-
-    public int getProfileVersion() {
-        return mProfileVersion;
-    }
-
-    public String getServiceName() {
-        return mServiceName;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(mRfcommChannelNumber);
-        dest.writeInt(mProfileVersion);
-        dest.writeString(mServiceName);
-
-    }
-
-    @Override
-    public String toString() {
-        String ret = "Bluetooth MAS SDP Record:\n";
-
-        if (mRfcommChannelNumber != -1) {
-            ret += "RFCOMM Chan Number: " + mRfcommChannelNumber + "\n";
-        }
-        if (mServiceName != null) {
-            ret += "Service Name: " + mServiceName + "\n";
-        }
-        if (mProfileVersion != -1) {
-            ret += "Profile version: " + mProfileVersion + "\n";
-        }
-        return ret;
-    }
-
-    public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
-        public SdpSapsRecord createFromParcel(Parcel in) {
-            return new SdpSapsRecord(in);
-        }
-
-        public SdpRecord[] newArray(int size) {
-            return new SdpRecord[size];
-        }
-    };
-}
diff --git a/core/java/android/bluetooth/UidTraffic.java b/core/java/android/bluetooth/UidTraffic.java
deleted file mode 100644
index 9982fa6..0000000
--- a/core/java/android/bluetooth/UidTraffic.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.bluetooth;
-
-import android.annotation.SystemApi;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Record of data traffic (in bytes) by an application identified by its UID.
- *
- * @hide
- */
-@SystemApi(client = SystemApi.Client.PRIVILEGED_APPS)
-public final class UidTraffic implements Cloneable, Parcelable {
-    private final int mAppUid;
-    private long mRxBytes;
-    private long mTxBytes;
-
-    /** @hide */
-    public UidTraffic(int appUid, long rx, long tx) {
-        mAppUid = appUid;
-        mRxBytes = rx;
-        mTxBytes = tx;
-    }
-
-    /** @hide */
-    private UidTraffic(Parcel in) {
-        mAppUid = in.readInt();
-        mRxBytes = in.readLong();
-        mTxBytes = in.readLong();
-    }
-
-    /** @hide */
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(mAppUid);
-        dest.writeLong(mRxBytes);
-        dest.writeLong(mTxBytes);
-    }
-
-    /** @hide */
-    public void setRxBytes(long bytes) {
-        mRxBytes = bytes;
-    }
-
-    /** @hide */
-    public void setTxBytes(long bytes) {
-        mTxBytes = bytes;
-    }
-
-    /** @hide */
-    public void addRxBytes(long bytes) {
-        mRxBytes += bytes;
-    }
-
-    /** @hide */
-    public void addTxBytes(long bytes) {
-        mTxBytes += bytes;
-    }
-
-    /**
-     * @return corresponding app Uid
-     */
-    public int getUid() {
-        return mAppUid;
-    }
-
-    /**
-     * @return rx bytes count
-     */
-    public long getRxBytes() {
-        return mRxBytes;
-    }
-
-    /**
-     * @return tx bytes count
-     */
-    public long getTxBytes() {
-        return mTxBytes;
-    }
-
-    /** @hide */
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    /** @hide */
-    @Override
-    public UidTraffic clone() {
-        return new UidTraffic(mAppUid, mRxBytes, mTxBytes);
-    }
-
-    /** @hide */
-    @Override
-    public String toString() {
-        return "UidTraffic{mAppUid=" + mAppUid + ", mRxBytes=" + mRxBytes + ", mTxBytes="
-                + mTxBytes + '}';
-    }
-
-    public static final @android.annotation.NonNull Creator<UidTraffic> CREATOR = new Creator<UidTraffic>() {
-        @Override
-        public UidTraffic createFromParcel(Parcel source) {
-            return new UidTraffic(source);
-        }
-
-        @Override
-        public UidTraffic[] newArray(int size) {
-            return new UidTraffic[size];
-        }
-    };
-}
diff --git a/core/java/android/bluetooth/annotations/RequiresBluetoothAdvertisePermission.java b/core/java/android/bluetooth/annotations/RequiresBluetoothAdvertisePermission.java
deleted file mode 100644
index c508c2c..0000000
--- a/core/java/android/bluetooth/annotations/RequiresBluetoothAdvertisePermission.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.annotations;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import android.Manifest;
-import android.os.Build;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * @memberDoc For apps targeting {@link Build.VERSION_CODES#S} or or higher,
- *            this requires the {@link Manifest.permission#BLUETOOTH_ADVERTISE}
- *            permission which can be gained with
- *            {@link android.app.Activity#requestPermissions(String[], int)}.
- * @hide
- */
-@Retention(SOURCE)
-@Target({METHOD, FIELD})
-public @interface RequiresBluetoothAdvertisePermission {
-}
diff --git a/core/java/android/bluetooth/annotations/RequiresBluetoothConnectPermission.java b/core/java/android/bluetooth/annotations/RequiresBluetoothConnectPermission.java
deleted file mode 100644
index e159eaa..0000000
--- a/core/java/android/bluetooth/annotations/RequiresBluetoothConnectPermission.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.annotations;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import android.Manifest;
-import android.os.Build;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * @memberDoc For apps targeting {@link Build.VERSION_CODES#S} or or higher,
- *            this requires the {@link Manifest.permission#BLUETOOTH_CONNECT}
- *            permission which can be gained with
- *            {@link android.app.Activity#requestPermissions(String[], int)}.
- * @hide
- */
-@Retention(SOURCE)
-@Target({METHOD, FIELD})
-public @interface RequiresBluetoothConnectPermission {
-}
diff --git a/core/java/android/bluetooth/annotations/RequiresBluetoothLocationPermission.java b/core/java/android/bluetooth/annotations/RequiresBluetoothLocationPermission.java
deleted file mode 100644
index 2bb3204..0000000
--- a/core/java/android/bluetooth/annotations/RequiresBluetoothLocationPermission.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.annotations;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import android.Manifest;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * @memberDoc In addition, this requires either the
- *            {@link Manifest.permission#ACCESS_FINE_LOCATION}
- *            permission or a strong assertion that you will never derive the
- *            physical location of the device. You can make this assertion by
- *            declaring {@code usesPermissionFlags="neverForLocation"} on the
- *            relevant {@code <uses-permission>} manifest tag, but it may
- *            restrict the types of Bluetooth devices you can interact with.
- * @hide
- */
-@Retention(SOURCE)
-@Target({METHOD, FIELD})
-public @interface RequiresBluetoothLocationPermission {
-}
diff --git a/core/java/android/bluetooth/annotations/RequiresBluetoothScanPermission.java b/core/java/android/bluetooth/annotations/RequiresBluetoothScanPermission.java
deleted file mode 100644
index 800ff39..0000000
--- a/core/java/android/bluetooth/annotations/RequiresBluetoothScanPermission.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.annotations;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import android.Manifest;
-import android.os.Build;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * @memberDoc For apps targeting {@link Build.VERSION_CODES#S} or or higher,
- *            this requires the {@link Manifest.permission#BLUETOOTH_SCAN}
- *            permission which can be gained with
- *            {@link android.app.Activity#requestPermissions(String[], int)}.
- * @hide
- */
-@Retention(SOURCE)
-@Target({METHOD, FIELD})
-public @interface RequiresBluetoothScanPermission {
-}
diff --git a/core/java/android/bluetooth/annotations/RequiresLegacyBluetoothAdminPermission.java b/core/java/android/bluetooth/annotations/RequiresLegacyBluetoothAdminPermission.java
deleted file mode 100644
index 9adf695..0000000
--- a/core/java/android/bluetooth/annotations/RequiresLegacyBluetoothAdminPermission.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.annotations;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import android.Manifest;
-import android.os.Build;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * @memberDoc For apps targeting {@link Build.VERSION_CODES#R} or lower, this
- *            requires the {@link Manifest.permission#BLUETOOTH_ADMIN}
- *            permission which can be gained with a simple
- *            {@code <uses-permission>} manifest tag.
- * @hide
- */
-@Retention(SOURCE)
-@Target({METHOD, FIELD})
-public @interface RequiresLegacyBluetoothAdminPermission {
-}
diff --git a/core/java/android/bluetooth/annotations/RequiresLegacyBluetoothPermission.java b/core/java/android/bluetooth/annotations/RequiresLegacyBluetoothPermission.java
deleted file mode 100644
index 79621c3..0000000
--- a/core/java/android/bluetooth/annotations/RequiresLegacyBluetoothPermission.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.annotations;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import android.Manifest;
-import android.os.Build;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * @memberDoc For apps targeting {@link Build.VERSION_CODES#R} or lower, this
- *            requires the {@link Manifest.permission#BLUETOOTH} permission
- *            which can be gained with a simple {@code <uses-permission>}
- *            manifest tag.
- * @hide
- */
-@Retention(SOURCE)
-@Target({METHOD, FIELD})
-public @interface RequiresLegacyBluetoothPermission {
-}
diff --git a/core/java/android/bluetooth/le/AdvertiseCallback.java b/core/java/android/bluetooth/le/AdvertiseCallback.java
deleted file mode 100644
index 4fa8c4f..0000000
--- a/core/java/android/bluetooth/le/AdvertiseCallback.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.le;
-
-/**
- * Bluetooth LE advertising callbacks, used to deliver advertising operation status.
- */
-public abstract class AdvertiseCallback {
-
-    /**
-     * The requested operation was successful.
-     *
-     * @hide
-     */
-    public static final int ADVERTISE_SUCCESS = 0;
-
-    /**
-     * Failed to start advertising as the advertise data to be broadcasted is larger than 31 bytes.
-     */
-    public static final int ADVERTISE_FAILED_DATA_TOO_LARGE = 1;
-
-    /**
-     * Failed to start advertising because no advertising instance is available.
-     */
-    public static final int ADVERTISE_FAILED_TOO_MANY_ADVERTISERS = 2;
-
-    /**
-     * Failed to start advertising as the advertising is already started.
-     */
-    public static final int ADVERTISE_FAILED_ALREADY_STARTED = 3;
-
-    /**
-     * Operation failed due to an internal error.
-     */
-    public static final int ADVERTISE_FAILED_INTERNAL_ERROR = 4;
-
-    /**
-     * This feature is not supported on this platform.
-     */
-    public static final int ADVERTISE_FAILED_FEATURE_UNSUPPORTED = 5;
-
-    /**
-     * Callback triggered in response to {@link BluetoothLeAdvertiser#startAdvertising} indicating
-     * that the advertising has been started successfully.
-     *
-     * @param settingsInEffect The actual settings used for advertising, which may be different from
-     * what has been requested.
-     */
-    public void onStartSuccess(AdvertiseSettings settingsInEffect) {
-    }
-
-    /**
-     * Callback when advertising could not be started.
-     *
-     * @param errorCode Error code (see ADVERTISE_FAILED_* constants) for advertising start
-     * failures.
-     */
-    public void onStartFailure(int errorCode) {
-    }
-}
diff --git a/core/java/android/bluetooth/le/AdvertiseData.java b/core/java/android/bluetooth/le/AdvertiseData.java
deleted file mode 100644
index fdf62ec..0000000
--- a/core/java/android/bluetooth/le/AdvertiseData.java
+++ /dev/null
@@ -1,374 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.le;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.os.Parcel;
-import android.os.ParcelUuid;
-import android.os.Parcelable;
-import android.util.ArrayMap;
-import android.util.SparseArray;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-
-/**
- * Advertise data packet container for Bluetooth LE advertising. This represents the data to be
- * advertised as well as the scan response data for active scans.
- * <p>
- * Use {@link AdvertiseData.Builder} to create an instance of {@link AdvertiseData} to be
- * advertised.
- *
- * @see BluetoothLeAdvertiser
- * @see ScanRecord
- */
-public final class AdvertiseData implements Parcelable {
-
-    @Nullable
-    private final List<ParcelUuid> mServiceUuids;
-
-    @NonNull
-    private final List<ParcelUuid> mServiceSolicitationUuids;
-
-    @Nullable
-    private final List<TransportDiscoveryData> mTransportDiscoveryData;
-
-    private final SparseArray<byte[]> mManufacturerSpecificData;
-    private final Map<ParcelUuid, byte[]> mServiceData;
-    private final boolean mIncludeTxPowerLevel;
-    private final boolean mIncludeDeviceName;
-
-    private AdvertiseData(List<ParcelUuid> serviceUuids,
-            List<ParcelUuid> serviceSolicitationUuids,
-            List<TransportDiscoveryData> transportDiscoveryData,
-            SparseArray<byte[]> manufacturerData,
-            Map<ParcelUuid, byte[]> serviceData,
-            boolean includeTxPowerLevel,
-            boolean includeDeviceName) {
-        mServiceUuids = serviceUuids;
-        mServiceSolicitationUuids = serviceSolicitationUuids;
-        mTransportDiscoveryData = transportDiscoveryData;
-        mManufacturerSpecificData = manufacturerData;
-        mServiceData = serviceData;
-        mIncludeTxPowerLevel = includeTxPowerLevel;
-        mIncludeDeviceName = includeDeviceName;
-    }
-
-    /**
-     * Returns a list of service UUIDs within the advertisement that are used to identify the
-     * Bluetooth GATT services.
-     */
-    public List<ParcelUuid> getServiceUuids() {
-        return mServiceUuids;
-    }
-
-    /**
-     * Returns a list of service solicitation UUIDs within the advertisement that we invite to connect.
-     */
-    @NonNull
-    public List<ParcelUuid> getServiceSolicitationUuids() {
-        return mServiceSolicitationUuids;
-    }
-
-    /**
-     * Returns a list of {@link TransportDiscoveryData} within the advertisement.
-     */
-    @NonNull
-    public List<TransportDiscoveryData> getTransportDiscoveryData() {
-        if (mTransportDiscoveryData == null) {
-            return Collections.emptyList();
-        }
-        return mTransportDiscoveryData;
-    }
-
-    /**
-     * Returns an array of manufacturer Id and the corresponding manufacturer specific data. The
-     * manufacturer id is a non-negative number assigned by Bluetooth SIG.
-     */
-    public SparseArray<byte[]> getManufacturerSpecificData() {
-        return mManufacturerSpecificData;
-    }
-
-    /**
-     * Returns a map of 16-bit UUID and its corresponding service data.
-     */
-    public Map<ParcelUuid, byte[]> getServiceData() {
-        return mServiceData;
-    }
-
-    /**
-     * Whether the transmission power level will be included in the advertisement packet.
-     */
-    public boolean getIncludeTxPowerLevel() {
-        return mIncludeTxPowerLevel;
-    }
-
-    /**
-     * Whether the device name will be included in the advertisement packet.
-     */
-    public boolean getIncludeDeviceName() {
-        return mIncludeDeviceName;
-    }
-
-    /**
-     * @hide
-     */
-    @Override
-    public int hashCode() {
-        return Objects.hash(mServiceUuids, mServiceSolicitationUuids, mTransportDiscoveryData,
-                mManufacturerSpecificData, mServiceData, mIncludeDeviceName, mIncludeTxPowerLevel);
-    }
-
-    /**
-     * @hide
-     */
-    @Override
-    public boolean equals(@Nullable Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj == null || getClass() != obj.getClass()) {
-            return false;
-        }
-        AdvertiseData other = (AdvertiseData) obj;
-        return Objects.equals(mServiceUuids, other.mServiceUuids)
-                && Objects.equals(mServiceSolicitationUuids, other.mServiceSolicitationUuids)
-                && Objects.equals(mTransportDiscoveryData, other.mTransportDiscoveryData)
-                && BluetoothLeUtils.equals(mManufacturerSpecificData,
-                    other.mManufacturerSpecificData)
-                && BluetoothLeUtils.equals(mServiceData, other.mServiceData)
-                && mIncludeDeviceName == other.mIncludeDeviceName
-                && mIncludeTxPowerLevel == other.mIncludeTxPowerLevel;
-    }
-
-    @Override
-    public String toString() {
-        return "AdvertiseData [mServiceUuids=" + mServiceUuids + ", mServiceSolicitationUuids="
-                + mServiceSolicitationUuids + ", mTransportDiscoveryData="
-                + mTransportDiscoveryData + ", mManufacturerSpecificData="
-                + BluetoothLeUtils.toString(mManufacturerSpecificData) + ", mServiceData="
-                + BluetoothLeUtils.toString(mServiceData)
-                + ", mIncludeTxPowerLevel=" + mIncludeTxPowerLevel + ", mIncludeDeviceName="
-                + mIncludeDeviceName + "]";
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeTypedArray(mServiceUuids.toArray(new ParcelUuid[mServiceUuids.size()]), flags);
-        dest.writeTypedArray(mServiceSolicitationUuids.toArray(
-                new ParcelUuid[mServiceSolicitationUuids.size()]), flags);
-
-        dest.writeTypedList(mTransportDiscoveryData);
-
-        // mManufacturerSpecificData could not be null.
-        dest.writeInt(mManufacturerSpecificData.size());
-        for (int i = 0; i < mManufacturerSpecificData.size(); ++i) {
-            dest.writeInt(mManufacturerSpecificData.keyAt(i));
-            dest.writeByteArray(mManufacturerSpecificData.valueAt(i));
-        }
-        dest.writeInt(mServiceData.size());
-        for (ParcelUuid uuid : mServiceData.keySet()) {
-            dest.writeTypedObject(uuid, flags);
-            dest.writeByteArray(mServiceData.get(uuid));
-        }
-        dest.writeByte((byte) (getIncludeTxPowerLevel() ? 1 : 0));
-        dest.writeByte((byte) (getIncludeDeviceName() ? 1 : 0));
-    }
-
-    public static final @android.annotation.NonNull Parcelable.Creator<AdvertiseData> CREATOR =
-            new Creator<AdvertiseData>() {
-                @Override
-                public AdvertiseData[] newArray(int size) {
-                    return new AdvertiseData[size];
-                }
-
-                @Override
-                public AdvertiseData createFromParcel(Parcel in) {
-                    Builder builder = new Builder();
-                    ArrayList<ParcelUuid> uuids = in.createTypedArrayList(ParcelUuid.CREATOR);
-                    for (ParcelUuid uuid : uuids) {
-                        builder.addServiceUuid(uuid);
-                    }
-
-                    ArrayList<ParcelUuid> solicitationUuids = in.createTypedArrayList(ParcelUuid.CREATOR);
-                    for (ParcelUuid uuid : solicitationUuids) {
-                        builder.addServiceSolicitationUuid(uuid);
-                    }
-
-                    List<TransportDiscoveryData> transportDiscoveryData =
-                            in.createTypedArrayList(TransportDiscoveryData.CREATOR);
-                    for (TransportDiscoveryData tdd : transportDiscoveryData) {
-                        builder.addTransportDiscoveryData(tdd);
-                    }
-
-                    int manufacturerSize = in.readInt();
-                    for (int i = 0; i < manufacturerSize; ++i) {
-                        int manufacturerId = in.readInt();
-                        byte[] manufacturerData = in.createByteArray();
-                        builder.addManufacturerData(manufacturerId, manufacturerData);
-                    }
-                    int serviceDataSize = in.readInt();
-                    for (int i = 0; i < serviceDataSize; ++i) {
-                        ParcelUuid serviceDataUuid = in.readTypedObject(ParcelUuid.CREATOR);
-                        byte[] serviceData = in.createByteArray();
-                        builder.addServiceData(serviceDataUuid, serviceData);
-                    }
-                    builder.setIncludeTxPowerLevel(in.readByte() == 1);
-                    builder.setIncludeDeviceName(in.readByte() == 1);
-                    return builder.build();
-                }
-            };
-
-    /**
-     * Builder for {@link AdvertiseData}.
-     */
-    public static final class Builder {
-        @Nullable
-        private List<ParcelUuid> mServiceUuids = new ArrayList<ParcelUuid>();
-        @NonNull
-        private List<ParcelUuid> mServiceSolicitationUuids = new ArrayList<ParcelUuid>();
-        @Nullable
-        private List<TransportDiscoveryData> mTransportDiscoveryData =
-                new ArrayList<TransportDiscoveryData>();
-        private SparseArray<byte[]> mManufacturerSpecificData = new SparseArray<byte[]>();
-        private Map<ParcelUuid, byte[]> mServiceData = new ArrayMap<ParcelUuid, byte[]>();
-        private boolean mIncludeTxPowerLevel;
-        private boolean mIncludeDeviceName;
-
-        /**
-         * Add a service UUID to advertise data.
-         *
-         * @param serviceUuid A service UUID to be advertised.
-         * @throws IllegalArgumentException If the {@code serviceUuid} is null.
-         */
-        public Builder addServiceUuid(ParcelUuid serviceUuid) {
-            if (serviceUuid == null) {
-                throw new IllegalArgumentException("serviceUuid is null");
-            }
-            mServiceUuids.add(serviceUuid);
-            return this;
-        }
-
-        /**
-         * Add a service solicitation UUID to advertise data.
-         *
-         * @param serviceSolicitationUuid A service solicitation UUID to be advertised.
-         * @throws IllegalArgumentException If the {@code serviceSolicitationUuid} is null.
-         */
-        @NonNull
-        public Builder addServiceSolicitationUuid(@NonNull ParcelUuid serviceSolicitationUuid) {
-            if (serviceSolicitationUuid == null) {
-                throw new IllegalArgumentException("serviceSolicitationUuid is null");
-            }
-            mServiceSolicitationUuids.add(serviceSolicitationUuid);
-            return this;
-        }
-
-        /**
-         * Add service data to advertise data.
-         *
-         * @param serviceDataUuid 16-bit UUID of the service the data is associated with
-         * @param serviceData Service data
-         * @throws IllegalArgumentException If the {@code serviceDataUuid} or {@code serviceData} is
-         * empty.
-         */
-        public Builder addServiceData(ParcelUuid serviceDataUuid, byte[] serviceData) {
-            if (serviceDataUuid == null || serviceData == null) {
-                throw new IllegalArgumentException(
-                        "serviceDataUuid or serviceDataUuid is null");
-            }
-            mServiceData.put(serviceDataUuid, serviceData);
-            return this;
-        }
-
-        /**
-         * Add Transport Discovery Data to advertise data.
-         *
-         * @param transportDiscoveryData Transport Discovery Data, consisting of one or more
-         * Transport Blocks. Transport Discovery Data AD Type Code is already included.
-         * @throws IllegalArgumentException If the {@code transportDiscoveryData} is empty
-         */
-        @NonNull
-        public Builder addTransportDiscoveryData(
-                @NonNull TransportDiscoveryData transportDiscoveryData) {
-            if (transportDiscoveryData == null) {
-                throw new IllegalArgumentException("transportDiscoveryData is null");
-            }
-            mTransportDiscoveryData.add(transportDiscoveryData);
-            return this;
-        }
-
-        /**
-         * Add manufacturer specific data.
-         * <p>
-         * Please refer to the Bluetooth Assigned Numbers document provided by the <a
-         * href="https://www.bluetooth.org">Bluetooth SIG</a> for a list of existing company
-         * identifiers.
-         *
-         * @param manufacturerId Manufacturer ID assigned by Bluetooth SIG.
-         * @param manufacturerSpecificData Manufacturer specific data
-         * @throws IllegalArgumentException If the {@code manufacturerId} is negative or {@code
-         * manufacturerSpecificData} is null.
-         */
-        public Builder addManufacturerData(int manufacturerId, byte[] manufacturerSpecificData) {
-            if (manufacturerId < 0) {
-                throw new IllegalArgumentException(
-                        "invalid manufacturerId - " + manufacturerId);
-            }
-            if (manufacturerSpecificData == null) {
-                throw new IllegalArgumentException("manufacturerSpecificData is null");
-            }
-            mManufacturerSpecificData.put(manufacturerId, manufacturerSpecificData);
-            return this;
-        }
-
-        /**
-         * Whether the transmission power level should be included in the advertise packet. Tx power
-         * level field takes 3 bytes in advertise packet.
-         */
-        public Builder setIncludeTxPowerLevel(boolean includeTxPowerLevel) {
-            mIncludeTxPowerLevel = includeTxPowerLevel;
-            return this;
-        }
-
-        /**
-         * Set whether the device name should be included in advertise packet.
-         */
-        public Builder setIncludeDeviceName(boolean includeDeviceName) {
-            mIncludeDeviceName = includeDeviceName;
-            return this;
-        }
-
-        /**
-         * Build the {@link AdvertiseData}.
-         */
-        public AdvertiseData build() {
-            return new AdvertiseData(mServiceUuids, mServiceSolicitationUuids,
-                    mTransportDiscoveryData, mManufacturerSpecificData, mServiceData,
-                    mIncludeTxPowerLevel, mIncludeDeviceName);
-        }
-    }
-}
diff --git a/core/java/android/bluetooth/le/AdvertiseSettings.java b/core/java/android/bluetooth/le/AdvertiseSettings.java
deleted file mode 100644
index c52a6ee..0000000
--- a/core/java/android/bluetooth/le/AdvertiseSettings.java
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.le;
-
-import android.annotation.NonNull;
-import android.annotation.SystemApi;
-import android.bluetooth.le.AdvertisingSetParameters.AddressTypeStatus;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * The {@link AdvertiseSettings} provide a way to adjust advertising preferences for each
- * Bluetooth LE advertisement instance. Use {@link AdvertiseSettings.Builder} to create an
- * instance of this class.
- */
-public final class AdvertiseSettings implements Parcelable {
-    /**
-     * Perform Bluetooth LE advertising in low power mode. This is the default and preferred
-     * advertising mode as it consumes the least power.
-     */
-    public static final int ADVERTISE_MODE_LOW_POWER = 0;
-
-    /**
-     * Perform Bluetooth LE advertising in balanced power mode. This is balanced between advertising
-     * frequency and power consumption.
-     */
-    public static final int ADVERTISE_MODE_BALANCED = 1;
-
-    /**
-     * Perform Bluetooth LE advertising in low latency, high power mode. This has the highest power
-     * consumption and should not be used for continuous background advertising.
-     */
-    public static final int ADVERTISE_MODE_LOW_LATENCY = 2;
-
-    /**
-     * Advertise using the lowest transmission (TX) power level. Low transmission power can be used
-     * to restrict the visibility range of advertising packets.
-     */
-    public static final int ADVERTISE_TX_POWER_ULTRA_LOW = 0;
-
-    /**
-     * Advertise using low TX power level.
-     */
-    public static final int ADVERTISE_TX_POWER_LOW = 1;
-
-    /**
-     * Advertise using medium TX power level.
-     */
-    public static final int ADVERTISE_TX_POWER_MEDIUM = 2;
-
-    /**
-     * Advertise using high TX power level. This corresponds to largest visibility range of the
-     * advertising packet.
-     */
-    public static final int ADVERTISE_TX_POWER_HIGH = 3;
-
-    /**
-     * The maximum limited advertisement duration as specified by the Bluetooth SIG
-     */
-    private static final int LIMITED_ADVERTISING_MAX_MILLIS = 180 * 1000;
-
-
-    private final int mAdvertiseMode;
-    private final int mAdvertiseTxPowerLevel;
-    private final int mAdvertiseTimeoutMillis;
-    private final boolean mAdvertiseConnectable;
-    private final int mOwnAddressType;
-
-    private AdvertiseSettings(int advertiseMode, int advertiseTxPowerLevel,
-            boolean advertiseConnectable, int advertiseTimeout,
-            @AddressTypeStatus int ownAddressType) {
-        mAdvertiseMode = advertiseMode;
-        mAdvertiseTxPowerLevel = advertiseTxPowerLevel;
-        mAdvertiseConnectable = advertiseConnectable;
-        mAdvertiseTimeoutMillis = advertiseTimeout;
-        mOwnAddressType = ownAddressType;
-    }
-
-    private AdvertiseSettings(Parcel in) {
-        mAdvertiseMode = in.readInt();
-        mAdvertiseTxPowerLevel = in.readInt();
-        mAdvertiseConnectable = in.readInt() != 0;
-        mAdvertiseTimeoutMillis = in.readInt();
-        mOwnAddressType = in.readInt();
-    }
-
-    /**
-     * Returns the advertise mode.
-     */
-    public int getMode() {
-        return mAdvertiseMode;
-    }
-
-    /**
-     * Returns the TX power level for advertising.
-     */
-    public int getTxPowerLevel() {
-        return mAdvertiseTxPowerLevel;
-    }
-
-    /**
-     * Returns whether the advertisement will indicate connectable.
-     */
-    public boolean isConnectable() {
-        return mAdvertiseConnectable;
-    }
-
-    /**
-     * Returns the advertising time limit in milliseconds.
-     */
-    public int getTimeout() {
-        return mAdvertiseTimeoutMillis;
-    }
-
-    /**
-     * @return the own address type for advertising
-     *
-     * @hide
-     */
-    @SystemApi
-    public @AddressTypeStatus int getOwnAddressType() {
-        return mOwnAddressType;
-    }
-
-    @Override
-    public String toString() {
-        return "Settings [mAdvertiseMode=" + mAdvertiseMode
-                + ", mAdvertiseTxPowerLevel=" + mAdvertiseTxPowerLevel
-                + ", mAdvertiseConnectable=" + mAdvertiseConnectable
-                + ", mAdvertiseTimeoutMillis=" + mAdvertiseTimeoutMillis
-                + ", mOwnAddressType=" + mOwnAddressType + "]";
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(mAdvertiseMode);
-        dest.writeInt(mAdvertiseTxPowerLevel);
-        dest.writeInt(mAdvertiseConnectable ? 1 : 0);
-        dest.writeInt(mAdvertiseTimeoutMillis);
-        dest.writeInt(mOwnAddressType);
-    }
-
-    public static final @android.annotation.NonNull Parcelable.Creator<AdvertiseSettings> CREATOR =
-            new Creator<AdvertiseSettings>() {
-                @Override
-                public AdvertiseSettings[] newArray(int size) {
-                    return new AdvertiseSettings[size];
-                }
-
-                @Override
-                public AdvertiseSettings createFromParcel(Parcel in) {
-                    return new AdvertiseSettings(in);
-                }
-            };
-
-    /**
-     * Builder class for {@link AdvertiseSettings}.
-     */
-    public static final class Builder {
-        private int mMode = ADVERTISE_MODE_LOW_POWER;
-        private int mTxPowerLevel = ADVERTISE_TX_POWER_MEDIUM;
-        private int mTimeoutMillis = 0;
-        private boolean mConnectable = true;
-        private int mOwnAddressType = AdvertisingSetParameters.ADDRESS_TYPE_DEFAULT;
-
-        /**
-         * Set advertise mode to control the advertising power and latency.
-         *
-         * @param advertiseMode Bluetooth LE Advertising mode, can only be one of {@link
-         * AdvertiseSettings#ADVERTISE_MODE_LOW_POWER},
-         * {@link AdvertiseSettings#ADVERTISE_MODE_BALANCED},
-         * or {@link AdvertiseSettings#ADVERTISE_MODE_LOW_LATENCY}.
-         * @throws IllegalArgumentException If the advertiseMode is invalid.
-         */
-        public Builder setAdvertiseMode(int advertiseMode) {
-            if (advertiseMode < ADVERTISE_MODE_LOW_POWER
-                    || advertiseMode > ADVERTISE_MODE_LOW_LATENCY) {
-                throw new IllegalArgumentException("unknown mode " + advertiseMode);
-            }
-            mMode = advertiseMode;
-            return this;
-        }
-
-        /**
-         * Set advertise TX power level to control the transmission power level for the advertising.
-         *
-         * @param txPowerLevel Transmission power of Bluetooth LE Advertising, can only be one of
-         * {@link AdvertiseSettings#ADVERTISE_TX_POWER_ULTRA_LOW}, {@link
-         * AdvertiseSettings#ADVERTISE_TX_POWER_LOW},
-         * {@link AdvertiseSettings#ADVERTISE_TX_POWER_MEDIUM}
-         * or {@link AdvertiseSettings#ADVERTISE_TX_POWER_HIGH}.
-         * @throws IllegalArgumentException If the {@code txPowerLevel} is invalid.
-         */
-        public Builder setTxPowerLevel(int txPowerLevel) {
-            if (txPowerLevel < ADVERTISE_TX_POWER_ULTRA_LOW
-                    || txPowerLevel > ADVERTISE_TX_POWER_HIGH) {
-                throw new IllegalArgumentException("unknown tx power level " + txPowerLevel);
-            }
-            mTxPowerLevel = txPowerLevel;
-            return this;
-        }
-
-        /**
-         * Set whether the advertisement type should be connectable or non-connectable.
-         *
-         * @param connectable Controls whether the advertisment type will be connectable (true) or
-         * non-connectable (false).
-         */
-        public Builder setConnectable(boolean connectable) {
-            mConnectable = connectable;
-            return this;
-        }
-
-        /**
-         * Limit advertising to a given amount of time.
-         *
-         * @param timeoutMillis Advertising time limit. May not exceed 180000 milliseconds. A value
-         * of 0 will disable the time limit.
-         * @throws IllegalArgumentException If the provided timeout is over 180000 ms.
-         */
-        public Builder setTimeout(int timeoutMillis) {
-            if (timeoutMillis < 0 || timeoutMillis > LIMITED_ADVERTISING_MAX_MILLIS) {
-                throw new IllegalArgumentException("timeoutMillis invalid (must be 0-"
-                        + LIMITED_ADVERTISING_MAX_MILLIS + " milliseconds)");
-            }
-            mTimeoutMillis = timeoutMillis;
-            return this;
-        }
-
-        /**
-         * Set own address type for advertising to control public or privacy mode. If used to set
-         * address type anything other than {@link AdvertisingSetParameters#ADDRESS_TYPE_DEFAULT},
-         * then it will require BLUETOOTH_PRIVILEGED permission and will be checked at the
-         * time of starting advertising.
-         *
-         * @throws IllegalArgumentException If the {@code ownAddressType} is invalid
-         *
-         * @hide
-         */
-        @SystemApi
-        public @NonNull Builder setOwnAddressType(@AddressTypeStatus int ownAddressType) {
-            if (ownAddressType < AdvertisingSetParameters.ADDRESS_TYPE_DEFAULT
-                    ||  ownAddressType > AdvertisingSetParameters.ADDRESS_TYPE_RANDOM) {
-                throw new IllegalArgumentException("unknown address type " + ownAddressType);
-            }
-            mOwnAddressType = ownAddressType;
-            return this;
-        }
-
-        /**
-         * Build the {@link AdvertiseSettings} object.
-         */
-        public AdvertiseSettings build() {
-            return new AdvertiseSettings(mMode, mTxPowerLevel, mConnectable, mTimeoutMillis,
-                mOwnAddressType);
-        }
-    }
-}
diff --git a/core/java/android/bluetooth/le/AdvertisingSet.java b/core/java/android/bluetooth/le/AdvertisingSet.java
deleted file mode 100644
index bbdb695..0000000
--- a/core/java/android/bluetooth/le/AdvertisingSet.java
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.le;
-
-import android.annotation.RequiresNoPermission;
-import android.annotation.RequiresPermission;
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.IBluetoothGatt;
-import android.bluetooth.IBluetoothManager;
-import android.bluetooth.annotations.RequiresBluetoothAdvertisePermission;
-import android.bluetooth.annotations.RequiresLegacyBluetoothAdminPermission;
-import android.content.AttributionSource;
-import android.os.RemoteException;
-import android.util.Log;
-
-/**
- * This class provides a way to control single Bluetooth LE advertising instance.
- * <p>
- * To get an instance of {@link AdvertisingSet}, call the
- * {@link BluetoothLeAdvertiser#startAdvertisingSet} method.
- *
- * @see AdvertiseData
- */
-public final class AdvertisingSet {
-    private static final String TAG = "AdvertisingSet";
-
-    private final IBluetoothGatt mGatt;
-    private int mAdvertiserId;
-    private AttributionSource mAttributionSource;
-
-    /* package */ AdvertisingSet(int advertiserId, IBluetoothManager bluetoothManager,
-            AttributionSource attributionSource) {
-        mAdvertiserId = advertiserId;
-        mAttributionSource = attributionSource;
-        try {
-            mGatt = bluetoothManager.getBluetoothGatt();
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to get Bluetooth gatt - ", e);
-            throw new IllegalStateException("Failed to get Bluetooth");
-        }
-    }
-
-    /* package */ void setAdvertiserId(int advertiserId) {
-        mAdvertiserId = advertiserId;
-    }
-
-    /**
-     * Enables Advertising. This method returns immediately, the operation status is
-     * delivered through {@code callback.onAdvertisingEnabled()}.
-     *
-     * @param enable whether the advertising should be enabled (true), or disabled (false)
-     * @param duration advertising duration, in 10ms unit. Valid range is from 1 (10ms) to 65535
-     * (655,350 ms)
-     * @param maxExtendedAdvertisingEvents maximum number of extended advertising events the
-     * controller shall attempt to send prior to terminating the extended advertising, even if the
-     * duration has not expired. Valid range is from 1 to 255.
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothAdvertisePermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)
-    public void enableAdvertising(boolean enable, int duration,
-            int maxExtendedAdvertisingEvents) {
-        try {
-            mGatt.enableAdvertisingSet(mAdvertiserId, enable, duration,
-                    maxExtendedAdvertisingEvents, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "remote exception - ", e);
-        }
-    }
-
-    /**
-     * Set/update data being Advertised. Make sure that data doesn't exceed the size limit for
-     * specified AdvertisingSetParameters. This method returns immediately, the operation status is
-     * delivered through {@code callback.onAdvertisingDataSet()}.
-     * <p>
-     * Advertising data must be empty if non-legacy scannable advertising is used.
-     *
-     * @param advertiseData Advertisement data to be broadcasted. Size must not exceed {@link
-     * BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the advertisement is connectable,
-     * three bytes will be added for flags. If the update takes place when the advertising set is
-     * enabled, the data can be maximum 251 bytes long.
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothAdvertisePermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)
-    public void setAdvertisingData(AdvertiseData advertiseData) {
-        try {
-            mGatt.setAdvertisingData(mAdvertiserId, advertiseData, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "remote exception - ", e);
-        }
-    }
-
-    /**
-     * Set/update scan response data. Make sure that data doesn't exceed the size limit for
-     * specified AdvertisingSetParameters. This method returns immediately, the operation status
-     * is delivered through {@code callback.onScanResponseDataSet()}.
-     *
-     * @param scanResponse Scan response associated with the advertisement data. Size must not
-     * exceed {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the update takes place
-     * when the advertising set is enabled, the data can be maximum 251 bytes long.
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothAdvertisePermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)
-    public void setScanResponseData(AdvertiseData scanResponse) {
-        try {
-            mGatt.setScanResponseData(mAdvertiserId, scanResponse, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "remote exception - ", e);
-        }
-    }
-
-    /**
-     * Update advertising parameters associated with this AdvertisingSet. Must be called when
-     * advertising is not active. This method returns immediately, the operation status is delivered
-     * through {@code callback.onAdvertisingParametersUpdated}.
-     *
-     * @param parameters advertising set parameters.
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothAdvertisePermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)
-    public void setAdvertisingParameters(AdvertisingSetParameters parameters) {
-        try {
-            mGatt.setAdvertisingParameters(mAdvertiserId, parameters, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "remote exception - ", e);
-        }
-    }
-
-    /**
-     * Update periodic advertising parameters associated with this set. Must be called when
-     * periodic advertising is not enabled. This method returns immediately, the operation
-     * status is delivered through {@code callback.onPeriodicAdvertisingParametersUpdated()}.
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothAdvertisePermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)
-    public void setPeriodicAdvertisingParameters(PeriodicAdvertisingParameters parameters) {
-        try {
-            mGatt.setPeriodicAdvertisingParameters(mAdvertiserId, parameters, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "remote exception - ", e);
-        }
-    }
-
-    /**
-     * Used to set periodic advertising data, must be called after setPeriodicAdvertisingParameters,
-     * or after advertising was started with periodic advertising data set. This method returns
-     * immediately, the operation status is delivered through
-     * {@code callback.onPeriodicAdvertisingDataSet()}.
-     *
-     * @param periodicData Periodic advertising data. Size must not exceed {@link
-     * BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the update takes place when the
-     * periodic advertising is enabled for this set, the data can be maximum 251 bytes long.
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothAdvertisePermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)
-    public void setPeriodicAdvertisingData(AdvertiseData periodicData) {
-        try {
-            mGatt.setPeriodicAdvertisingData(mAdvertiserId, periodicData, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "remote exception - ", e);
-        }
-    }
-
-    /**
-     * Used to enable/disable periodic advertising. This method returns immediately, the operation
-     * status is delivered through {@code callback.onPeriodicAdvertisingEnable()}.
-     *
-     * @param enable whether the periodic advertising should be enabled (true), or disabled
-     * (false).
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothAdvertisePermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)
-    public void setPeriodicAdvertisingEnabled(boolean enable) {
-        try {
-            mGatt.setPeriodicAdvertisingEnable(mAdvertiserId, enable, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "remote exception - ", e);
-        }
-    }
-
-    /**
-     * Returns address associated with this advertising set.
-     * This method is exposed only for Bluetooth PTS tests, no app or system service
-     * should ever use it.
-     *
-     * @hide
-     */
-    @RequiresBluetoothAdvertisePermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_ADVERTISE,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public void getOwnAddress() {
-        try {
-            mGatt.getOwnAddress(mAdvertiserId, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "remote exception - ", e);
-        }
-    }
-
-    /**
-     * Returns advertiserId associated with this advertising set.
-     *
-     * @hide
-     */
-    @RequiresNoPermission
-    public int getAdvertiserId() {
-        return mAdvertiserId;
-    }
-}
diff --git a/core/java/android/bluetooth/le/AdvertisingSetCallback.java b/core/java/android/bluetooth/le/AdvertisingSetCallback.java
deleted file mode 100644
index 51324fd..0000000
--- a/core/java/android/bluetooth/le/AdvertisingSetCallback.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.le;
-
-/**
- * Bluetooth LE advertising set callbacks, used to deliver advertising operation
- * status.
- */
-public abstract class AdvertisingSetCallback {
-
-    /**
-     * The requested operation was successful.
-     */
-    public static final int ADVERTISE_SUCCESS = 0;
-
-    /**
-     * Failed to start advertising as the advertise data to be broadcasted is too
-     * large.
-     */
-    public static final int ADVERTISE_FAILED_DATA_TOO_LARGE = 1;
-
-    /**
-     * Failed to start advertising because no advertising instance is available.
-     */
-    public static final int ADVERTISE_FAILED_TOO_MANY_ADVERTISERS = 2;
-
-    /**
-     * Failed to start advertising as the advertising is already started.
-     */
-    public static final int ADVERTISE_FAILED_ALREADY_STARTED = 3;
-
-    /**
-     * Operation failed due to an internal error.
-     */
-    public static final int ADVERTISE_FAILED_INTERNAL_ERROR = 4;
-
-    /**
-     * This feature is not supported on this platform.
-     */
-    public static final int ADVERTISE_FAILED_FEATURE_UNSUPPORTED = 5;
-
-    /**
-     * Callback triggered in response to {@link BluetoothLeAdvertiser#startAdvertisingSet}
-     * indicating result of the operation. If status is ADVERTISE_SUCCESS, then advertisingSet
-     * contains the started set and it is advertising. If error occurred, advertisingSet is
-     * null, and status will be set to proper error code.
-     *
-     * @param advertisingSet The advertising set that was started or null if error.
-     * @param txPower tx power that will be used for this set.
-     * @param status Status of the operation.
-     */
-    public void onAdvertisingSetStarted(AdvertisingSet advertisingSet, int txPower, int status) {
-    }
-
-    /**
-     * Callback triggered in response to {@link BluetoothLeAdvertiser#stopAdvertisingSet}
-     * indicating advertising set is stopped.
-     *
-     * @param advertisingSet The advertising set.
-     */
-    public void onAdvertisingSetStopped(AdvertisingSet advertisingSet) {
-    }
-
-    /**
-     * Callback triggered in response to {@link BluetoothLeAdvertiser#startAdvertisingSet}
-     * indicating result of the operation. If status is ADVERTISE_SUCCESS, then advertising set is
-     * advertising.
-     *
-     * @param advertisingSet The advertising set.
-     * @param status Status of the operation.
-     */
-    public void onAdvertisingEnabled(AdvertisingSet advertisingSet, boolean enable, int status) {
-    }
-
-    /**
-     * Callback triggered in response to {@link AdvertisingSet#setAdvertisingData} indicating
-     * result of the operation. If status is ADVERTISE_SUCCESS, then data was changed.
-     *
-     * @param advertisingSet The advertising set.
-     * @param status Status of the operation.
-     */
-    public void onAdvertisingDataSet(AdvertisingSet advertisingSet, int status) {
-    }
-
-    /**
-     * Callback triggered in response to {@link AdvertisingSet#setAdvertisingData} indicating
-     * result of the operation.
-     *
-     * @param advertisingSet The advertising set.
-     * @param status Status of the operation.
-     */
-    public void onScanResponseDataSet(AdvertisingSet advertisingSet, int status) {
-    }
-
-    /**
-     * Callback triggered in response to {@link AdvertisingSet#setAdvertisingParameters}
-     * indicating result of the operation.
-     *
-     * @param advertisingSet The advertising set.
-     * @param txPower tx power that will be used for this set.
-     * @param status Status of the operation.
-     */
-    public void onAdvertisingParametersUpdated(AdvertisingSet advertisingSet,
-            int txPower, int status) {
-    }
-
-    /**
-     * Callback triggered in response to {@link AdvertisingSet#setPeriodicAdvertisingParameters}
-     * indicating result of the operation.
-     *
-     * @param advertisingSet The advertising set.
-     * @param status Status of the operation.
-     */
-    public void onPeriodicAdvertisingParametersUpdated(AdvertisingSet advertisingSet, int status) {
-    }
-
-    /**
-     * Callback triggered in response to {@link AdvertisingSet#setPeriodicAdvertisingData}
-     * indicating result of the operation.
-     *
-     * @param advertisingSet The advertising set.
-     * @param status Status of the operation.
-     */
-    public void onPeriodicAdvertisingDataSet(AdvertisingSet advertisingSet,
-            int status) {
-    }
-
-    /**
-     * Callback triggered in response to {@link AdvertisingSet#setPeriodicAdvertisingEnabled}
-     * indicating result of the operation.
-     *
-     * @param advertisingSet The advertising set.
-     * @param status Status of the operation.
-     */
-    public void onPeriodicAdvertisingEnabled(AdvertisingSet advertisingSet, boolean enable,
-            int status) {
-    }
-
-    /**
-     * Callback triggered in response to {@link AdvertisingSet#getOwnAddress()}
-     * indicating result of the operation.
-     *
-     * @param advertisingSet The advertising set.
-     * @param addressType type of address.
-     * @param address advertising set bluetooth address.
-     * @hide
-     */
-    public void onOwnAddressRead(AdvertisingSet advertisingSet, int addressType, String address) {
-    }
-}
diff --git a/core/java/android/bluetooth/le/AdvertisingSetParameters.java b/core/java/android/bluetooth/le/AdvertisingSetParameters.java
deleted file mode 100644
index 5c8fae6..0000000
--- a/core/java/android/bluetooth/le/AdvertisingSetParameters.java
+++ /dev/null
@@ -1,513 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.le;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.SystemApi;
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothDevice;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * The {@link AdvertisingSetParameters} provide a way to adjust advertising
- * preferences for each
- * Bluetooth LE advertising set. Use {@link AdvertisingSetParameters.Builder} to
- * create an
- * instance of this class.
- */
-public final class AdvertisingSetParameters implements Parcelable {
-
-    /**
-     * Advertise on low frequency, around every 1000ms. This is the default and
-     * preferred advertising mode as it consumes the least power.
-     */
-    public static final int INTERVAL_HIGH = 1600;
-
-    /**
-     * Advertise on medium frequency, around every 250ms. This is balanced
-     * between advertising frequency and power consumption.
-     */
-    public static final int INTERVAL_MEDIUM = 400;
-
-    /**
-     * Perform high frequency, low latency advertising, around every 100ms. This
-     * has the highest power consumption and should not be used for continuous
-     * background advertising.
-     */
-    public static final int INTERVAL_LOW = 160;
-
-    /**
-     * Minimum value for advertising interval.
-     */
-    public static final int INTERVAL_MIN = 160;
-
-    /**
-     * Maximum value for advertising interval.
-     */
-    public static final int INTERVAL_MAX = 16777215;
-
-    /**
-     * Advertise using the lowest transmission (TX) power level. Low transmission
-     * power can be used to restrict the visibility range of advertising packets.
-     */
-    public static final int TX_POWER_ULTRA_LOW = -21;
-
-    /**
-     * Advertise using low TX power level.
-     */
-    public static final int TX_POWER_LOW = -15;
-
-    /**
-     * Advertise using medium TX power level.
-     */
-    public static final int TX_POWER_MEDIUM = -7;
-
-    /**
-     * Advertise using high TX power level. This corresponds to largest visibility
-     * range of the advertising packet.
-     */
-    public static final int TX_POWER_HIGH = 1;
-
-    /**
-     * Minimum value for TX power.
-     */
-    public static final int TX_POWER_MIN = -127;
-
-    /**
-     * Maximum value for TX power.
-     */
-    public static final int TX_POWER_MAX = 1;
-
-    /**
-     * The maximum limited advertisement duration as specified by the Bluetooth
-     * SIG
-     */
-    private static final int LIMITED_ADVERTISING_MAX_MILLIS = 180 * 1000;
-
-    /** @hide */
-    @IntDef(prefix = "ADDRESS_TYPE_", value = {
-        ADDRESS_TYPE_DEFAULT,
-        ADDRESS_TYPE_PUBLIC,
-        ADDRESS_TYPE_RANDOM
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface AddressTypeStatus {}
-
-    /**
-     * Advertise own address type that corresponds privacy settings of the device.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int ADDRESS_TYPE_DEFAULT = -1;
-
-    /**
-     * Advertise own public address type.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int ADDRESS_TYPE_PUBLIC = 0;
-
-    /**
-     * Generate and adverise own resolvable private address.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int ADDRESS_TYPE_RANDOM = 1;
-
-    private final boolean mIsLegacy;
-    private final boolean mIsAnonymous;
-    private final boolean mIncludeTxPower;
-    private final int mPrimaryPhy;
-    private final int mSecondaryPhy;
-    private final boolean mConnectable;
-    private final boolean mScannable;
-    private final int mInterval;
-    private final int mTxPowerLevel;
-    private final int mOwnAddressType;
-
-    private AdvertisingSetParameters(boolean connectable, boolean scannable, boolean isLegacy,
-            boolean isAnonymous, boolean includeTxPower,
-            int primaryPhy, int secondaryPhy,
-            int interval, int txPowerLevel, @AddressTypeStatus int ownAddressType) {
-        mConnectable = connectable;
-        mScannable = scannable;
-        mIsLegacy = isLegacy;
-        mIsAnonymous = isAnonymous;
-        mIncludeTxPower = includeTxPower;
-        mPrimaryPhy = primaryPhy;
-        mSecondaryPhy = secondaryPhy;
-        mInterval = interval;
-        mTxPowerLevel = txPowerLevel;
-        mOwnAddressType = ownAddressType;
-    }
-
-    private AdvertisingSetParameters(Parcel in) {
-        mConnectable = in.readInt() != 0;
-        mScannable = in.readInt() != 0;
-        mIsLegacy = in.readInt() != 0;
-        mIsAnonymous = in.readInt() != 0;
-        mIncludeTxPower = in.readInt() != 0;
-        mPrimaryPhy = in.readInt();
-        mSecondaryPhy = in.readInt();
-        mInterval = in.readInt();
-        mTxPowerLevel = in.readInt();
-        mOwnAddressType = in.readInt();
-    }
-
-    /**
-     * Returns whether the advertisement will be connectable.
-     */
-    public boolean isConnectable() {
-        return mConnectable;
-    }
-
-    /**
-     * Returns whether the advertisement will be scannable.
-     */
-    public boolean isScannable() {
-        return mScannable;
-    }
-
-    /**
-     * Returns whether the legacy advertisement will be used.
-     */
-    public boolean isLegacy() {
-        return mIsLegacy;
-    }
-
-    /**
-     * Returns whether the advertisement will be anonymous.
-     */
-    public boolean isAnonymous() {
-        return mIsAnonymous;
-    }
-
-    /**
-     * Returns whether the TX Power will be included.
-     */
-    public boolean includeTxPower() {
-        return mIncludeTxPower;
-    }
-
-    /**
-     * Returns the primary advertising phy.
-     */
-    public int getPrimaryPhy() {
-        return mPrimaryPhy;
-    }
-
-    /**
-     * Returns the secondary advertising phy.
-     */
-    public int getSecondaryPhy() {
-        return mSecondaryPhy;
-    }
-
-    /**
-     * Returns the advertising interval.
-     */
-    public int getInterval() {
-        return mInterval;
-    }
-
-    /**
-     * Returns the TX power level for advertising.
-     */
-    public int getTxPowerLevel() {
-        return mTxPowerLevel;
-    }
-
-    /**
-     * @return the own address type for advertising
-     *
-     * @hide
-     */
-    @SystemApi
-    public @AddressTypeStatus int getOwnAddressType() {
-        return mOwnAddressType;
-    }
-
-    @Override
-    public String toString() {
-        return "AdvertisingSetParameters [connectable=" + mConnectable
-                + ", isLegacy=" + mIsLegacy
-                + ", isAnonymous=" + mIsAnonymous
-                + ", includeTxPower=" + mIncludeTxPower
-                + ", primaryPhy=" + mPrimaryPhy
-                + ", secondaryPhy=" + mSecondaryPhy
-                + ", interval=" + mInterval
-                + ", txPowerLevel=" + mTxPowerLevel
-                + ", ownAddressType=" + mOwnAddressType + "]";
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(mConnectable ? 1 : 0);
-        dest.writeInt(mScannable ? 1 : 0);
-        dest.writeInt(mIsLegacy ? 1 : 0);
-        dest.writeInt(mIsAnonymous ? 1 : 0);
-        dest.writeInt(mIncludeTxPower ? 1 : 0);
-        dest.writeInt(mPrimaryPhy);
-        dest.writeInt(mSecondaryPhy);
-        dest.writeInt(mInterval);
-        dest.writeInt(mTxPowerLevel);
-        dest.writeInt(mOwnAddressType);
-    }
-
-    public static final @android.annotation.NonNull Parcelable.Creator<AdvertisingSetParameters> CREATOR =
-            new Creator<AdvertisingSetParameters>() {
-                @Override
-                public AdvertisingSetParameters[] newArray(int size) {
-                    return new AdvertisingSetParameters[size];
-                }
-
-                @Override
-                public AdvertisingSetParameters createFromParcel(Parcel in) {
-                    return new AdvertisingSetParameters(in);
-                }
-            };
-
-    /**
-     * Builder class for {@link AdvertisingSetParameters}.
-     */
-    public static final class Builder {
-        private boolean mConnectable = false;
-        private boolean mScannable = false;
-        private boolean mIsLegacy = false;
-        private boolean mIsAnonymous = false;
-        private boolean mIncludeTxPower = false;
-        private int mPrimaryPhy = BluetoothDevice.PHY_LE_1M;
-        private int mSecondaryPhy = BluetoothDevice.PHY_LE_1M;
-        private int mInterval = INTERVAL_LOW;
-        private int mTxPowerLevel = TX_POWER_MEDIUM;
-        private int mOwnAddressType = ADDRESS_TYPE_DEFAULT;
-
-        /**
-         * Set whether the advertisement type should be connectable or
-         * non-connectable.
-         * Legacy advertisements can be both connectable and scannable. Non-legacy
-         * advertisements can be only scannable or only connectable.
-         *
-         * @param connectable Controls whether the advertisement type will be connectable (true) or
-         * non-connectable (false).
-         */
-        public Builder setConnectable(boolean connectable) {
-            mConnectable = connectable;
-            return this;
-        }
-
-        /**
-         * Set whether the advertisement type should be scannable.
-         * Legacy advertisements can be both connectable and scannable. Non-legacy
-         * advertisements can be only scannable or only connectable.
-         *
-         * @param scannable Controls whether the advertisement type will be scannable (true) or
-         * non-scannable (false).
-         */
-        public Builder setScannable(boolean scannable) {
-            mScannable = scannable;
-            return this;
-        }
-
-        /**
-         * When set to true, advertising set will advertise 4.x Spec compliant
-         * advertisements.
-         *
-         * @param isLegacy whether legacy advertising mode should be used.
-         */
-        public Builder setLegacyMode(boolean isLegacy) {
-            mIsLegacy = isLegacy;
-            return this;
-        }
-
-        /**
-         * Set whether advertiser address should be ommited from all packets. If this
-         * mode is used, periodic advertising can't be enabled for this set.
-         *
-         * This is used only if legacy mode is not used.
-         *
-         * @param isAnonymous whether anonymous advertising should be used.
-         */
-        public Builder setAnonymous(boolean isAnonymous) {
-            mIsAnonymous = isAnonymous;
-            return this;
-        }
-
-        /**
-         * Set whether TX power should be included in the extended header.
-         *
-         * This is used only if legacy mode is not used.
-         *
-         * @param includeTxPower whether TX power should be included in extended header
-         */
-        public Builder setIncludeTxPower(boolean includeTxPower) {
-            mIncludeTxPower = includeTxPower;
-            return this;
-        }
-
-        /**
-         * Set the primary physical channel used for this advertising set.
-         *
-         * This is used only if legacy mode is not used.
-         *
-         * Use {@link BluetoothAdapter#isLeCodedPhySupported} to determine if LE Coded PHY is
-         * supported on this device.
-         *
-         * @param primaryPhy Primary advertising physical channel, can only be {@link
-         * BluetoothDevice#PHY_LE_1M} or {@link BluetoothDevice#PHY_LE_CODED}.
-         * @throws IllegalArgumentException If the primaryPhy is invalid.
-         */
-        public Builder setPrimaryPhy(int primaryPhy) {
-            if (primaryPhy != BluetoothDevice.PHY_LE_1M
-                    && primaryPhy != BluetoothDevice.PHY_LE_CODED) {
-                throw new IllegalArgumentException("bad primaryPhy " + primaryPhy);
-            }
-            mPrimaryPhy = primaryPhy;
-            return this;
-        }
-
-        /**
-         * Set the secondary physical channel used for this advertising set.
-         *
-         * This is used only if legacy mode is not used.
-         *
-         * Use {@link BluetoothAdapter#isLeCodedPhySupported} and
-         * {@link BluetoothAdapter#isLe2MPhySupported} to determine if LE Coded PHY or 2M PHY is
-         * supported on this device.
-         *
-         * @param secondaryPhy Secondary advertising physical channel, can only be one of {@link
-         * BluetoothDevice#PHY_LE_1M}, {@link BluetoothDevice#PHY_LE_2M} or {@link
-         * BluetoothDevice#PHY_LE_CODED}.
-         * @throws IllegalArgumentException If the secondaryPhy is invalid.
-         */
-        public Builder setSecondaryPhy(int secondaryPhy) {
-            if (secondaryPhy != BluetoothDevice.PHY_LE_1M
-                    && secondaryPhy != BluetoothDevice.PHY_LE_2M
-                    && secondaryPhy != BluetoothDevice.PHY_LE_CODED) {
-                throw new IllegalArgumentException("bad secondaryPhy " + secondaryPhy);
-            }
-            mSecondaryPhy = secondaryPhy;
-            return this;
-        }
-
-        /**
-         * Set advertising interval.
-         *
-         * @param interval Bluetooth LE Advertising interval, in 0.625ms unit. Valid range is from
-         * 160 (100ms) to 16777215 (10,485.759375 s). Recommended values are: {@link
-         * AdvertisingSetParameters#INTERVAL_LOW}, {@link AdvertisingSetParameters#INTERVAL_MEDIUM},
-         * or {@link AdvertisingSetParameters#INTERVAL_HIGH}.
-         * @throws IllegalArgumentException If the interval is invalid.
-         */
-        public Builder setInterval(int interval) {
-            if (interval < INTERVAL_MIN || interval > INTERVAL_MAX) {
-                throw new IllegalArgumentException("unknown interval " + interval);
-            }
-            mInterval = interval;
-            return this;
-        }
-
-        /**
-         * Set the transmission power level for the advertising.
-         *
-         * @param txPowerLevel Transmission power of Bluetooth LE Advertising, in dBm. The valid
-         * range is [-127, 1] Recommended values are:
-         * {@link AdvertisingSetParameters#TX_POWER_ULTRA_LOW},
-         * {@link AdvertisingSetParameters#TX_POWER_LOW},
-         * {@link AdvertisingSetParameters#TX_POWER_MEDIUM},
-         * or {@link AdvertisingSetParameters#TX_POWER_HIGH}.
-         * @throws IllegalArgumentException If the {@code txPowerLevel} is invalid.
-         */
-        public Builder setTxPowerLevel(int txPowerLevel) {
-            if (txPowerLevel < TX_POWER_MIN || txPowerLevel > TX_POWER_MAX) {
-                throw new IllegalArgumentException("unknown txPowerLevel " + txPowerLevel);
-            }
-            mTxPowerLevel = txPowerLevel;
-            return this;
-        }
-
-        /**
-         * Set own address type for advertising to control public or privacy mode. If used to set
-         * address type anything other than {@link AdvertisingSetParameters#ADDRESS_TYPE_DEFAULT},
-         * then it will require BLUETOOTH_PRIVILEGED permission and will be checked at the
-         * time of starting advertising.
-         *
-         * @throws IllegalArgumentException If the {@code ownAddressType} is invalid
-         *
-         * @hide
-         */
-        @SystemApi
-        public @NonNull Builder setOwnAddressType(@AddressTypeStatus int ownAddressType) {
-            if (ownAddressType < AdvertisingSetParameters.ADDRESS_TYPE_DEFAULT
-                    ||  ownAddressType > AdvertisingSetParameters.ADDRESS_TYPE_RANDOM) {
-                throw new IllegalArgumentException("unknown address type " + ownAddressType);
-            }
-            mOwnAddressType = ownAddressType;
-            return this;
-        }
-
-        /**
-         * Build the {@link AdvertisingSetParameters} object.
-         *
-         * @throws IllegalStateException if invalid combination of parameters is used.
-         */
-        public AdvertisingSetParameters build() {
-            if (mIsLegacy) {
-                if (mIsAnonymous) {
-                    throw new IllegalArgumentException("Legacy advertising can't be anonymous");
-                }
-
-                if (mConnectable && !mScannable) {
-                    throw new IllegalStateException(
-                            "Legacy advertisement can't be connectable and non-scannable");
-                }
-
-                if (mIncludeTxPower) {
-                    throw new IllegalStateException(
-                            "Legacy advertising can't include TX power level in header");
-                }
-            } else {
-                if (mConnectable && mScannable) {
-                    throw new IllegalStateException(
-                            "Advertising can't be both connectable and scannable");
-                }
-
-                if (mIsAnonymous && mConnectable) {
-                    throw new IllegalStateException(
-                            "Advertising can't be both connectable and anonymous");
-                }
-            }
-
-            return new AdvertisingSetParameters(mConnectable, mScannable, mIsLegacy, mIsAnonymous,
-                    mIncludeTxPower, mPrimaryPhy, mSecondaryPhy, mInterval, mTxPowerLevel,
-                    mOwnAddressType);
-        }
-    }
-}
diff --git a/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java b/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java
deleted file mode 100644
index 879dcee..0000000
--- a/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java
+++ /dev/null
@@ -1,756 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.le;
-
-import android.annotation.RequiresNoPermission;
-import android.annotation.RequiresPermission;
-import android.annotation.SuppressLint;
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothUuid;
-import android.bluetooth.IBluetoothGatt;
-import android.bluetooth.IBluetoothManager;
-import android.bluetooth.annotations.RequiresBluetoothAdvertisePermission;
-import android.bluetooth.annotations.RequiresLegacyBluetoothAdminPermission;
-import android.content.AttributionSource;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.ParcelUuid;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Objects;
-
-/**
- * This class provides a way to perform Bluetooth LE advertise operations, such as starting and
- * stopping advertising. An advertiser can broadcast up to 31 bytes of advertisement data
- * represented by {@link AdvertiseData}.
- * <p>
- * To get an instance of {@link BluetoothLeAdvertiser}, call the
- * {@link BluetoothAdapter#getBluetoothLeAdvertiser()} method.
- *
- * @see AdvertiseData
- */
-public final class BluetoothLeAdvertiser {
-
-    private static final String TAG = "BluetoothLeAdvertiser";
-
-    private static final int MAX_ADVERTISING_DATA_BYTES = 1650;
-    private static final int MAX_LEGACY_ADVERTISING_DATA_BYTES = 31;
-    // Each fields need one byte for field length and another byte for field type.
-    private static final int OVERHEAD_BYTES_PER_FIELD = 2;
-    // Flags field will be set by system.
-    private static final int FLAGS_FIELD_BYTES = 3;
-    private static final int MANUFACTURER_SPECIFIC_DATA_LENGTH = 2;
-
-    private final BluetoothAdapter mBluetoothAdapter;
-    private final IBluetoothManager mBluetoothManager;
-    private final AttributionSource mAttributionSource;
-
-    private final Handler mHandler;
-    private final Map<AdvertiseCallback, AdvertisingSetCallback>
-            mLegacyAdvertisers = new HashMap<>();
-    private final Map<AdvertisingSetCallback, IAdvertisingSetCallback>
-            mCallbackWrappers = Collections.synchronizedMap(new HashMap<>());
-    private final Map<Integer, AdvertisingSet>
-            mAdvertisingSets = Collections.synchronizedMap(new HashMap<>());
-
-    /**
-     * Use BluetoothAdapter.getLeAdvertiser() instead.
-     *
-     * @param bluetoothManager BluetoothManager that conducts overall Bluetooth Management
-     * @hide
-     */
-    public BluetoothLeAdvertiser(BluetoothAdapter bluetoothAdapter) {
-        mBluetoothAdapter = Objects.requireNonNull(bluetoothAdapter);
-        mBluetoothManager = mBluetoothAdapter.getBluetoothManager();
-        mAttributionSource = mBluetoothAdapter.getAttributionSource();
-        mHandler = new Handler(Looper.getMainLooper());
-    }
-
-    /**
-     * Start Bluetooth LE Advertising. On success, the {@code advertiseData} will be broadcasted.
-     * Returns immediately, the operation status is delivered through {@code callback}.
-     *
-     * @param settings Settings for Bluetooth LE advertising.
-     * @param advertiseData Advertisement data to be broadcasted.
-     * @param callback Callback for advertising status.
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothAdvertisePermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)
-    public void startAdvertising(AdvertiseSettings settings,
-            AdvertiseData advertiseData, final AdvertiseCallback callback) {
-        startAdvertising(settings, advertiseData, null, callback);
-    }
-
-    /**
-     * Start Bluetooth LE Advertising. The {@code advertiseData} will be broadcasted if the
-     * operation succeeds. The {@code scanResponse} is returned when a scanning device sends an
-     * active scan request. This method returns immediately, the operation status is delivered
-     * through {@code callback}.
-     *
-     * @param settings Settings for Bluetooth LE advertising.
-     * @param advertiseData Advertisement data to be advertised in advertisement packet.
-     * @param scanResponse Scan response associated with the advertisement data.
-     * @param callback Callback for advertising status.
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothAdvertisePermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)
-    public void startAdvertising(AdvertiseSettings settings,
-            AdvertiseData advertiseData, AdvertiseData scanResponse,
-            final AdvertiseCallback callback) {
-        synchronized (mLegacyAdvertisers) {
-            BluetoothLeUtils.checkAdapterStateOn(mBluetoothAdapter);
-            if (callback == null) {
-                throw new IllegalArgumentException("callback cannot be null");
-            }
-            boolean isConnectable = settings.isConnectable();
-            if (totalBytes(advertiseData, isConnectable) > MAX_LEGACY_ADVERTISING_DATA_BYTES
-                    || totalBytes(scanResponse, false) > MAX_LEGACY_ADVERTISING_DATA_BYTES) {
-                postStartFailure(callback, AdvertiseCallback.ADVERTISE_FAILED_DATA_TOO_LARGE);
-                return;
-            }
-            if (mLegacyAdvertisers.containsKey(callback)) {
-                postStartFailure(callback, AdvertiseCallback.ADVERTISE_FAILED_ALREADY_STARTED);
-                return;
-            }
-
-            AdvertisingSetParameters.Builder parameters = new AdvertisingSetParameters.Builder();
-            parameters.setLegacyMode(true);
-            parameters.setConnectable(isConnectable);
-            parameters.setScannable(true); // legacy advertisements we support are always scannable
-            parameters.setOwnAddressType(settings.getOwnAddressType());
-            if (settings.getMode() == AdvertiseSettings.ADVERTISE_MODE_LOW_POWER) {
-                parameters.setInterval(1600); // 1s
-            } else if (settings.getMode() == AdvertiseSettings.ADVERTISE_MODE_BALANCED) {
-                parameters.setInterval(400); // 250ms
-            } else if (settings.getMode() == AdvertiseSettings.ADVERTISE_MODE_LOW_LATENCY) {
-                parameters.setInterval(160); // 100ms
-            }
-
-            if (settings.getTxPowerLevel() == AdvertiseSettings.ADVERTISE_TX_POWER_ULTRA_LOW) {
-                parameters.setTxPowerLevel(-21);
-            } else if (settings.getTxPowerLevel() == AdvertiseSettings.ADVERTISE_TX_POWER_LOW) {
-                parameters.setTxPowerLevel(-15);
-            } else if (settings.getTxPowerLevel() == AdvertiseSettings.ADVERTISE_TX_POWER_MEDIUM) {
-                parameters.setTxPowerLevel(-7);
-            } else if (settings.getTxPowerLevel() == AdvertiseSettings.ADVERTISE_TX_POWER_HIGH) {
-                parameters.setTxPowerLevel(1);
-            }
-
-            int duration = 0;
-            int timeoutMillis = settings.getTimeout();
-            if (timeoutMillis > 0) {
-                duration = (timeoutMillis < 10) ? 1 : timeoutMillis / 10;
-            }
-
-            AdvertisingSetCallback wrapped = wrapOldCallback(callback, settings);
-            mLegacyAdvertisers.put(callback, wrapped);
-            startAdvertisingSet(parameters.build(), advertiseData, scanResponse, null, null,
-                    duration, 0, wrapped);
-        }
-    }
-
-    @SuppressLint({
-            "AndroidFrameworkBluetoothPermission",
-            "AndroidFrameworkRequiresPermission",
-    })
-    AdvertisingSetCallback wrapOldCallback(AdvertiseCallback callback, AdvertiseSettings settings) {
-        return new AdvertisingSetCallback() {
-            @Override
-            public void onAdvertisingSetStarted(AdvertisingSet advertisingSet, int txPower,
-                    int status) {
-                if (status != AdvertisingSetCallback.ADVERTISE_SUCCESS) {
-                    postStartFailure(callback, status);
-                    return;
-                }
-
-                postStartSuccess(callback, settings);
-            }
-
-            /* Legacy advertiser is disabled on timeout */
-            @Override
-            public void onAdvertisingEnabled(AdvertisingSet advertisingSet, boolean enabled,
-                    int status) {
-                if (enabled) {
-                    Log.e(TAG, "Legacy advertiser should be only disabled on timeout,"
-                            + " but was enabled!");
-                    return;
-                }
-
-                stopAdvertising(callback);
-            }
-
-        };
-    }
-
-    /**
-     * Stop Bluetooth LE advertising. The {@code callback} must be the same one use in
-     * {@link BluetoothLeAdvertiser#startAdvertising}.
-     *
-     * @param callback {@link AdvertiseCallback} identifies the advertising instance to stop.
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothAdvertisePermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)
-    public void stopAdvertising(final AdvertiseCallback callback) {
-        synchronized (mLegacyAdvertisers) {
-            if (callback == null) {
-                throw new IllegalArgumentException("callback cannot be null");
-            }
-            AdvertisingSetCallback wrapper = mLegacyAdvertisers.get(callback);
-            if (wrapper == null) return;
-
-            stopAdvertisingSet(wrapper);
-
-            mLegacyAdvertisers.remove(callback);
-        }
-    }
-
-    /**
-     * Creates a new advertising set. If operation succeed, device will start advertising. This
-     * method returns immediately, the operation status is delivered through
-     * {@code callback.onAdvertisingSetStarted()}.
-     * <p>
-     *
-     * @param parameters advertising set parameters.
-     * @param advertiseData Advertisement data to be broadcasted. Size must not exceed {@link
-     * BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the advertisement is connectable,
-     * three bytes will be added for flags.
-     * @param scanResponse Scan response associated with the advertisement data. Size must not
-     * exceed {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}.
-     * @param periodicParameters periodic advertisng parameters. If null, periodic advertising will
-     * not be started.
-     * @param periodicData Periodic advertising data. Size must not exceed {@link
-     * BluetoothAdapter#getLeMaximumAdvertisingDataLength}.
-     * @param callback Callback for advertising set.
-     * @throws IllegalArgumentException when any of the data parameter exceed the maximum allowable
-     * size, or unsupported advertising PHY is selected, or when attempt to use Periodic Advertising
-     * feature is made when it's not supported by the controller.
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothAdvertisePermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)
-    public void startAdvertisingSet(AdvertisingSetParameters parameters,
-            AdvertiseData advertiseData, AdvertiseData scanResponse,
-            PeriodicAdvertisingParameters periodicParameters,
-            AdvertiseData periodicData, AdvertisingSetCallback callback) {
-        startAdvertisingSet(parameters, advertiseData, scanResponse, periodicParameters,
-                periodicData, 0, 0, callback, new Handler(Looper.getMainLooper()));
-    }
-
-    /**
-     * Creates a new advertising set. If operation succeed, device will start advertising. This
-     * method returns immediately, the operation status is delivered through
-     * {@code callback.onAdvertisingSetStarted()}.
-     * <p>
-     *
-     * @param parameters advertising set parameters.
-     * @param advertiseData Advertisement data to be broadcasted. Size must not exceed {@link
-     * BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the advertisement is connectable,
-     * three bytes will be added for flags.
-     * @param scanResponse Scan response associated with the advertisement data. Size must not
-     * exceed {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}.
-     * @param periodicParameters periodic advertisng parameters. If null, periodic advertising will
-     * not be started.
-     * @param periodicData Periodic advertising data. Size must not exceed {@link
-     * BluetoothAdapter#getLeMaximumAdvertisingDataLength}.
-     * @param callback Callback for advertising set.
-     * @param handler thread upon which the callbacks will be invoked.
-     * @throws IllegalArgumentException when any of the data parameter exceed the maximum allowable
-     * size, or unsupported advertising PHY is selected, or when attempt to use Periodic Advertising
-     * feature is made when it's not supported by the controller.
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothAdvertisePermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)
-    public void startAdvertisingSet(AdvertisingSetParameters parameters,
-            AdvertiseData advertiseData, AdvertiseData scanResponse,
-            PeriodicAdvertisingParameters periodicParameters,
-            AdvertiseData periodicData, AdvertisingSetCallback callback,
-            Handler handler) {
-        startAdvertisingSet(parameters, advertiseData, scanResponse, periodicParameters,
-                periodicData, 0, 0, callback, handler);
-    }
-
-    /**
-     * Creates a new advertising set. If operation succeed, device will start advertising. This
-     * method returns immediately, the operation status is delivered through
-     * {@code callback.onAdvertisingSetStarted()}.
-     * <p>
-     *
-     * @param parameters advertising set parameters.
-     * @param advertiseData Advertisement data to be broadcasted. Size must not exceed {@link
-     * BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the advertisement is connectable,
-     * three bytes will be added for flags.
-     * @param scanResponse Scan response associated with the advertisement data. Size must not
-     * exceed {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}.
-     * @param periodicParameters periodic advertisng parameters. If null, periodic advertising will
-     * not be started.
-     * @param periodicData Periodic advertising data. Size must not exceed {@link
-     * BluetoothAdapter#getLeMaximumAdvertisingDataLength}.
-     * @param duration advertising duration, in 10ms unit. Valid range is from 1 (10ms) to 65535
-     * (655,350 ms). 0 means advertising should continue until stopped.
-     * @param maxExtendedAdvertisingEvents maximum number of extended advertising events the
-     * controller shall attempt to send prior to terminating the extended advertising, even if the
-     * duration has not expired. Valid range is from 1 to 255. 0 means no maximum.
-     * @param callback Callback for advertising set.
-     * @throws IllegalArgumentException when any of the data parameter exceed the maximum allowable
-     * size, or unsupported advertising PHY is selected, or when attempt to use Periodic Advertising
-     * feature is made when it's not supported by the controller.
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothAdvertisePermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)
-    public void startAdvertisingSet(AdvertisingSetParameters parameters,
-            AdvertiseData advertiseData, AdvertiseData scanResponse,
-            PeriodicAdvertisingParameters periodicParameters,
-            AdvertiseData periodicData, int duration,
-            int maxExtendedAdvertisingEvents,
-            AdvertisingSetCallback callback) {
-        startAdvertisingSet(parameters, advertiseData, scanResponse, periodicParameters,
-                periodicData, duration, maxExtendedAdvertisingEvents, callback,
-                new Handler(Looper.getMainLooper()));
-    }
-
-    /**
-     * Creates a new advertising set. If operation succeed, device will start advertising. This
-     * method returns immediately, the operation status is delivered through
-     * {@code callback.onAdvertisingSetStarted()}.
-     * <p>
-     *
-     * @param parameters Advertising set parameters.
-     * @param advertiseData Advertisement data to be broadcasted. Size must not exceed {@link
-     * BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the advertisement is connectable,
-     * three bytes will be added for flags.
-     * @param scanResponse Scan response associated with the advertisement data. Size must not
-     * exceed {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}
-     * @param periodicParameters Periodic advertisng parameters. If null, periodic advertising will
-     * not be started.
-     * @param periodicData Periodic advertising data. Size must not exceed {@link
-     * BluetoothAdapter#getLeMaximumAdvertisingDataLength}
-     * @param duration advertising duration, in 10ms unit. Valid range is from 1 (10ms) to 65535
-     * (655,350 ms). 0 means advertising should continue until stopped.
-     * @param maxExtendedAdvertisingEvents maximum number of extended advertising events the
-     * controller shall attempt to send prior to terminating the extended advertising, even if the
-     * duration has not expired. Valid range is from 1 to 255. 0 means no maximum.
-     * @param callback Callback for advertising set.
-     * @param handler Thread upon which the callbacks will be invoked.
-     * @throws IllegalArgumentException When any of the data parameter exceed the maximum allowable
-     * size, or unsupported advertising PHY is selected, or when attempt to use Periodic Advertising
-     * feature is made when it's not supported by the controller, or when
-     * maxExtendedAdvertisingEvents is used on a controller that doesn't support the LE Extended
-     * Advertising
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothAdvertisePermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)
-    public void startAdvertisingSet(AdvertisingSetParameters parameters,
-            AdvertiseData advertiseData, AdvertiseData scanResponse,
-            PeriodicAdvertisingParameters periodicParameters,
-            AdvertiseData periodicData, int duration,
-            int maxExtendedAdvertisingEvents, AdvertisingSetCallback callback,
-            Handler handler) {
-        BluetoothLeUtils.checkAdapterStateOn(mBluetoothAdapter);
-        if (callback == null) {
-            throw new IllegalArgumentException("callback cannot be null");
-        }
-
-        boolean isConnectable = parameters.isConnectable();
-        if (parameters.isLegacy()) {
-            if (totalBytes(advertiseData, isConnectable) > MAX_LEGACY_ADVERTISING_DATA_BYTES) {
-                throw new IllegalArgumentException("Legacy advertising data too big");
-            }
-
-            if (totalBytes(scanResponse, false) > MAX_LEGACY_ADVERTISING_DATA_BYTES) {
-                throw new IllegalArgumentException("Legacy scan response data too big");
-            }
-        } else {
-            boolean supportCodedPhy = mBluetoothAdapter.isLeCodedPhySupported();
-            boolean support2MPhy = mBluetoothAdapter.isLe2MPhySupported();
-            int pphy = parameters.getPrimaryPhy();
-            int sphy = parameters.getSecondaryPhy();
-            if (pphy == BluetoothDevice.PHY_LE_CODED && !supportCodedPhy) {
-                throw new IllegalArgumentException("Unsupported primary PHY selected");
-            }
-
-            if ((sphy == BluetoothDevice.PHY_LE_CODED && !supportCodedPhy)
-                    || (sphy == BluetoothDevice.PHY_LE_2M && !support2MPhy)) {
-                throw new IllegalArgumentException("Unsupported secondary PHY selected");
-            }
-
-            int maxData = mBluetoothAdapter.getLeMaximumAdvertisingDataLength();
-            if (totalBytes(advertiseData, isConnectable) > maxData) {
-                throw new IllegalArgumentException("Advertising data too big");
-            }
-
-            if (totalBytes(scanResponse, false) > maxData) {
-                throw new IllegalArgumentException("Scan response data too big");
-            }
-
-            if (totalBytes(periodicData, false) > maxData) {
-                throw new IllegalArgumentException("Periodic advertising data too big");
-            }
-
-            boolean supportPeriodic = mBluetoothAdapter.isLePeriodicAdvertisingSupported();
-            if (periodicParameters != null && !supportPeriodic) {
-                throw new IllegalArgumentException(
-                        "Controller does not support LE Periodic Advertising");
-            }
-        }
-
-        if (maxExtendedAdvertisingEvents < 0 || maxExtendedAdvertisingEvents > 255) {
-            throw new IllegalArgumentException(
-                    "maxExtendedAdvertisingEvents out of range: " + maxExtendedAdvertisingEvents);
-        }
-
-        if (maxExtendedAdvertisingEvents != 0
-                && !mBluetoothAdapter.isLePeriodicAdvertisingSupported()) {
-            throw new IllegalArgumentException(
-                    "Can't use maxExtendedAdvertisingEvents with controller that don't support "
-                            + "LE Extended Advertising");
-        }
-
-        if (duration < 0 || duration > 65535) {
-            throw new IllegalArgumentException("duration out of range: " + duration);
-        }
-
-        IBluetoothGatt gatt;
-        try {
-            gatt = mBluetoothManager.getBluetoothGatt();
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to get Bluetooth GATT - ", e);
-            postStartSetFailure(handler, callback,
-                    AdvertiseCallback.ADVERTISE_FAILED_INTERNAL_ERROR);
-            return;
-        }
-
-        if (gatt == null) {
-            Log.e(TAG, "Bluetooth GATT is null");
-            postStartSetFailure(handler, callback,
-                    AdvertiseCallback.ADVERTISE_FAILED_INTERNAL_ERROR);
-            return;
-        }
-
-        IAdvertisingSetCallback wrapped = wrap(callback, handler);
-        if (mCallbackWrappers.putIfAbsent(callback, wrapped) != null) {
-            throw new IllegalArgumentException(
-                    "callback instance already associated with advertising");
-        }
-
-        try {
-            gatt.startAdvertisingSet(parameters, advertiseData, scanResponse, periodicParameters,
-                    periodicData, duration, maxExtendedAdvertisingEvents, wrapped,
-                    mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to start advertising set - ", e);
-            postStartSetFailure(handler, callback,
-                    AdvertiseCallback.ADVERTISE_FAILED_INTERNAL_ERROR);
-            return;
-        }
-    }
-
-    /**
-     * Used to dispose of a {@link AdvertisingSet} object, obtained with {@link
-     * BluetoothLeAdvertiser#startAdvertisingSet}.
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothAdvertisePermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)
-    public void stopAdvertisingSet(AdvertisingSetCallback callback) {
-        if (callback == null) {
-            throw new IllegalArgumentException("callback cannot be null");
-        }
-
-        IAdvertisingSetCallback wrapped = mCallbackWrappers.remove(callback);
-        if (wrapped == null) {
-            return;
-        }
-
-        IBluetoothGatt gatt;
-        try {
-            gatt = mBluetoothManager.getBluetoothGatt();
-            gatt.stopAdvertisingSet(wrapped, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to stop advertising - ", e);
-        }
-    }
-
-    /**
-     * Cleans up advertisers. Should be called when bluetooth is down.
-     *
-     * @hide
-     */
-    @RequiresNoPermission
-    public void cleanup() {
-        mLegacyAdvertisers.clear();
-        mCallbackWrappers.clear();
-        mAdvertisingSets.clear();
-    }
-
-    // Compute the size of advertisement data or scan resp
-    @RequiresBluetoothAdvertisePermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)
-    private int totalBytes(AdvertiseData data, boolean isFlagsIncluded) {
-        if (data == null) return 0;
-        // Flags field is omitted if the advertising is not connectable.
-        int size = (isFlagsIncluded) ? FLAGS_FIELD_BYTES : 0;
-        if (data.getServiceUuids() != null) {
-            int num16BitUuids = 0;
-            int num32BitUuids = 0;
-            int num128BitUuids = 0;
-            for (ParcelUuid uuid : data.getServiceUuids()) {
-                if (BluetoothUuid.is16BitUuid(uuid)) {
-                    ++num16BitUuids;
-                } else if (BluetoothUuid.is32BitUuid(uuid)) {
-                    ++num32BitUuids;
-                } else {
-                    ++num128BitUuids;
-                }
-            }
-            // 16 bit service uuids are grouped into one field when doing advertising.
-            if (num16BitUuids != 0) {
-                size += OVERHEAD_BYTES_PER_FIELD + num16BitUuids * BluetoothUuid.UUID_BYTES_16_BIT;
-            }
-            // 32 bit service uuids are grouped into one field when doing advertising.
-            if (num32BitUuids != 0) {
-                size += OVERHEAD_BYTES_PER_FIELD + num32BitUuids * BluetoothUuid.UUID_BYTES_32_BIT;
-            }
-            // 128 bit service uuids are grouped into one field when doing advertising.
-            if (num128BitUuids != 0) {
-                size += OVERHEAD_BYTES_PER_FIELD
-                        + num128BitUuids * BluetoothUuid.UUID_BYTES_128_BIT;
-            }
-        }
-        if (data.getServiceSolicitationUuids() != null) {
-            int num16BitUuids = 0;
-            int num32BitUuids = 0;
-            int num128BitUuids = 0;
-            for (ParcelUuid uuid : data.getServiceSolicitationUuids()) {
-                if (BluetoothUuid.is16BitUuid(uuid)) {
-                    ++num16BitUuids;
-                } else if (BluetoothUuid.is32BitUuid(uuid)) {
-                    ++num32BitUuids;
-                } else {
-                    ++num128BitUuids;
-                }
-            }
-            // 16 bit service uuids are grouped into one field when doing advertising.
-            if (num16BitUuids != 0) {
-                size += OVERHEAD_BYTES_PER_FIELD + num16BitUuids * BluetoothUuid.UUID_BYTES_16_BIT;
-            }
-            // 32 bit service uuids are grouped into one field when doing advertising.
-            if (num32BitUuids != 0) {
-                size += OVERHEAD_BYTES_PER_FIELD + num32BitUuids * BluetoothUuid.UUID_BYTES_32_BIT;
-            }
-            // 128 bit service uuids are grouped into one field when doing advertising.
-            if (num128BitUuids != 0) {
-                size += OVERHEAD_BYTES_PER_FIELD
-                        + num128BitUuids * BluetoothUuid.UUID_BYTES_128_BIT;
-            }
-        }
-        for (TransportDiscoveryData transportDiscoveryData : data.getTransportDiscoveryData()) {
-            size += OVERHEAD_BYTES_PER_FIELD + transportDiscoveryData.totalBytes();
-        }
-        for (ParcelUuid uuid : data.getServiceData().keySet()) {
-            int uuidLen = BluetoothUuid.uuidToBytes(uuid).length;
-            size += OVERHEAD_BYTES_PER_FIELD + uuidLen
-                    + byteLength(data.getServiceData().get(uuid));
-        }
-        for (int i = 0; i < data.getManufacturerSpecificData().size(); ++i) {
-            size += OVERHEAD_BYTES_PER_FIELD + MANUFACTURER_SPECIFIC_DATA_LENGTH
-                    + byteLength(data.getManufacturerSpecificData().valueAt(i));
-        }
-        if (data.getIncludeTxPowerLevel()) {
-            size += OVERHEAD_BYTES_PER_FIELD + 1; // tx power level value is one byte.
-        }
-        if (data.getIncludeDeviceName()) {
-            final int length = mBluetoothAdapter.getNameLengthForAdvertise();
-            if (length >= 0) {
-                size += OVERHEAD_BYTES_PER_FIELD + length;
-            }
-        }
-        return size;
-    }
-
-    private int byteLength(byte[] array) {
-        return array == null ? 0 : array.length;
-    }
-
-    @SuppressLint("AndroidFrameworkBluetoothPermission")
-    IAdvertisingSetCallback wrap(AdvertisingSetCallback callback, Handler handler) {
-        return new IAdvertisingSetCallback.Stub() {
-            @Override
-            public void onAdvertisingSetStarted(int advertiserId, int txPower, int status) {
-                handler.post(new Runnable() {
-                    @Override
-                    public void run() {
-                        if (status != AdvertisingSetCallback.ADVERTISE_SUCCESS) {
-                            callback.onAdvertisingSetStarted(null, 0, status);
-                            mCallbackWrappers.remove(callback);
-                            return;
-                        }
-
-                        AdvertisingSet advertisingSet = new AdvertisingSet(
-                                advertiserId, mBluetoothManager, mAttributionSource);
-                        mAdvertisingSets.put(advertiserId, advertisingSet);
-                        callback.onAdvertisingSetStarted(advertisingSet, txPower, status);
-                    }
-                });
-            }
-
-            @Override
-            public void onOwnAddressRead(int advertiserId, int addressType, String address) {
-                handler.post(new Runnable() {
-                    @Override
-                    public void run() {
-                        AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId);
-                        callback.onOwnAddressRead(advertisingSet, addressType, address);
-                    }
-                });
-            }
-
-            @Override
-            public void onAdvertisingSetStopped(int advertiserId) {
-                handler.post(new Runnable() {
-                    @Override
-                    public void run() {
-                        AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId);
-                        callback.onAdvertisingSetStopped(advertisingSet);
-                        mAdvertisingSets.remove(advertiserId);
-                        mCallbackWrappers.remove(callback);
-                    }
-                });
-            }
-
-            @Override
-            public void onAdvertisingEnabled(int advertiserId, boolean enabled, int status) {
-                handler.post(new Runnable() {
-                    @Override
-                    public void run() {
-                        AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId);
-                        callback.onAdvertisingEnabled(advertisingSet, enabled, status);
-                    }
-                });
-            }
-
-            @Override
-            public void onAdvertisingDataSet(int advertiserId, int status) {
-                handler.post(new Runnable() {
-                    @Override
-                    public void run() {
-                        AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId);
-                        callback.onAdvertisingDataSet(advertisingSet, status);
-                    }
-                });
-            }
-
-            @Override
-            public void onScanResponseDataSet(int advertiserId, int status) {
-                handler.post(new Runnable() {
-                    @Override
-                    public void run() {
-                        AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId);
-                        callback.onScanResponseDataSet(advertisingSet, status);
-                    }
-                });
-            }
-
-            @Override
-            public void onAdvertisingParametersUpdated(int advertiserId, int txPower, int status) {
-                handler.post(new Runnable() {
-                    @Override
-                    public void run() {
-                        AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId);
-                        callback.onAdvertisingParametersUpdated(advertisingSet, txPower, status);
-                    }
-                });
-            }
-
-            @Override
-            public void onPeriodicAdvertisingParametersUpdated(int advertiserId, int status) {
-                handler.post(new Runnable() {
-                    @Override
-                    public void run() {
-                        AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId);
-                        callback.onPeriodicAdvertisingParametersUpdated(advertisingSet, status);
-                    }
-                });
-            }
-
-            @Override
-            public void onPeriodicAdvertisingDataSet(int advertiserId, int status) {
-                handler.post(new Runnable() {
-                    @Override
-                    public void run() {
-                        AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId);
-                        callback.onPeriodicAdvertisingDataSet(advertisingSet, status);
-                    }
-                });
-            }
-
-            @Override
-            public void onPeriodicAdvertisingEnabled(int advertiserId, boolean enable, int status) {
-                handler.post(new Runnable() {
-                    @Override
-                    public void run() {
-                        AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId);
-                        callback.onPeriodicAdvertisingEnabled(advertisingSet, enable, status);
-                    }
-                });
-            }
-        };
-    }
-
-    @SuppressLint("AndroidFrameworkBluetoothPermission")
-    private void postStartSetFailure(Handler handler, final AdvertisingSetCallback callback,
-            final int error) {
-        handler.post(new Runnable() {
-            @Override
-            public void run() {
-                callback.onAdvertisingSetStarted(null, 0, error);
-            }
-        });
-    }
-
-    @SuppressLint("AndroidFrameworkBluetoothPermission")
-    private void postStartFailure(final AdvertiseCallback callback, final int error) {
-        mHandler.post(new Runnable() {
-            @Override
-            public void run() {
-                callback.onStartFailure(error);
-            }
-        });
-    }
-
-    @SuppressLint("AndroidFrameworkBluetoothPermission")
-    private void postStartSuccess(final AdvertiseCallback callback,
-            final AdvertiseSettings settings) {
-        mHandler.post(new Runnable() {
-
-            @Override
-            public void run() {
-                callback.onStartSuccess(settings);
-            }
-        });
-    }
-}
diff --git a/core/java/android/bluetooth/le/BluetoothLeScanner.java b/core/java/android/bluetooth/le/BluetoothLeScanner.java
deleted file mode 100644
index 540e5a7..0000000
--- a/core/java/android/bluetooth/le/BluetoothLeScanner.java
+++ /dev/null
@@ -1,658 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package android.bluetooth.le;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.RequiresNoPermission;
-import android.annotation.RequiresPermission;
-import android.annotation.SuppressLint;
-import android.annotation.SystemApi;
-import android.app.PendingIntent;
-import android.bluetooth.Attributable;
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothGatt;
-import android.bluetooth.IBluetoothGatt;
-import android.bluetooth.IBluetoothManager;
-import android.bluetooth.annotations.RequiresBluetoothLocationPermission;
-import android.bluetooth.annotations.RequiresBluetoothScanPermission;
-import android.bluetooth.annotations.RequiresLegacyBluetoothAdminPermission;
-import android.content.AttributionSource;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.RemoteException;
-import android.os.WorkSource;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-
-/**
- * This class provides methods to perform scan related operations for Bluetooth LE devices. An
- * application can scan for a particular type of Bluetooth LE devices using {@link ScanFilter}. It
- * can also request different types of callbacks for delivering the result.
- * <p>
- * Use {@link BluetoothAdapter#getBluetoothLeScanner()} to get an instance of
- * {@link BluetoothLeScanner}.
- *
- * @see ScanFilter
- */
-public final class BluetoothLeScanner {
-
-    private static final String TAG = "BluetoothLeScanner";
-    private static final boolean DBG = true;
-    private static final boolean VDBG = false;
-
-    /**
-     * Extra containing a list of ScanResults. It can have one or more results if there was no
-     * error. In case of error, {@link #EXTRA_ERROR_CODE} will contain the error code and this
-     * extra will not be available.
-     */
-    public static final String EXTRA_LIST_SCAN_RESULT =
-            "android.bluetooth.le.extra.LIST_SCAN_RESULT";
-
-    /**
-     * Optional extra indicating the error code, if any. The error code will be one of the
-     * SCAN_FAILED_* codes in {@link ScanCallback}.
-     */
-    public static final String EXTRA_ERROR_CODE = "android.bluetooth.le.extra.ERROR_CODE";
-
-    /**
-     * Optional extra indicating the callback type, which will be one of
-     * CALLBACK_TYPE_* constants in {@link ScanSettings}.
-     *
-     * @see ScanCallback#onScanResult(int, ScanResult)
-     */
-    public static final String EXTRA_CALLBACK_TYPE = "android.bluetooth.le.extra.CALLBACK_TYPE";
-
-    private final BluetoothAdapter mBluetoothAdapter;
-    private final IBluetoothManager mBluetoothManager;
-    private final AttributionSource mAttributionSource;
-
-    private final Handler mHandler;
-    private final Map<ScanCallback, BleScanCallbackWrapper> mLeScanClients;
-
-    /**
-     * Use {@link BluetoothAdapter#getBluetoothLeScanner()} instead.
-     *
-     * @param bluetoothManager BluetoothManager that conducts overall Bluetooth Management.
-     * @param opPackageName The opPackageName of the context this object was created from
-     * @param featureId  The featureId of the context this object was created from
-     * @hide
-     */
-    public BluetoothLeScanner(BluetoothAdapter bluetoothAdapter) {
-        mBluetoothAdapter = Objects.requireNonNull(bluetoothAdapter);
-        mBluetoothManager = mBluetoothAdapter.getBluetoothManager();
-        mAttributionSource = mBluetoothAdapter.getAttributionSource();
-        mHandler = new Handler(Looper.getMainLooper());
-        mLeScanClients = new HashMap<ScanCallback, BleScanCallbackWrapper>();
-    }
-
-    /**
-     * Start Bluetooth LE scan with default parameters and no filters. The scan results will be
-     * delivered through {@code callback}. For unfiltered scans, scanning is stopped on screen
-     * off to save power. Scanning is resumed when screen is turned on again. To avoid this, use
-     * {@link #startScan(List, ScanSettings, ScanCallback)} with desired {@link ScanFilter}.
-     * <p>
-     * An app must have
-     * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION} permission
-     * in order to get results. An App targeting Android Q or later must have
-     * {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} permission
-     * in order to get results.
-     *
-     * @param callback Callback used to deliver scan results.
-     * @throws IllegalArgumentException If {@code callback} is null.
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothScanPermission
-    @RequiresBluetoothLocationPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
-    public void startScan(final ScanCallback callback) {
-        startScan(null, new ScanSettings.Builder().build(), callback);
-    }
-
-    /**
-     * Start Bluetooth LE scan. The scan results will be delivered through {@code callback}.
-     * For unfiltered scans, scanning is stopped on screen off to save power. Scanning is
-     * resumed when screen is turned on again. To avoid this, do filetered scanning by
-     * using proper {@link ScanFilter}.
-     * <p>
-     * An app must have
-     * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION} permission
-     * in order to get results. An App targeting Android Q or later must have
-     * {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} permission
-     * in order to get results.
-     *
-     * @param filters {@link ScanFilter}s for finding exact BLE devices.
-     * @param settings Settings for the scan.
-     * @param callback Callback used to deliver scan results.
-     * @throws IllegalArgumentException If {@code settings} or {@code callback} is null.
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothScanPermission
-    @RequiresBluetoothLocationPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
-    public void startScan(List<ScanFilter> filters, ScanSettings settings,
-            final ScanCallback callback) {
-        startScan(filters, settings, null, callback, /*callbackIntent=*/ null);
-    }
-
-    /**
-     * Start Bluetooth LE scan using a {@link PendingIntent}. The scan results will be delivered via
-     * the PendingIntent. Use this method of scanning if your process is not always running and it
-     * should be started when scan results are available.
-     * <p>
-     * An app must have
-     * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION} permission
-     * in order to get results. An App targeting Android Q or later must have
-     * {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} permission
-     * in order to get results.
-     * <p>
-     * When the PendingIntent is delivered, the Intent passed to the receiver or activity
-     * will contain one or more of the extras {@link #EXTRA_CALLBACK_TYPE},
-     * {@link #EXTRA_ERROR_CODE} and {@link #EXTRA_LIST_SCAN_RESULT} to indicate the result of
-     * the scan.
-     *
-     * @param filters Optional list of ScanFilters for finding exact BLE devices.
-     * @param settings Optional settings for the scan.
-     * @param callbackIntent The PendingIntent to deliver the result to.
-     * @return Returns 0 for success or an error code from {@link ScanCallback} if the scan request
-     * could not be sent.
-     * @see #stopScan(PendingIntent)
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothScanPermission
-    @RequiresBluetoothLocationPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
-    public int startScan(@Nullable List<ScanFilter> filters, @Nullable ScanSettings settings,
-            @NonNull PendingIntent callbackIntent) {
-        return startScan(filters,
-                settings != null ? settings : new ScanSettings.Builder().build(),
-                null, null, callbackIntent);
-    }
-
-    /**
-     * Start Bluetooth LE scan. Same as {@link #startScan(ScanCallback)} but allows the caller to
-     * specify on behalf of which application(s) the work is being done.
-     *
-     * @param workSource {@link WorkSource} identifying the application(s) for which to blame for
-     * the scan.
-     * @param callback Callback used to deliver scan results.
-     * @hide
-     */
-    @SystemApi
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothScanPermission
-    @RequiresBluetoothLocationPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_SCAN,
-            android.Manifest.permission.UPDATE_DEVICE_STATS
-    })
-    public void startScanFromSource(final WorkSource workSource, final ScanCallback callback) {
-        startScanFromSource(null, new ScanSettings.Builder().build(), workSource, callback);
-    }
-
-    /**
-     * Start Bluetooth LE scan. Same as {@link #startScan(List, ScanSettings, ScanCallback)} but
-     * allows the caller to specify on behalf of which application(s) the work is being done.
-     *
-     * @param filters {@link ScanFilter}s for finding exact BLE devices.
-     * @param settings Settings for the scan.
-     * @param workSource {@link WorkSource} identifying the application(s) for which to blame for
-     * the scan.
-     * @param callback Callback used to deliver scan results.
-     * @hide
-     */
-    @SystemApi
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothScanPermission
-    @RequiresBluetoothLocationPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_SCAN,
-            android.Manifest.permission.UPDATE_DEVICE_STATS
-    })
-    @SuppressLint("AndroidFrameworkRequiresPermission")
-    public void startScanFromSource(List<ScanFilter> filters, ScanSettings settings,
-            final WorkSource workSource, final ScanCallback callback) {
-        startScan(filters, settings, workSource, callback, null);
-    }
-
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
-    private int startScan(List<ScanFilter> filters, ScanSettings settings,
-            final WorkSource workSource, final ScanCallback callback,
-            final PendingIntent callbackIntent) {
-        BluetoothLeUtils.checkAdapterStateOn(mBluetoothAdapter);
-        if (callback == null && callbackIntent == null) {
-            throw new IllegalArgumentException("callback is null");
-        }
-        if (settings == null) {
-            throw new IllegalArgumentException("settings is null");
-        }
-        synchronized (mLeScanClients) {
-            if (callback != null && mLeScanClients.containsKey(callback)) {
-                return postCallbackErrorOrReturn(callback,
-                            ScanCallback.SCAN_FAILED_ALREADY_STARTED);
-            }
-            IBluetoothGatt gatt;
-            try {
-                gatt = mBluetoothManager.getBluetoothGatt();
-            } catch (RemoteException e) {
-                gatt = null;
-            }
-            if (gatt == null) {
-                return postCallbackErrorOrReturn(callback, ScanCallback.SCAN_FAILED_INTERNAL_ERROR);
-            }
-            if (!isSettingsConfigAllowedForScan(settings)) {
-                return postCallbackErrorOrReturn(callback,
-                        ScanCallback.SCAN_FAILED_FEATURE_UNSUPPORTED);
-            }
-            if (!isHardwareResourcesAvailableForScan(settings)) {
-                return postCallbackErrorOrReturn(callback,
-                        ScanCallback.SCAN_FAILED_OUT_OF_HARDWARE_RESOURCES);
-            }
-            if (!isSettingsAndFilterComboAllowed(settings, filters)) {
-                return postCallbackErrorOrReturn(callback,
-                        ScanCallback.SCAN_FAILED_FEATURE_UNSUPPORTED);
-            }
-            if (callback != null) {
-                BleScanCallbackWrapper wrapper = new BleScanCallbackWrapper(gatt, filters,
-                        settings, workSource, callback);
-                wrapper.startRegistration();
-            } else {
-                try {
-                    gatt.startScanForIntent(callbackIntent, settings, filters,
-                            mAttributionSource);
-                } catch (RemoteException e) {
-                    return ScanCallback.SCAN_FAILED_INTERNAL_ERROR;
-                }
-            }
-        }
-        return ScanCallback.NO_ERROR;
-    }
-
-    /**
-     * Stops an ongoing Bluetooth LE scan.
-     *
-     * @param callback
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothScanPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
-    public void stopScan(ScanCallback callback) {
-        BluetoothLeUtils.checkAdapterStateOn(mBluetoothAdapter);
-        synchronized (mLeScanClients) {
-            BleScanCallbackWrapper wrapper = mLeScanClients.remove(callback);
-            if (wrapper == null) {
-                if (DBG) Log.d(TAG, "could not find callback wrapper");
-                return;
-            }
-            wrapper.stopLeScan();
-        }
-    }
-
-    /**
-     * Stops an ongoing Bluetooth LE scan started using a PendingIntent. When creating the
-     * PendingIntent parameter, please do not use the FLAG_CANCEL_CURRENT flag. Otherwise, the stop
-     * scan may have no effect.
-     *
-     * @param callbackIntent The PendingIntent that was used to start the scan.
-     * @see #startScan(List, ScanSettings, PendingIntent)
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothScanPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
-    public void stopScan(PendingIntent callbackIntent) {
-        BluetoothLeUtils.checkAdapterStateOn(mBluetoothAdapter);
-        IBluetoothGatt gatt;
-        try {
-            gatt = mBluetoothManager.getBluetoothGatt();
-            gatt.stopScanForIntent(callbackIntent, mAttributionSource);
-        } catch (RemoteException e) {
-        }
-    }
-
-    /**
-     * Flush pending batch scan results stored in Bluetooth controller. This will return Bluetooth
-     * LE scan results batched on bluetooth controller. Returns immediately, batch scan results data
-     * will be delivered through the {@code callback}.
-     *
-     * @param callback Callback of the Bluetooth LE Scan, it has to be the same instance as the one
-     * used to start scan.
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothScanPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
-    public void flushPendingScanResults(ScanCallback callback) {
-        BluetoothLeUtils.checkAdapterStateOn(mBluetoothAdapter);
-        if (callback == null) {
-            throw new IllegalArgumentException("callback cannot be null!");
-        }
-        synchronized (mLeScanClients) {
-            BleScanCallbackWrapper wrapper = mLeScanClients.get(callback);
-            if (wrapper == null) {
-                return;
-            }
-            wrapper.flushPendingBatchResults();
-        }
-    }
-
-    /**
-     * Start truncated scan.
-     *
-     * @deprecated this is not used anywhere
-     *
-     * @hide
-     */
-    @Deprecated
-    @SystemApi
-    @RequiresBluetoothScanPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
-    public void startTruncatedScan(List<TruncatedFilter> truncatedFilters, ScanSettings settings,
-            final ScanCallback callback) {
-        int filterSize = truncatedFilters.size();
-        List<ScanFilter> scanFilters = new ArrayList<ScanFilter>(filterSize);
-        for (TruncatedFilter filter : truncatedFilters) {
-            scanFilters.add(filter.getFilter());
-        }
-        startScan(scanFilters, settings, null, callback, null);
-    }
-
-    /**
-     * Cleans up scan clients. Should be called when bluetooth is down.
-     *
-     * @hide
-     */
-    @RequiresNoPermission
-    public void cleanup() {
-        mLeScanClients.clear();
-    }
-
-    /**
-     * Bluetooth GATT interface callbacks
-     */
-    @SuppressLint("AndroidFrameworkRequiresPermission")
-    private class BleScanCallbackWrapper extends IScannerCallback.Stub {
-        private static final int REGISTRATION_CALLBACK_TIMEOUT_MILLIS = 2000;
-
-        private final ScanCallback mScanCallback;
-        private final List<ScanFilter> mFilters;
-        private final WorkSource mWorkSource;
-        private ScanSettings mSettings;
-        private IBluetoothGatt mBluetoothGatt;
-
-        // mLeHandle 0: not registered
-        // -2: registration failed because app is scanning to frequently
-        // -1: scan stopped or registration failed
-        // > 0: registered and scan started
-        private int mScannerId;
-
-        public BleScanCallbackWrapper(IBluetoothGatt bluetoothGatt,
-                List<ScanFilter> filters, ScanSettings settings,
-                WorkSource workSource, ScanCallback scanCallback) {
-            mBluetoothGatt = bluetoothGatt;
-            mFilters = filters;
-            mSettings = settings;
-            mWorkSource = workSource;
-            mScanCallback = scanCallback;
-            mScannerId = 0;
-        }
-
-        public void startRegistration() {
-            synchronized (this) {
-                // Scan stopped.
-                if (mScannerId == -1 || mScannerId == -2) return;
-                try {
-                    mBluetoothGatt.registerScanner(this, mWorkSource, mAttributionSource);
-                    wait(REGISTRATION_CALLBACK_TIMEOUT_MILLIS);
-                } catch (InterruptedException | RemoteException e) {
-                    Log.e(TAG, "application registeration exception", e);
-                    postCallbackError(mScanCallback, ScanCallback.SCAN_FAILED_INTERNAL_ERROR);
-                }
-                if (mScannerId > 0) {
-                    mLeScanClients.put(mScanCallback, this);
-                } else {
-                    // Registration timed out or got exception, reset RscannerId to -1 so no
-                    // subsequent operations can proceed.
-                    if (mScannerId == 0) mScannerId = -1;
-
-                    // If scanning too frequently, don't report anything to the app.
-                    if (mScannerId == -2) return;
-
-                    postCallbackError(mScanCallback,
-                            ScanCallback.SCAN_FAILED_APPLICATION_REGISTRATION_FAILED);
-                }
-            }
-        }
-
-        @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
-        public void stopLeScan() {
-            synchronized (this) {
-                if (mScannerId <= 0) {
-                    Log.e(TAG, "Error state, mLeHandle: " + mScannerId);
-                    return;
-                }
-                try {
-                    mBluetoothGatt.stopScan(mScannerId, mAttributionSource);
-                    mBluetoothGatt.unregisterScanner(mScannerId, mAttributionSource);
-                } catch (RemoteException e) {
-                    Log.e(TAG, "Failed to stop scan and unregister", e);
-                }
-                mScannerId = -1;
-            }
-        }
-
-        @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
-        void flushPendingBatchResults() {
-            synchronized (this) {
-                if (mScannerId <= 0) {
-                    Log.e(TAG, "Error state, mLeHandle: " + mScannerId);
-                    return;
-                }
-                try {
-                    mBluetoothGatt.flushPendingBatchResults(mScannerId, mAttributionSource);
-                } catch (RemoteException e) {
-                    Log.e(TAG, "Failed to get pending scan results", e);
-                }
-            }
-        }
-
-        /**
-         * Application interface registered - app is ready to go
-         */
-        @Override
-        public void onScannerRegistered(int status, int scannerId) {
-            Log.d(TAG, "onScannerRegistered() - status=" + status
-                    + " scannerId=" + scannerId + " mScannerId=" + mScannerId);
-            synchronized (this) {
-                if (status == BluetoothGatt.GATT_SUCCESS) {
-                    try {
-                        if (mScannerId == -1) {
-                            // Registration succeeds after timeout, unregister scanner.
-                            mBluetoothGatt.unregisterScanner(scannerId, mAttributionSource);
-                        } else {
-                            mScannerId = scannerId;
-                            mBluetoothGatt.startScan(mScannerId, mSettings, mFilters,
-                                    mAttributionSource);
-                        }
-                    } catch (RemoteException e) {
-                        Log.e(TAG, "fail to start le scan: " + e);
-                        mScannerId = -1;
-                    }
-                } else if (status == ScanCallback.SCAN_FAILED_SCANNING_TOO_FREQUENTLY) {
-                    // applicaiton was scanning too frequently
-                    mScannerId = -2;
-                } else {
-                    // registration failed
-                    mScannerId = -1;
-                }
-                notifyAll();
-            }
-        }
-
-        /**
-         * Callback reporting an LE scan result.
-         *
-         * @hide
-         */
-        @Override
-        public void onScanResult(final ScanResult scanResult) {
-            Attributable.setAttributionSource(scanResult, mAttributionSource);
-            if (Log.isLoggable(TAG, Log.DEBUG)) {
-                Log.d(TAG, "onScanResult() - mScannerId=" + mScannerId);
-            }
-            if (VDBG) Log.d(TAG, "onScanResult() - " + scanResult.toString());
-
-            // Check null in case the scan has been stopped
-            synchronized (this) {
-                if (mScannerId <= 0) {
-                    if (Log.isLoggable(TAG, Log.DEBUG)) {
-                        Log.d(TAG, "Ignoring result as scan stopped.");
-                    }
-                    return;
-                };
-            }
-            Handler handler = new Handler(Looper.getMainLooper());
-            handler.post(new Runnable() {
-                @Override
-                public void run() {
-                    if (Log.isLoggable(TAG, Log.DEBUG)) {
-                        Log.d(TAG, "onScanResult() - handler run");
-                    }
-                    mScanCallback.onScanResult(ScanSettings.CALLBACK_TYPE_ALL_MATCHES, scanResult);
-                }
-            });
-        }
-
-        @Override
-        public void onBatchScanResults(final List<ScanResult> results) {
-            Attributable.setAttributionSource(results, mAttributionSource);
-            Handler handler = new Handler(Looper.getMainLooper());
-            handler.post(new Runnable() {
-                @Override
-                public void run() {
-                    mScanCallback.onBatchScanResults(results);
-                }
-            });
-        }
-
-        @Override
-        public void onFoundOrLost(final boolean onFound, final ScanResult scanResult) {
-            Attributable.setAttributionSource(scanResult, mAttributionSource);
-            if (VDBG) {
-                Log.d(TAG, "onFoundOrLost() - onFound = " + onFound + " " + scanResult.toString());
-            }
-
-            // Check null in case the scan has been stopped
-            synchronized (this) {
-                if (mScannerId <= 0) {
-                    return;
-                }
-            }
-            Handler handler = new Handler(Looper.getMainLooper());
-            handler.post(new Runnable() {
-                @Override
-                public void run() {
-                    if (onFound) {
-                        mScanCallback.onScanResult(ScanSettings.CALLBACK_TYPE_FIRST_MATCH,
-                                scanResult);
-                    } else {
-                        mScanCallback.onScanResult(ScanSettings.CALLBACK_TYPE_MATCH_LOST,
-                                scanResult);
-                    }
-                }
-            });
-        }
-
-        @Override
-        public void onScanManagerErrorCallback(final int errorCode) {
-            if (VDBG) {
-                Log.d(TAG, "onScanManagerErrorCallback() - errorCode = " + errorCode);
-            }
-            synchronized (this) {
-                if (mScannerId <= 0) {
-                    return;
-                }
-            }
-            postCallbackError(mScanCallback, errorCode);
-        }
-    }
-
-    private int postCallbackErrorOrReturn(final ScanCallback callback, final int errorCode) {
-        if (callback == null) {
-            return errorCode;
-        } else {
-            postCallbackError(callback, errorCode);
-            return ScanCallback.NO_ERROR;
-        }
-    }
-
-    @SuppressLint("AndroidFrameworkBluetoothPermission")
-    private void postCallbackError(final ScanCallback callback, final int errorCode) {
-        mHandler.post(new Runnable() {
-            @Override
-            public void run() {
-                callback.onScanFailed(errorCode);
-            }
-        });
-    }
-
-    private boolean isSettingsConfigAllowedForScan(ScanSettings settings) {
-        if (mBluetoothAdapter.isOffloadedFilteringSupported()) {
-            return true;
-        }
-        final int callbackType = settings.getCallbackType();
-        // Only support regular scan if no offloaded filter support.
-        if (callbackType == ScanSettings.CALLBACK_TYPE_ALL_MATCHES
-                && settings.getReportDelayMillis() == 0) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean isSettingsAndFilterComboAllowed(ScanSettings settings,
-            List<ScanFilter> filterList) {
-        final int callbackType = settings.getCallbackType();
-        // If onlost/onfound is requested, a non-empty filter is expected
-        if ((callbackType & (ScanSettings.CALLBACK_TYPE_FIRST_MATCH
-                | ScanSettings.CALLBACK_TYPE_MATCH_LOST)) != 0) {
-            if (filterList == null) {
-                return false;
-            }
-            for (ScanFilter filter : filterList) {
-                if (filter.isAllFieldsEmpty()) {
-                    return false;
-                }
-            }
-        }
-        return true;
-    }
-
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    private boolean isHardwareResourcesAvailableForScan(ScanSettings settings) {
-        final int callbackType = settings.getCallbackType();
-        if ((callbackType & ScanSettings.CALLBACK_TYPE_FIRST_MATCH) != 0
-                || (callbackType & ScanSettings.CALLBACK_TYPE_MATCH_LOST) != 0) {
-            // For onlost/onfound, we required hw support be available
-            return (mBluetoothAdapter.isOffloadedFilteringSupported()
-                    && mBluetoothAdapter.isHardwareTrackingFiltersAvailable());
-        }
-        return true;
-    }
-}
diff --git a/core/java/android/bluetooth/le/BluetoothLeUtils.java b/core/java/android/bluetooth/le/BluetoothLeUtils.java
deleted file mode 100644
index ed50b09..0000000
--- a/core/java/android/bluetooth/le/BluetoothLeUtils.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.le;
-
-import android.bluetooth.BluetoothAdapter;
-import android.util.SparseArray;
-
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import java.util.UUID;
-
-/**
- * Helper class for Bluetooth LE utils.
- *
- * @hide
- */
-public class BluetoothLeUtils {
-
-    /**
-     * Returns a string composed from a {@link SparseArray}.
-     */
-    static String toString(SparseArray<byte[]> array) {
-        if (array == null) {
-            return "null";
-        }
-        if (array.size() == 0) {
-            return "{}";
-        }
-        StringBuilder buffer = new StringBuilder();
-        buffer.append('{');
-        for (int i = 0; i < array.size(); ++i) {
-            buffer.append(array.keyAt(i)).append("=").append(Arrays.toString(array.valueAt(i)));
-        }
-        buffer.append('}');
-        return buffer.toString();
-    }
-
-    /**
-     * Returns a string composed from a {@link Map}.
-     */
-    static <T> String toString(Map<T, byte[]> map) {
-        if (map == null) {
-            return "null";
-        }
-        if (map.isEmpty()) {
-            return "{}";
-        }
-        StringBuilder buffer = new StringBuilder();
-        buffer.append('{');
-        Iterator<Map.Entry<T, byte[]>> it = map.entrySet().iterator();
-        while (it.hasNext()) {
-            Map.Entry<T, byte[]> entry = it.next();
-            Object key = entry.getKey();
-            buffer.append(key).append("=").append(Arrays.toString(map.get(key)));
-            if (it.hasNext()) {
-                buffer.append(", ");
-            }
-        }
-        buffer.append('}');
-        return buffer.toString();
-    }
-
-    /**
-     * Check whether two {@link SparseArray} equal.
-     */
-    static boolean equals(SparseArray<byte[]> array, SparseArray<byte[]> otherArray) {
-        if (array == otherArray) {
-            return true;
-        }
-        if (array == null || otherArray == null) {
-            return false;
-        }
-        if (array.size() != otherArray.size()) {
-            return false;
-        }
-
-        // Keys are guaranteed in ascending order when indices are in ascending order.
-        for (int i = 0; i < array.size(); ++i) {
-            if (array.keyAt(i) != otherArray.keyAt(i)
-                    || !Arrays.equals(array.valueAt(i), otherArray.valueAt(i))) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Check whether two {@link Map} equal.
-     */
-    static <T> boolean equals(Map<T, byte[]> map, Map<T, byte[]> otherMap) {
-        if (map == otherMap) {
-            return true;
-        }
-        if (map == null || otherMap == null) {
-            return false;
-        }
-        if (map.size() != otherMap.size()) {
-            return false;
-        }
-        Set<T> keys = map.keySet();
-        if (!keys.equals(otherMap.keySet())) {
-            return false;
-        }
-        for (T key : keys) {
-            if (!Objects.deepEquals(map.get(key), otherMap.get(key))) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Ensure Bluetooth is turned on.
-     *
-     * @throws IllegalStateException If {@code adapter} is null or Bluetooth state is not {@link
-     * BluetoothAdapter#STATE_ON}.
-     */
-    static void checkAdapterStateOn(BluetoothAdapter adapter) {
-        if (adapter == null || !adapter.isLeEnabled()) {
-            throw new IllegalStateException("BT Adapter is not turned ON");
-        }
-    }
-
-    /**
-     * Compares two UUIDs with a UUID mask.
-     *
-     * @param data first {@link #UUID} to compare.
-     * @param uuid second {@link #UUID} to compare.
-     * @param mask mask {@link #UUID}.
-     * @return true if both UUIDs are equals when masked, false otherwise.
-     */
-    static boolean maskedEquals(UUID data, UUID uuid, UUID mask) {
-        if (mask == null) {
-            return Objects.equals(data, uuid);
-        }
-        return (data.getLeastSignificantBits() & mask.getLeastSignificantBits())
-                == (uuid.getLeastSignificantBits() & mask.getLeastSignificantBits())
-                && (data.getMostSignificantBits() & mask.getMostSignificantBits())
-                == (uuid.getMostSignificantBits() & mask.getMostSignificantBits());
-    }
-}
diff --git a/core/java/android/bluetooth/le/OWNERS b/core/java/android/bluetooth/le/OWNERS
deleted file mode 100644
index 3523ee0..0000000
--- a/core/java/android/bluetooth/le/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-# Bug component: 27441
-
-zachoverflow@google.com
-siyuanh@google.com
diff --git a/core/java/android/bluetooth/le/PeriodicAdvertisingCallback.java b/core/java/android/bluetooth/le/PeriodicAdvertisingCallback.java
deleted file mode 100644
index 14ac911..0000000
--- a/core/java/android/bluetooth/le/PeriodicAdvertisingCallback.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.le;
-
-import android.bluetooth.BluetoothDevice;
-
-/**
- * Bluetooth LE periodic advertising callbacks, used to deliver periodic
- * advertising operation status.
- *
- * @hide
- * @see PeriodicAdvertisingManager#createSync
- */
-public abstract class PeriodicAdvertisingCallback {
-
-    /**
-     * The requested operation was successful.
-     *
-     * @hide
-     */
-    public static final int SYNC_SUCCESS = 0;
-
-    /**
-     * Sync failed to be established because remote device did not respond.
-     */
-    public static final int SYNC_NO_RESPONSE = 1;
-
-    /**
-     * Sync failed to be established because controller can't support more syncs.
-     */
-    public static final int SYNC_NO_RESOURCES = 2;
-
-
-    /**
-     * Callback when synchronization was established.
-     *
-     * @param syncHandle handle used to identify this synchronization.
-     * @param device remote device.
-     * @param advertisingSid synchronized advertising set id.
-     * @param skip The number of periodic advertising packets that can be skipped after a successful
-     * receive in force. @see PeriodicAdvertisingManager#createSync
-     * @param timeout Synchronization timeout for the periodic advertising in force. One unit is
-     * 10ms. @see PeriodicAdvertisingManager#createSync
-     * @param timeout
-     * @param status operation status.
-     */
-    public void onSyncEstablished(int syncHandle, BluetoothDevice device,
-            int advertisingSid, int skip, int timeout,
-            int status) {
-    }
-
-    /**
-     * Callback when periodic advertising report is received.
-     *
-     * @param report periodic advertising report.
-     */
-    public void onPeriodicAdvertisingReport(PeriodicAdvertisingReport report) {
-    }
-
-    /**
-     * Callback when periodic advertising synchronization was lost.
-     *
-     * @param syncHandle handle used to identify this synchronization.
-     */
-    public void onSyncLost(int syncHandle) {
-    }
-}
diff --git a/core/java/android/bluetooth/le/PeriodicAdvertisingManager.java b/core/java/android/bluetooth/le/PeriodicAdvertisingManager.java
deleted file mode 100644
index bbd3117..0000000
--- a/core/java/android/bluetooth/le/PeriodicAdvertisingManager.java
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package android.bluetooth.le;
-
-import android.annotation.RequiresPermission;
-import android.annotation.SuppressLint;
-import android.bluetooth.Attributable;
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.IBluetoothGatt;
-import android.bluetooth.IBluetoothManager;
-import android.bluetooth.annotations.RequiresBluetoothLocationPermission;
-import android.bluetooth.annotations.RequiresBluetoothScanPermission;
-import android.bluetooth.annotations.RequiresLegacyBluetoothAdminPermission;
-import android.content.AttributionSource;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.util.IdentityHashMap;
-import java.util.Map;
-import java.util.Objects;
-
-/**
- * This class provides methods to perform periodic advertising related
- * operations. An application can register for periodic advertisements using
- * {@link PeriodicAdvertisingManager#registerSync}.
- * <p>
- * Use {@link BluetoothAdapter#getPeriodicAdvertisingManager()} to get an
- * instance of {@link PeriodicAdvertisingManager}.
- *
- * @hide
- */
-public final class PeriodicAdvertisingManager {
-
-    private static final String TAG = "PeriodicAdvertisingManager";
-
-    private static final int SKIP_MIN = 0;
-    private static final int SKIP_MAX = 499;
-    private static final int TIMEOUT_MIN = 10;
-    private static final int TIMEOUT_MAX = 16384;
-
-    private static final int SYNC_STARTING = -1;
-
-    private final BluetoothAdapter mBluetoothAdapter;
-    private final IBluetoothManager mBluetoothManager;
-    private final AttributionSource mAttributionSource;
-
-    /* maps callback, to callback wrapper and sync handle */
-    Map<PeriodicAdvertisingCallback,
-            IPeriodicAdvertisingCallback /* callbackWrapper */> mCallbackWrappers;
-
-    /**
-     * Use {@link BluetoothAdapter#getBluetoothLeScanner()} instead.
-     *
-     * @param bluetoothManager BluetoothManager that conducts overall Bluetooth Management.
-     * @hide
-     */
-    public PeriodicAdvertisingManager(BluetoothAdapter bluetoothAdapter) {
-        mBluetoothAdapter = Objects.requireNonNull(bluetoothAdapter);
-        mBluetoothManager = mBluetoothAdapter.getBluetoothManager();
-        mAttributionSource = mBluetoothAdapter.getAttributionSource();
-        mCallbackWrappers = new IdentityHashMap<>();
-    }
-
-    /**
-     * Synchronize with periodic advertising pointed to by the {@code scanResult}.
-     * The {@code scanResult} used must contain a valid advertisingSid. First
-     * call to registerSync will use the {@code skip} and {@code timeout} provided.
-     * Subsequent calls from other apps, trying to sync with same set will reuse
-     * existing sync, thus {@code skip} and {@code timeout} values will not take
-     * effect. The values in effect will be returned in
-     * {@link PeriodicAdvertisingCallback#onSyncEstablished}.
-     *
-     * @param scanResult Scan result containing advertisingSid.
-     * @param skip The number of periodic advertising packets that can be skipped after a successful
-     * receive. Must be between 0 and 499.
-     * @param timeout Synchronization timeout for the periodic advertising. One unit is 10ms. Must
-     * be between 10 (100ms) and 16384 (163.84s).
-     * @param callback Callback used to deliver all operations status.
-     * @throws IllegalArgumentException if {@code scanResult} is null or {@code skip} is invalid or
-     * {@code timeout} is invalid or {@code callback} is null.
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothScanPermission
-    @RequiresBluetoothLocationPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
-    public void registerSync(ScanResult scanResult, int skip, int timeout,
-            PeriodicAdvertisingCallback callback) {
-        registerSync(scanResult, skip, timeout, callback, null);
-    }
-
-    /**
-     * Synchronize with periodic advertising pointed to by the {@code scanResult}.
-     * The {@code scanResult} used must contain a valid advertisingSid. First
-     * call to registerSync will use the {@code skip} and {@code timeout} provided.
-     * Subsequent calls from other apps, trying to sync with same set will reuse
-     * existing sync, thus {@code skip} and {@code timeout} values will not take
-     * effect. The values in effect will be returned in
-     * {@link PeriodicAdvertisingCallback#onSyncEstablished}.
-     *
-     * @param scanResult Scan result containing advertisingSid.
-     * @param skip The number of periodic advertising packets that can be skipped after a successful
-     * receive. Must be between 0 and 499.
-     * @param timeout Synchronization timeout for the periodic advertising. One unit is 10ms. Must
-     * be between 10 (100ms) and 16384 (163.84s).
-     * @param callback Callback used to deliver all operations status.
-     * @param handler thread upon which the callbacks will be invoked.
-     * @throws IllegalArgumentException if {@code scanResult} is null or {@code skip} is invalid or
-     * {@code timeout} is invalid or {@code callback} is null.
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothScanPermission
-    @RequiresBluetoothLocationPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
-    public void registerSync(ScanResult scanResult, int skip, int timeout,
-            PeriodicAdvertisingCallback callback, Handler handler) {
-        if (callback == null) {
-            throw new IllegalArgumentException("callback can't be null");
-        }
-
-        if (scanResult == null) {
-            throw new IllegalArgumentException("scanResult can't be null");
-        }
-
-        if (scanResult.getAdvertisingSid() == ScanResult.SID_NOT_PRESENT) {
-            throw new IllegalArgumentException("scanResult must contain a valid sid");
-        }
-
-        if (skip < SKIP_MIN || skip > SKIP_MAX) {
-            throw new IllegalArgumentException(
-                    "timeout must be between " + TIMEOUT_MIN + " and " + TIMEOUT_MAX);
-        }
-
-        if (timeout < TIMEOUT_MIN || timeout > TIMEOUT_MAX) {
-            throw new IllegalArgumentException(
-                    "timeout must be between " + TIMEOUT_MIN + " and " + TIMEOUT_MAX);
-        }
-
-        IBluetoothGatt gatt;
-        try {
-            gatt = mBluetoothManager.getBluetoothGatt();
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to get Bluetooth gatt - ", e);
-            callback.onSyncEstablished(0, scanResult.getDevice(), scanResult.getAdvertisingSid(),
-                    skip, timeout,
-                    PeriodicAdvertisingCallback.SYNC_NO_RESOURCES);
-            return;
-        }
-
-        if (handler == null) {
-            handler = new Handler(Looper.getMainLooper());
-        }
-
-        IPeriodicAdvertisingCallback wrapped = wrap(callback, handler);
-        mCallbackWrappers.put(callback, wrapped);
-
-        try {
-            gatt.registerSync(
-                    scanResult, skip, timeout, wrapped, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to register sync - ", e);
-            return;
-        }
-    }
-
-    /**
-     * Cancel pending attempt to create sync, or terminate existing sync.
-     *
-     * @param callback Callback used to deliver all operations status.
-     * @throws IllegalArgumentException if {@code callback} is null, or not a properly registered
-     * callback.
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothScanPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
-    public void unregisterSync(PeriodicAdvertisingCallback callback) {
-        if (callback == null) {
-            throw new IllegalArgumentException("callback can't be null");
-        }
-
-        IBluetoothGatt gatt;
-        try {
-            gatt = mBluetoothManager.getBluetoothGatt();
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to get Bluetooth gatt - ", e);
-            return;
-        }
-
-        IPeriodicAdvertisingCallback wrapper = mCallbackWrappers.remove(callback);
-        if (wrapper == null) {
-            throw new IllegalArgumentException("callback was not properly registered");
-        }
-
-        try {
-            gatt.unregisterSync(wrapper, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to cancel sync creation - ", e);
-            return;
-        }
-    }
-
-    @SuppressLint("AndroidFrameworkBluetoothPermission")
-    private IPeriodicAdvertisingCallback wrap(PeriodicAdvertisingCallback callback,
-            Handler handler) {
-        return new IPeriodicAdvertisingCallback.Stub() {
-            public void onSyncEstablished(int syncHandle, BluetoothDevice device,
-                    int advertisingSid, int skip, int timeout, int status) {
-                Attributable.setAttributionSource(device, mAttributionSource);
-                handler.post(new Runnable() {
-                    @Override
-                    public void run() {
-                        callback.onSyncEstablished(syncHandle, device, advertisingSid, skip,
-                                timeout,
-                                status);
-
-                        if (status != PeriodicAdvertisingCallback.SYNC_SUCCESS) {
-                            // App can still unregister the sync until notified it failed. Remove
-                            // callback
-                            // after app was notifed.
-                            mCallbackWrappers.remove(callback);
-                        }
-                    }
-                });
-            }
-
-            public void onPeriodicAdvertisingReport(PeriodicAdvertisingReport report) {
-                handler.post(new Runnable() {
-                    @Override
-                    public void run() {
-                        callback.onPeriodicAdvertisingReport(report);
-                    }
-                });
-            }
-
-            public void onSyncLost(int syncHandle) {
-                handler.post(new Runnable() {
-                    @Override
-                    public void run() {
-                        callback.onSyncLost(syncHandle);
-                        // App can still unregister the sync until notified it's lost.
-                        // Remove callback after app was notifed.
-                        mCallbackWrappers.remove(callback);
-                    }
-                });
-            }
-        };
-    }
-}
diff --git a/core/java/android/bluetooth/le/PeriodicAdvertisingParameters.java b/core/java/android/bluetooth/le/PeriodicAdvertisingParameters.java
deleted file mode 100644
index 4e64dbe..0000000
--- a/core/java/android/bluetooth/le/PeriodicAdvertisingParameters.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.le;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * The {@link PeriodicAdvertisingParameters} provide a way to adjust periodic
- * advertising preferences for each Bluetooth LE advertising set. Use {@link
- * PeriodicAdvertisingParameters.Builder} to create an instance of this class.
- */
-public final class PeriodicAdvertisingParameters implements Parcelable {
-
-    private static final int INTERVAL_MIN = 80;
-    private static final int INTERVAL_MAX = 65519;
-
-    private final boolean mIncludeTxPower;
-    private final int mInterval;
-
-    private PeriodicAdvertisingParameters(boolean includeTxPower, int interval) {
-        mIncludeTxPower = includeTxPower;
-        mInterval = interval;
-    }
-
-    private PeriodicAdvertisingParameters(Parcel in) {
-        mIncludeTxPower = in.readInt() != 0;
-        mInterval = in.readInt();
-    }
-
-    /**
-     * Returns whether the TX Power will be included.
-     */
-    public boolean getIncludeTxPower() {
-        return mIncludeTxPower;
-    }
-
-    /**
-     * Returns the periodic advertising interval, in 1.25ms unit.
-     * Valid values are from 80 (100ms) to 65519 (81.89875s).
-     */
-    public int getInterval() {
-        return mInterval;
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(mIncludeTxPower ? 1 : 0);
-        dest.writeInt(mInterval);
-    }
-
-    public static final Parcelable
-            .Creator<PeriodicAdvertisingParameters> CREATOR =
-            new Creator<PeriodicAdvertisingParameters>() {
-                @Override
-                public PeriodicAdvertisingParameters[] newArray(int size) {
-                    return new PeriodicAdvertisingParameters[size];
-                }
-
-                @Override
-                public PeriodicAdvertisingParameters createFromParcel(Parcel in) {
-                    return new PeriodicAdvertisingParameters(in);
-                }
-            };
-
-    public static final class Builder {
-        private boolean mIncludeTxPower = false;
-        private int mInterval = INTERVAL_MAX;
-
-        /**
-         * Whether the transmission power level should be included in the periodic
-         * packet.
-         */
-        public Builder setIncludeTxPower(boolean includeTxPower) {
-            mIncludeTxPower = includeTxPower;
-            return this;
-        }
-
-        /**
-         * Set advertising interval for periodic advertising, in 1.25ms unit.
-         * Valid values are from 80 (100ms) to 65519 (81.89875s).
-         * Value from range [interval, interval+20ms] will be picked as the actual value.
-         *
-         * @throws IllegalArgumentException If the interval is invalid.
-         */
-        public Builder setInterval(int interval) {
-            if (interval < INTERVAL_MIN || interval > INTERVAL_MAX) {
-                throw new IllegalArgumentException("Invalid interval (must be " + INTERVAL_MIN
-                        + "-" + INTERVAL_MAX + ")");
-            }
-            mInterval = interval;
-            return this;
-        }
-
-        /**
-         * Build the {@link AdvertisingSetParameters} object.
-         */
-        public PeriodicAdvertisingParameters build() {
-            return new PeriodicAdvertisingParameters(mIncludeTxPower, mInterval);
-        }
-    }
-}
diff --git a/core/java/android/bluetooth/le/PeriodicAdvertisingReport.java b/core/java/android/bluetooth/le/PeriodicAdvertisingReport.java
deleted file mode 100644
index 54b953c..0000000
--- a/core/java/android/bluetooth/le/PeriodicAdvertisingReport.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.le;
-
-import android.annotation.Nullable;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.Objects;
-
-/**
- * PeriodicAdvertisingReport for Bluetooth LE synchronized advertising.
- *
- * @hide
- */
-public final class PeriodicAdvertisingReport implements Parcelable {
-
-    /**
-     * The data returned is complete
-     */
-    public static final int DATA_COMPLETE = 0;
-
-    /**
-     * The data returned is incomplete. The controller was unsuccessfull to
-     * receive all chained packets, returning only partial data.
-     */
-    public static final int DATA_INCOMPLETE_TRUNCATED = 2;
-
-    private int mSyncHandle;
-    private int mTxPower;
-    private int mRssi;
-    private int mDataStatus;
-
-    // periodic advertising data.
-    @Nullable
-    private ScanRecord mData;
-
-    // Device timestamp when the result was last seen.
-    private long mTimestampNanos;
-
-    /**
-     * Constructor of periodic advertising result.
-     */
-    public PeriodicAdvertisingReport(int syncHandle, int txPower, int rssi,
-            int dataStatus, ScanRecord data) {
-        mSyncHandle = syncHandle;
-        mTxPower = txPower;
-        mRssi = rssi;
-        mDataStatus = dataStatus;
-        mData = data;
-    }
-
-    private PeriodicAdvertisingReport(Parcel in) {
-        readFromParcel(in);
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(mSyncHandle);
-        dest.writeInt(mTxPower);
-        dest.writeInt(mRssi);
-        dest.writeInt(mDataStatus);
-        if (mData != null) {
-            dest.writeInt(1);
-            dest.writeByteArray(mData.getBytes());
-        } else {
-            dest.writeInt(0);
-        }
-    }
-
-    private void readFromParcel(Parcel in) {
-        mSyncHandle = in.readInt();
-        mTxPower = in.readInt();
-        mRssi = in.readInt();
-        mDataStatus = in.readInt();
-        if (in.readInt() == 1) {
-            mData = ScanRecord.parseFromBytes(in.createByteArray());
-        }
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    /**
-     * Returns the synchronization handle.
-     */
-    public int getSyncHandle() {
-        return mSyncHandle;
-    }
-
-    /**
-     * Returns the transmit power in dBm. The valid range is [-127, 126]. Value
-     * of 127 means information was not available.
-     */
-    public int getTxPower() {
-        return mTxPower;
-    }
-
-    /**
-     * Returns the received signal strength in dBm. The valid range is [-127, 20].
-     */
-    public int getRssi() {
-        return mRssi;
-    }
-
-    /**
-     * Returns the data status. Can be one of {@link PeriodicAdvertisingReport#DATA_COMPLETE}
-     * or {@link PeriodicAdvertisingReport#DATA_INCOMPLETE_TRUNCATED}.
-     */
-    public int getDataStatus() {
-        return mDataStatus;
-    }
-
-    /**
-     * Returns the data contained in this periodic advertising report.
-     */
-    @Nullable
-    public ScanRecord getData() {
-        return mData;
-    }
-
-    /**
-     * Returns timestamp since boot when the scan record was observed.
-     */
-    public long getTimestampNanos() {
-        return mTimestampNanos;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(mSyncHandle, mTxPower, mRssi, mDataStatus, mData, mTimestampNanos);
-    }
-
-    @Override
-    public boolean equals(@Nullable Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj == null || getClass() != obj.getClass()) {
-            return false;
-        }
-        PeriodicAdvertisingReport other = (PeriodicAdvertisingReport) obj;
-        return (mSyncHandle == other.mSyncHandle)
-                && (mTxPower == other.mTxPower)
-                && (mRssi == other.mRssi)
-                && (mDataStatus == other.mDataStatus)
-                && Objects.equals(mData, other.mData)
-                && (mTimestampNanos == other.mTimestampNanos);
-    }
-
-    @Override
-    public String toString() {
-        return "PeriodicAdvertisingReport{syncHandle=" + mSyncHandle
-                + ", txPower=" + mTxPower + ", rssi=" + mRssi + ", dataStatus=" + mDataStatus
-                + ", data=" + Objects.toString(mData) + ", timestampNanos=" + mTimestampNanos + '}';
-    }
-
-    public static final @android.annotation.NonNull Parcelable.Creator<PeriodicAdvertisingReport> CREATOR =
-            new Creator<PeriodicAdvertisingReport>() {
-                @Override
-                public PeriodicAdvertisingReport createFromParcel(Parcel source) {
-                    return new PeriodicAdvertisingReport(source);
-                }
-
-                @Override
-                public PeriodicAdvertisingReport[] newArray(int size) {
-                    return new PeriodicAdvertisingReport[size];
-                }
-            };
-}
diff --git a/core/java/android/bluetooth/le/ResultStorageDescriptor.java b/core/java/android/bluetooth/le/ResultStorageDescriptor.java
deleted file mode 100644
index f650489..0000000
--- a/core/java/android/bluetooth/le/ResultStorageDescriptor.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.le;
-
-import android.annotation.SystemApi;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Describes the way to store scan result.
- *
- * @deprecated this is not used anywhere
- *
- * @hide
- */
-@Deprecated
-@SystemApi
-public final class ResultStorageDescriptor implements Parcelable {
-    private int mType;
-    private int mOffset;
-    private int mLength;
-
-    public int getType() {
-        return mType;
-    }
-
-    public int getOffset() {
-        return mOffset;
-    }
-
-    public int getLength() {
-        return mLength;
-    }
-
-    /**
-     * Constructor of {@link ResultStorageDescriptor}
-     *
-     * @param type Type of the data.
-     * @param offset Offset from start of the advertise packet payload.
-     * @param length Byte length of the data
-     */
-    public ResultStorageDescriptor(int type, int offset, int length) {
-        mType = type;
-        mOffset = offset;
-        mLength = length;
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(mType);
-        dest.writeInt(mOffset);
-        dest.writeInt(mLength);
-    }
-
-    private ResultStorageDescriptor(Parcel in) {
-        ReadFromParcel(in);
-    }
-
-    private void ReadFromParcel(Parcel in) {
-        mType = in.readInt();
-        mOffset = in.readInt();
-        mLength = in.readInt();
-    }
-
-    public static final @android.annotation.NonNull Parcelable.Creator<ResultStorageDescriptor> CREATOR =
-            new Creator<ResultStorageDescriptor>() {
-        @Override
-        public ResultStorageDescriptor createFromParcel(Parcel source) {
-            return new ResultStorageDescriptor(source);
-        }
-
-        @Override
-        public ResultStorageDescriptor[] newArray(int size) {
-            return new ResultStorageDescriptor[size];
-        }
-    };
-}
diff --git a/core/java/android/bluetooth/le/ScanCallback.java b/core/java/android/bluetooth/le/ScanCallback.java
deleted file mode 100644
index 53d9310..0000000
--- a/core/java/android/bluetooth/le/ScanCallback.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.le;
-
-import java.util.List;
-
-/**
- * Bluetooth LE scan callbacks. Scan results are reported using these callbacks.
- *
- * @see BluetoothLeScanner#startScan
- */
-public abstract class ScanCallback {
-    /**
-     * Fails to start scan as BLE scan with the same settings is already started by the app.
-     */
-    public static final int SCAN_FAILED_ALREADY_STARTED = 1;
-
-    /**
-     * Fails to start scan as app cannot be registered.
-     */
-    public static final int SCAN_FAILED_APPLICATION_REGISTRATION_FAILED = 2;
-
-    /**
-     * Fails to start scan due an internal error
-     */
-    public static final int SCAN_FAILED_INTERNAL_ERROR = 3;
-
-    /**
-     * Fails to start power optimized scan as this feature is not supported.
-     */
-    public static final int SCAN_FAILED_FEATURE_UNSUPPORTED = 4;
-
-    /**
-     * Fails to start scan as it is out of hardware resources.
-     *
-     * @hide
-     */
-    public static final int SCAN_FAILED_OUT_OF_HARDWARE_RESOURCES = 5;
-
-    /**
-     * Fails to start scan as application tries to scan too frequently.
-     * @hide
-     */
-    public static final int SCAN_FAILED_SCANNING_TOO_FREQUENTLY = 6;
-
-    static final int NO_ERROR = 0;
-
-    /**
-     * Callback when a BLE advertisement has been found.
-     *
-     * @param callbackType Determines how this callback was triggered. Could be one of {@link
-     * ScanSettings#CALLBACK_TYPE_ALL_MATCHES}, {@link ScanSettings#CALLBACK_TYPE_FIRST_MATCH} or
-     * {@link ScanSettings#CALLBACK_TYPE_MATCH_LOST}
-     * @param result A Bluetooth LE scan result.
-     */
-    public void onScanResult(int callbackType, ScanResult result) {
-    }
-
-    /**
-     * Callback when batch results are delivered.
-     *
-     * @param results List of scan results that are previously scanned.
-     */
-    public void onBatchScanResults(List<ScanResult> results) {
-    }
-
-    /**
-     * Callback when scan could not be started.
-     *
-     * @param errorCode Error code (one of SCAN_FAILED_*) for scan failure.
-     */
-    public void onScanFailed(int errorCode) {
-    }
-}
diff --git a/core/java/android/bluetooth/le/ScanFilter.java b/core/java/android/bluetooth/le/ScanFilter.java
deleted file mode 100644
index b059193..0000000
--- a/core/java/android/bluetooth/le/ScanFilter.java
+++ /dev/null
@@ -1,910 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.le;
-
-import static java.util.Objects.requireNonNull;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothDevice.AddressType;
-import android.os.Parcel;
-import android.os.ParcelUuid;
-import android.os.Parcelable;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.Objects;
-import java.util.UUID;
-
-/**
- * Criteria for filtering result from Bluetooth LE scans. A {@link ScanFilter} allows clients to
- * restrict scan results to only those that are of interest to them.
- * <p>
- * Current filtering on the following fields are supported:
- * <li>Service UUIDs which identify the bluetooth gatt services running on the device.
- * <li>Name of remote Bluetooth LE device.
- * <li>Mac address of the remote device.
- * <li>Service data which is the data associated with a service.
- * <li>Manufacturer specific data which is the data associated with a particular manufacturer.
- *
- * @see ScanResult
- * @see BluetoothLeScanner
- */
-public final class ScanFilter implements Parcelable {
-
-    @Nullable
-    private final String mDeviceName;
-
-    @Nullable
-    private final String mDeviceAddress;
-
-    private final @AddressType int mAddressType;
-
-    @Nullable
-    private final byte[] mIrk;
-
-    @Nullable
-    private final ParcelUuid mServiceUuid;
-    @Nullable
-    private final ParcelUuid mServiceUuidMask;
-
-    @Nullable
-    private final ParcelUuid mServiceSolicitationUuid;
-    @Nullable
-    private final ParcelUuid mServiceSolicitationUuidMask;
-
-    @Nullable
-    private final ParcelUuid mServiceDataUuid;
-    @Nullable
-    private final byte[] mServiceData;
-    @Nullable
-    private final byte[] mServiceDataMask;
-
-    private final int mManufacturerId;
-    @Nullable
-    private final byte[] mManufacturerData;
-    @Nullable
-    private final byte[] mManufacturerDataMask;
-
-    /** @hide */
-    public static final ScanFilter EMPTY = new ScanFilter.Builder().build();
-
-    private ScanFilter(String name, String deviceAddress, ParcelUuid uuid,
-            ParcelUuid uuidMask, ParcelUuid solicitationUuid,
-            ParcelUuid solicitationUuidMask, ParcelUuid serviceDataUuid,
-            byte[] serviceData, byte[] serviceDataMask,
-            int manufacturerId, byte[] manufacturerData, byte[] manufacturerDataMask,
-            @AddressType int addressType, @Nullable byte[] irk) {
-        mDeviceName = name;
-        mServiceUuid = uuid;
-        mServiceUuidMask = uuidMask;
-        mServiceSolicitationUuid = solicitationUuid;
-        mServiceSolicitationUuidMask = solicitationUuidMask;
-        mDeviceAddress = deviceAddress;
-        mServiceDataUuid = serviceDataUuid;
-        mServiceData = serviceData;
-        mServiceDataMask = serviceDataMask;
-        mManufacturerId = manufacturerId;
-        mManufacturerData = manufacturerData;
-        mManufacturerDataMask = manufacturerDataMask;
-        mAddressType = addressType;
-        mIrk = irk;
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(mDeviceName == null ? 0 : 1);
-        if (mDeviceName != null) {
-            dest.writeString(mDeviceName);
-        }
-        dest.writeInt(mDeviceAddress == null ? 0 : 1);
-        if (mDeviceAddress != null) {
-            dest.writeString(mDeviceAddress);
-        }
-        dest.writeInt(mServiceUuid == null ? 0 : 1);
-        if (mServiceUuid != null) {
-            dest.writeParcelable(mServiceUuid, flags);
-            dest.writeInt(mServiceUuidMask == null ? 0 : 1);
-            if (mServiceUuidMask != null) {
-                dest.writeParcelable(mServiceUuidMask, flags);
-            }
-        }
-        dest.writeInt(mServiceSolicitationUuid == null ? 0 : 1);
-        if (mServiceSolicitationUuid != null) {
-            dest.writeParcelable(mServiceSolicitationUuid, flags);
-            dest.writeInt(mServiceSolicitationUuidMask == null ? 0 : 1);
-            if (mServiceSolicitationUuidMask != null) {
-                dest.writeParcelable(mServiceSolicitationUuidMask, flags);
-            }
-        }
-        dest.writeInt(mServiceDataUuid == null ? 0 : 1);
-        if (mServiceDataUuid != null) {
-            dest.writeParcelable(mServiceDataUuid, flags);
-            dest.writeInt(mServiceData == null ? 0 : 1);
-            if (mServiceData != null) {
-                dest.writeInt(mServiceData.length);
-                dest.writeByteArray(mServiceData);
-
-                dest.writeInt(mServiceDataMask == null ? 0 : 1);
-                if (mServiceDataMask != null) {
-                    dest.writeInt(mServiceDataMask.length);
-                    dest.writeByteArray(mServiceDataMask);
-                }
-            }
-        }
-        dest.writeInt(mManufacturerId);
-        dest.writeInt(mManufacturerData == null ? 0 : 1);
-        if (mManufacturerData != null) {
-            dest.writeInt(mManufacturerData.length);
-            dest.writeByteArray(mManufacturerData);
-
-            dest.writeInt(mManufacturerDataMask == null ? 0 : 1);
-            if (mManufacturerDataMask != null) {
-                dest.writeInt(mManufacturerDataMask.length);
-                dest.writeByteArray(mManufacturerDataMask);
-            }
-        }
-
-        // IRK
-        if (mDeviceAddress != null) {
-            dest.writeInt(mAddressType);
-            dest.writeInt(mIrk == null ? 0 : 1);
-            if (mIrk != null) {
-                dest.writeByteArray(mIrk);
-            }
-        }
-    }
-
-    /**
-     * A {@link android.os.Parcelable.Creator} to create {@link ScanFilter} from parcel.
-     */
-    public static final @android.annotation.NonNull Creator<ScanFilter> CREATOR =
-            new Creator<ScanFilter>() {
-
-        @Override
-        public ScanFilter[] newArray(int size) {
-            return new ScanFilter[size];
-        }
-
-        @Override
-        public ScanFilter createFromParcel(Parcel in) {
-            Builder builder = new Builder();
-            if (in.readInt() == 1) {
-                builder.setDeviceName(in.readString());
-            }
-            String address = null;
-            // If we have a non-null address
-            if (in.readInt() == 1) {
-                address = in.readString();
-            }
-            if (in.readInt() == 1) {
-                ParcelUuid uuid = in.readParcelable(ParcelUuid.class.getClassLoader());
-                builder.setServiceUuid(uuid);
-                if (in.readInt() == 1) {
-                    ParcelUuid uuidMask = in.readParcelable(
-                            ParcelUuid.class.getClassLoader());
-                    builder.setServiceUuid(uuid, uuidMask);
-                }
-            }
-            if (in.readInt() == 1) {
-                ParcelUuid solicitationUuid = in.readParcelable(
-                        ParcelUuid.class.getClassLoader());
-                builder.setServiceSolicitationUuid(solicitationUuid);
-                if (in.readInt() == 1) {
-                    ParcelUuid solicitationUuidMask = in.readParcelable(
-                            ParcelUuid.class.getClassLoader());
-                    builder.setServiceSolicitationUuid(solicitationUuid,
-                            solicitationUuidMask);
-                }
-            }
-            if (in.readInt() == 1) {
-                ParcelUuid servcieDataUuid =
-                        in.readParcelable(ParcelUuid.class.getClassLoader());
-                if (in.readInt() == 1) {
-                    int serviceDataLength = in.readInt();
-                    byte[] serviceData = new byte[serviceDataLength];
-                    in.readByteArray(serviceData);
-                    if (in.readInt() == 0) {
-                        builder.setServiceData(servcieDataUuid, serviceData);
-                    } else {
-                        int serviceDataMaskLength = in.readInt();
-                        byte[] serviceDataMask = new byte[serviceDataMaskLength];
-                        in.readByteArray(serviceDataMask);
-                        builder.setServiceData(
-                                servcieDataUuid, serviceData, serviceDataMask);
-                    }
-                }
-            }
-
-            int manufacturerId = in.readInt();
-            if (in.readInt() == 1) {
-                int manufacturerDataLength = in.readInt();
-                byte[] manufacturerData = new byte[manufacturerDataLength];
-                in.readByteArray(manufacturerData);
-                if (in.readInt() == 0) {
-                    builder.setManufacturerData(manufacturerId, manufacturerData);
-                } else {
-                    int manufacturerDataMaskLength = in.readInt();
-                    byte[] manufacturerDataMask = new byte[manufacturerDataMaskLength];
-                    in.readByteArray(manufacturerDataMask);
-                    builder.setManufacturerData(manufacturerId, manufacturerData,
-                            manufacturerDataMask);
-                }
-            }
-
-            // IRK
-            if (address != null) {
-                final int addressType = in.readInt();
-                if (in.readInt() == 1) {
-                    final byte[] irk = new byte[16];
-                    in.readByteArray(irk);
-                    builder.setDeviceAddress(address, addressType, irk);
-                } else {
-                    builder.setDeviceAddress(address, addressType);
-                }
-            }
-            return builder.build();
-        }
-    };
-
-    /**
-     * Returns the filter set the device name field of Bluetooth advertisement data.
-     */
-    @Nullable
-    public String getDeviceName() {
-        return mDeviceName;
-    }
-
-    /**
-     * Returns the filter set on the service uuid.
-     */
-    @Nullable
-    public ParcelUuid getServiceUuid() {
-        return mServiceUuid;
-    }
-
-    @Nullable
-    public ParcelUuid getServiceUuidMask() {
-        return mServiceUuidMask;
-    }
-
-    /**
-     * Returns the filter set on the service Solicitation uuid.
-     */
-    @Nullable
-    public ParcelUuid getServiceSolicitationUuid() {
-        return mServiceSolicitationUuid;
-    }
-
-    /**
-     * Returns the filter set on the service Solicitation uuid mask.
-     */
-    @Nullable
-    public ParcelUuid getServiceSolicitationUuidMask() {
-        return mServiceSolicitationUuidMask;
-    }
-
-    @Nullable
-    public String getDeviceAddress() {
-        return mDeviceAddress;
-    }
-
-    /**
-     * @hide
-     */
-    @SystemApi
-    public @AddressType int getAddressType() {
-        return mAddressType;
-    }
-
-    /**
-     * @hide
-     */
-    @SystemApi
-    @Nullable
-    public byte[] getIrk() {
-        return mIrk;
-    }
-
-    @Nullable
-    public byte[] getServiceData() {
-        return mServiceData;
-    }
-
-    @Nullable
-    public byte[] getServiceDataMask() {
-        return mServiceDataMask;
-    }
-
-    @Nullable
-    public ParcelUuid getServiceDataUuid() {
-        return mServiceDataUuid;
-    }
-
-    /**
-     * Returns the manufacturer id. -1 if the manufacturer filter is not set.
-     */
-    public int getManufacturerId() {
-        return mManufacturerId;
-    }
-
-    @Nullable
-    public byte[] getManufacturerData() {
-        return mManufacturerData;
-    }
-
-    @Nullable
-    public byte[] getManufacturerDataMask() {
-        return mManufacturerDataMask;
-    }
-
-    /**
-     * Check if the scan filter matches a {@code scanResult}. A scan result is considered as a match
-     * if it matches all the field filters.
-     */
-    public boolean matches(ScanResult scanResult) {
-        if (scanResult == null) {
-            return false;
-        }
-        BluetoothDevice device = scanResult.getDevice();
-        // Device match.
-        if (mDeviceAddress != null
-                && (device == null || !mDeviceAddress.equals(device.getAddress()))) {
-            return false;
-        }
-
-        ScanRecord scanRecord = scanResult.getScanRecord();
-
-        // Scan record is null but there exist filters on it.
-        if (scanRecord == null
-                && (mDeviceName != null || mServiceUuid != null || mManufacturerData != null
-                || mServiceData != null || mServiceSolicitationUuid != null)) {
-            return false;
-        }
-
-        // Local name match.
-        if (mDeviceName != null && !mDeviceName.equals(scanRecord.getDeviceName())) {
-            return false;
-        }
-
-        // UUID match.
-        if (mServiceUuid != null && !matchesServiceUuids(mServiceUuid, mServiceUuidMask,
-                scanRecord.getServiceUuids())) {
-            return false;
-        }
-
-        // solicitation UUID match.
-        if (mServiceSolicitationUuid != null && !matchesServiceSolicitationUuids(
-                mServiceSolicitationUuid, mServiceSolicitationUuidMask,
-                scanRecord.getServiceSolicitationUuids())) {
-            return false;
-        }
-
-        // Service data match
-        if (mServiceDataUuid != null) {
-            if (!matchesPartialData(mServiceData, mServiceDataMask,
-                    scanRecord.getServiceData(mServiceDataUuid))) {
-                return false;
-            }
-        }
-
-        // Manufacturer data match.
-        if (mManufacturerId >= 0) {
-            if (!matchesPartialData(mManufacturerData, mManufacturerDataMask,
-                    scanRecord.getManufacturerSpecificData(mManufacturerId))) {
-                return false;
-            }
-        }
-        // All filters match.
-        return true;
-    }
-
-    /**
-     * Check if the uuid pattern is contained in a list of parcel uuids.
-     *
-     * @hide
-     */
-    public static boolean matchesServiceUuids(ParcelUuid uuid, ParcelUuid parcelUuidMask,
-            List<ParcelUuid> uuids) {
-        if (uuid == null) {
-            return true;
-        }
-        if (uuids == null) {
-            return false;
-        }
-
-        for (ParcelUuid parcelUuid : uuids) {
-            UUID uuidMask = parcelUuidMask == null ? null : parcelUuidMask.getUuid();
-            if (matchesServiceUuid(uuid.getUuid(), uuidMask, parcelUuid.getUuid())) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    // Check if the uuid pattern matches the particular service uuid.
-    private static boolean matchesServiceUuid(UUID uuid, UUID mask, UUID data) {
-        return BluetoothLeUtils.maskedEquals(data, uuid, mask);
-    }
-
-    /**
-     * Check if the solicitation uuid pattern is contained in a list of parcel uuids.
-     *
-     */
-    private static boolean matchesServiceSolicitationUuids(ParcelUuid solicitationUuid,
-            ParcelUuid parcelSolicitationUuidMask, List<ParcelUuid> solicitationUuids) {
-        if (solicitationUuid == null) {
-            return true;
-        }
-        if (solicitationUuids == null) {
-            return false;
-        }
-
-        for (ParcelUuid parcelSolicitationUuid : solicitationUuids) {
-            UUID solicitationUuidMask = parcelSolicitationUuidMask == null
-                    ? null : parcelSolicitationUuidMask.getUuid();
-            if (matchesServiceUuid(solicitationUuid.getUuid(), solicitationUuidMask,
-                    parcelSolicitationUuid.getUuid())) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    // Check if the solicitation uuid pattern matches the particular service solicitation uuid.
-    private static boolean matchesServiceSolicitationUuid(UUID solicitationUuid,
-            UUID solicitationUuidMask, UUID data) {
-        return BluetoothLeUtils.maskedEquals(data, solicitationUuid, solicitationUuidMask);
-    }
-
-    // Check whether the data pattern matches the parsed data.
-    private boolean matchesPartialData(byte[] data, byte[] dataMask, byte[] parsedData) {
-        if (parsedData == null || parsedData.length < data.length) {
-            return false;
-        }
-        if (dataMask == null) {
-            for (int i = 0; i < data.length; ++i) {
-                if (parsedData[i] != data[i]) {
-                    return false;
-                }
-            }
-            return true;
-        }
-        for (int i = 0; i < data.length; ++i) {
-            if ((dataMask[i] & parsedData[i]) != (dataMask[i] & data[i])) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    @Override
-    public String toString() {
-        return "BluetoothLeScanFilter [mDeviceName=" + mDeviceName + ", mDeviceAddress="
-                + mDeviceAddress
-                + ", mUuid=" + mServiceUuid + ", mUuidMask=" + mServiceUuidMask
-                + ", mServiceSolicitationUuid=" + mServiceSolicitationUuid
-                + ", mServiceSolicitationUuidMask=" + mServiceSolicitationUuidMask
-                + ", mServiceDataUuid=" + Objects.toString(mServiceDataUuid) + ", mServiceData="
-                + Arrays.toString(mServiceData) + ", mServiceDataMask="
-                + Arrays.toString(mServiceDataMask) + ", mManufacturerId=" + mManufacturerId
-                + ", mManufacturerData=" + Arrays.toString(mManufacturerData)
-                + ", mManufacturerDataMask=" + Arrays.toString(mManufacturerDataMask) + "]";
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(mDeviceName, mDeviceAddress, mManufacturerId,
-                Arrays.hashCode(mManufacturerData),
-                Arrays.hashCode(mManufacturerDataMask),
-                mServiceDataUuid,
-                Arrays.hashCode(mServiceData),
-                Arrays.hashCode(mServiceDataMask),
-                mServiceUuid, mServiceUuidMask,
-                mServiceSolicitationUuid, mServiceSolicitationUuidMask);
-    }
-
-    @Override
-    public boolean equals(@Nullable Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj == null || getClass() != obj.getClass()) {
-            return false;
-        }
-        ScanFilter other = (ScanFilter) obj;
-        return Objects.equals(mDeviceName, other.mDeviceName)
-                && Objects.equals(mDeviceAddress, other.mDeviceAddress)
-                && mManufacturerId == other.mManufacturerId
-                && Objects.deepEquals(mManufacturerData, other.mManufacturerData)
-                && Objects.deepEquals(mManufacturerDataMask, other.mManufacturerDataMask)
-                && Objects.equals(mServiceDataUuid, other.mServiceDataUuid)
-                && Objects.deepEquals(mServiceData, other.mServiceData)
-                && Objects.deepEquals(mServiceDataMask, other.mServiceDataMask)
-                && Objects.equals(mServiceUuid, other.mServiceUuid)
-                && Objects.equals(mServiceUuidMask, other.mServiceUuidMask)
-                && Objects.equals(mServiceSolicitationUuid, other.mServiceSolicitationUuid)
-                && Objects.equals(mServiceSolicitationUuidMask,
-                        other.mServiceSolicitationUuidMask);
-    }
-
-    /**
-     * Checks if the scanfilter is empty
-     *
-     * @hide
-     */
-    public boolean isAllFieldsEmpty() {
-        return EMPTY.equals(this);
-    }
-
-    /**
-     * Builder class for {@link ScanFilter}.
-     */
-    public static final class Builder {
-
-        /**
-         * @hide
-         */
-        @SystemApi
-        public static final int LEN_IRK_OCTETS = 16;
-
-        private String mDeviceName;
-        private String mDeviceAddress;
-        private @AddressType int mAddressType = BluetoothDevice.ADDRESS_TYPE_PUBLIC;
-        private byte[] mIrk;
-
-        private ParcelUuid mServiceUuid;
-        private ParcelUuid mUuidMask;
-
-        private ParcelUuid mServiceSolicitationUuid;
-        private ParcelUuid mServiceSolicitationUuidMask;
-
-        private ParcelUuid mServiceDataUuid;
-        private byte[] mServiceData;
-        private byte[] mServiceDataMask;
-
-        private int mManufacturerId = -1;
-        private byte[] mManufacturerData;
-        private byte[] mManufacturerDataMask;
-
-        /**
-         * Set filter on device name.
-         */
-        public Builder setDeviceName(String deviceName) {
-            mDeviceName = deviceName;
-            return this;
-        }
-
-        /**
-         * Set filter on device address.
-         *
-         * @param deviceAddress The device Bluetooth address for the filter. It needs to be in the
-         * format of "01:02:03:AB:CD:EF". The device address can be validated using {@link
-         * BluetoothAdapter#checkBluetoothAddress}.  The @AddressType is defaulted to {@link
-         * BluetoothDevice#ADDRESS_TYPE_PUBLIC}
-         * @throws IllegalArgumentException If the {@code deviceAddress} is invalid.
-         */
-        public Builder setDeviceAddress(String deviceAddress) {
-            if (deviceAddress == null) {
-                mDeviceAddress = deviceAddress;
-                return this;
-            }
-            return setDeviceAddress(deviceAddress, BluetoothDevice.ADDRESS_TYPE_PUBLIC);
-        }
-
-        /**
-         * Set filter on Address with AddressType
-         *
-         * <p>This key is used to resolve a private address from a public address.
-         *
-         * @param deviceAddress The device Bluetooth address for the filter. It needs to be in the
-         * format of "01:02:03:AB:CD:EF". The device address can be validated using {@link
-         * BluetoothAdapter#checkBluetoothAddress}. May be any type of address.
-         * @param addressType indication of the type of address
-         * e.g. {@link BluetoothDevice#ADDRESS_TYPE_PUBLIC}
-         * or {@link BluetoothDevice#ADDRESS_TYPE_RANDOM}
-         *
-         * @throws IllegalArgumentException If the {@code deviceAddress} is invalid.
-         * @throws IllegalArgumentException If the {@code addressType} is invalid length
-         * @throws NullPointerException if {@code deviceAddress} is null.
-         *
-         * @hide
-         */
-        @NonNull
-        @SystemApi
-        public Builder setDeviceAddress(@NonNull String deviceAddress,
-                                        @AddressType int addressType) {
-            return setDeviceAddressInternal(deviceAddress, addressType, null);
-        }
-
-        /**
-         * Set filter on Address with AddressType and the Identity Resolving Key (IRK).
-         *
-         * <p>The IRK is used to resolve a {@link BluetoothDevice#ADDRESS_TYPE_PUBLIC} from
-         * a PRIVATE_ADDRESS type.
-         *
-         * @param deviceAddress The device Bluetooth address for the filter. It needs to be in the
-         * format of "01:02:03:AB:CD:EF". The device address can be validated using {@link
-         * BluetoothAdapter#checkBluetoothAddress}.  This Address type must only be PUBLIC OR RANDOM
-         * STATIC.
-         * @param addressType indication of the type of address
-         * e.g. {@link BluetoothDevice#ADDRESS_TYPE_PUBLIC}
-         * or {@link BluetoothDevice#ADDRESS_TYPE_RANDOM}
-         * @param irk non-null byte array representing the Identity Resolving Key
-         *
-         * @throws IllegalArgumentException If the {@code deviceAddress} is invalid.
-         * @throws IllegalArgumentException if the {@code irk} is invalid length.
-         * @throws IllegalArgumentException If the {@code addressType} is invalid length or is not
-         * PUBLIC or RANDOM STATIC when an IRK is present.
-         * @throws NullPointerException if {@code deviceAddress} or {@code irk} is null.
-         *
-         * @hide
-         */
-        @NonNull
-        @SystemApi
-        public Builder setDeviceAddress(@NonNull String deviceAddress,
-                                        @AddressType int addressType,
-                                        @NonNull byte[] irk) {
-            requireNonNull(irk);
-            if (irk.length != LEN_IRK_OCTETS) {
-                throw new IllegalArgumentException("'irk' is invalid length!");
-            }
-            return setDeviceAddressInternal(deviceAddress, addressType, irk);
-        }
-
-        /**
-         * Set filter on Address with AddressType and the Identity Resolving Key (IRK).
-         *
-         * <p>Internal setter for the device address
-         *
-         * @param deviceAddress The device Bluetooth address for the filter. It needs to be in the
-         * format of "01:02:03:AB:CD:EF". The device address can be validated using {@link
-         * BluetoothAdapter#checkBluetoothAddress}.
-         * @param addressType indication of the type of address
-         * e.g. {@link BluetoothDevice#ADDRESS_TYPE_PUBLIC}
-         * @param irk non-null byte array representing the Identity Resolving Address; nullable
-         * internally.
-         *
-         * @throws IllegalArgumentException If the {@code deviceAddress} is invalid.
-         * @throws IllegalArgumentException If the {@code addressType} is invalid length.
-         * @throws NullPointerException if {@code deviceAddress} is null.
-         *
-         * @hide
-         */
-        @NonNull
-        private Builder setDeviceAddressInternal(@NonNull String deviceAddress,
-                                                 @AddressType int addressType,
-                                                 @Nullable byte[] irk) {
-
-            // Make sure our deviceAddress is valid!
-            requireNonNull(deviceAddress);
-            if (!BluetoothAdapter.checkBluetoothAddress(deviceAddress)) {
-                throw new IllegalArgumentException("invalid device address " + deviceAddress);
-            }
-
-            // Verify type range
-            if (addressType < BluetoothDevice.ADDRESS_TYPE_PUBLIC
-                || addressType > BluetoothDevice.ADDRESS_TYPE_RANDOM) {
-                throw new IllegalArgumentException("'addressType' is invalid!");
-            }
-
-            // IRK can only be used for a PUBLIC or RANDOM (STATIC) Address.
-            if (addressType == BluetoothDevice.ADDRESS_TYPE_RANDOM) {
-                // Don't want a bad combination of address and irk!
-                if (irk != null) {
-                    // Since there are 3 possible RANDOM subtypes we must check to make sure
-                    // the correct type of address is used.
-                    if (!BluetoothAdapter.isAddressRandomStatic(deviceAddress)) {
-                        throw new IllegalArgumentException(
-                                "Invalid combination: IRK requires either a PUBLIC or "
-                                + "RANDOM (STATIC) Address");
-                    }
-                }
-            }
-
-            // PUBLIC doesn't require extra work
-            // Without an IRK any address may be accepted
-
-            mDeviceAddress = deviceAddress;
-            mAddressType = addressType;
-            mIrk = irk;
-            return this;
-        }
-
-        /**
-         * Set filter on service uuid.
-         */
-        public Builder setServiceUuid(ParcelUuid serviceUuid) {
-            mServiceUuid = serviceUuid;
-            mUuidMask = null; // clear uuid mask
-            return this;
-        }
-
-        /**
-         * Set filter on partial service uuid. The {@code uuidMask} is the bit mask for the
-         * {@code serviceUuid}. Set any bit in the mask to 1 to indicate a match is needed for the
-         * bit in {@code serviceUuid}, and 0 to ignore that bit.
-         *
-         * @throws IllegalArgumentException If {@code serviceUuid} is {@code null} but {@code
-         * uuidMask} is not {@code null}.
-         */
-        public Builder setServiceUuid(ParcelUuid serviceUuid, ParcelUuid uuidMask) {
-            if (mUuidMask != null && mServiceUuid == null) {
-                throw new IllegalArgumentException("uuid is null while uuidMask is not null!");
-            }
-            mServiceUuid = serviceUuid;
-            mUuidMask = uuidMask;
-            return this;
-        }
-
-
-        /**
-         * Set filter on service solicitation uuid.
-         */
-        public @NonNull Builder setServiceSolicitationUuid(
-                @Nullable ParcelUuid serviceSolicitationUuid) {
-            mServiceSolicitationUuid = serviceSolicitationUuid;
-            if (serviceSolicitationUuid == null) {
-                mServiceSolicitationUuidMask = null;
-            }
-            return this;
-        }
-
-
-        /**
-         * Set filter on partial service Solicitation uuid. The {@code SolicitationUuidMask} is the
-         * bit mask for the {@code serviceSolicitationUuid}. Set any bit in the mask to 1 to
-         * indicate a match is needed for the bit in {@code serviceSolicitationUuid}, and 0 to
-         * ignore that bit.
-         *
-         * @param serviceSolicitationUuid can only be null if solicitationUuidMask is null.
-         * @param solicitationUuidMask can be null or a mask with no restriction.
-         *
-         * @throws IllegalArgumentException If {@code serviceSolicitationUuid} is {@code null} but
-         *             {@code serviceSolicitationUuidMask} is not {@code null}.
-         */
-        public @NonNull Builder setServiceSolicitationUuid(
-                @Nullable ParcelUuid serviceSolicitationUuid,
-                @Nullable ParcelUuid solicitationUuidMask) {
-            if (solicitationUuidMask != null && serviceSolicitationUuid == null) {
-                throw new IllegalArgumentException(
-                        "SolicitationUuid is null while SolicitationUuidMask is not null!");
-            }
-            mServiceSolicitationUuid = serviceSolicitationUuid;
-            mServiceSolicitationUuidMask = solicitationUuidMask;
-            return this;
-        }
-
-        /**
-         * Set filtering on service data.
-         *
-         * @throws IllegalArgumentException If {@code serviceDataUuid} is null.
-         */
-        public Builder setServiceData(ParcelUuid serviceDataUuid, byte[] serviceData) {
-            if (serviceDataUuid == null) {
-                throw new IllegalArgumentException("serviceDataUuid is null");
-            }
-            mServiceDataUuid = serviceDataUuid;
-            mServiceData = serviceData;
-            mServiceDataMask = null; // clear service data mask
-            return this;
-        }
-
-        /**
-         * Set partial filter on service data. For any bit in the mask, set it to 1 if it needs to
-         * match the one in service data, otherwise set it to 0 to ignore that bit.
-         * <p>
-         * The {@code serviceDataMask} must have the same length of the {@code serviceData}.
-         *
-         * @throws IllegalArgumentException If {@code serviceDataUuid} is null or {@code
-         * serviceDataMask} is {@code null} while {@code serviceData} is not or {@code
-         * serviceDataMask} and {@code serviceData} has different length.
-         */
-        public Builder setServiceData(ParcelUuid serviceDataUuid,
-                byte[] serviceData, byte[] serviceDataMask) {
-            if (serviceDataUuid == null) {
-                throw new IllegalArgumentException("serviceDataUuid is null");
-            }
-            if (mServiceDataMask != null) {
-                if (mServiceData == null) {
-                    throw new IllegalArgumentException(
-                            "serviceData is null while serviceDataMask is not null");
-                }
-                // Since the mServiceDataMask is a bit mask for mServiceData, the lengths of the two
-                // byte array need to be the same.
-                if (mServiceData.length != mServiceDataMask.length) {
-                    throw new IllegalArgumentException(
-                            "size mismatch for service data and service data mask");
-                }
-            }
-            mServiceDataUuid = serviceDataUuid;
-            mServiceData = serviceData;
-            mServiceDataMask = serviceDataMask;
-            return this;
-        }
-
-        /**
-         * Set filter on on manufacturerData. A negative manufacturerId is considered as invalid id.
-         *
-         * @throws IllegalArgumentException If the {@code manufacturerId} is invalid.
-         */
-        public Builder setManufacturerData(int manufacturerId, byte[] manufacturerData) {
-            if (manufacturerData != null && manufacturerId < 0) {
-                throw new IllegalArgumentException("invalid manufacture id");
-            }
-            mManufacturerId = manufacturerId;
-            mManufacturerData = manufacturerData;
-            mManufacturerDataMask = null; // clear manufacturer data mask
-            return this;
-        }
-
-        /**
-         * Set filter on partial manufacture data. For any bit in the mask, set it the 1 if it needs
-         * to match the one in manufacturer data, otherwise set it to 0.
-         * <p>
-         * The {@code manufacturerDataMask} must have the same length of {@code manufacturerData}.
-         *
-         * @throws IllegalArgumentException If the {@code manufacturerId} is invalid, or {@code
-         * manufacturerData} is null while {@code manufacturerDataMask} is not, or {@code
-         * manufacturerData} and {@code manufacturerDataMask} have different length.
-         */
-        public Builder setManufacturerData(int manufacturerId, byte[] manufacturerData,
-                byte[] manufacturerDataMask) {
-            if (manufacturerData != null && manufacturerId < 0) {
-                throw new IllegalArgumentException("invalid manufacture id");
-            }
-            if (mManufacturerDataMask != null) {
-                if (mManufacturerData == null) {
-                    throw new IllegalArgumentException(
-                            "manufacturerData is null while manufacturerDataMask is not null");
-                }
-                // Since the mManufacturerDataMask is a bit mask for mManufacturerData, the lengths
-                // of the two byte array need to be the same.
-                if (mManufacturerData.length != mManufacturerDataMask.length) {
-                    throw new IllegalArgumentException(
-                            "size mismatch for manufacturerData and manufacturerDataMask");
-                }
-            }
-            mManufacturerId = manufacturerId;
-            mManufacturerData = manufacturerData;
-            mManufacturerDataMask = manufacturerDataMask;
-            return this;
-        }
-
-        /**
-         * Build {@link ScanFilter}.
-         *
-         * @throws IllegalArgumentException If the filter cannot be built.
-         */
-        public ScanFilter build() {
-            return new ScanFilter(mDeviceName, mDeviceAddress,
-                    mServiceUuid, mUuidMask, mServiceSolicitationUuid,
-                    mServiceSolicitationUuidMask,
-                    mServiceDataUuid, mServiceData, mServiceDataMask,
-                    mManufacturerId, mManufacturerData, mManufacturerDataMask,
-                    mAddressType, mIrk);
-        }
-    }
-}
diff --git a/core/java/android/bluetooth/le/ScanRecord.java b/core/java/android/bluetooth/le/ScanRecord.java
deleted file mode 100644
index 9b8c2ea..0000000
--- a/core/java/android/bluetooth/le/ScanRecord.java
+++ /dev/null
@@ -1,378 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.le;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SuppressLint;
-import android.bluetooth.BluetoothUuid;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.os.ParcelUuid;
-import android.util.ArrayMap;
-import android.util.Log;
-import android.util.SparseArray;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import java.util.function.Predicate;
-
-/**
- * Represents a scan record from Bluetooth LE scan.
- */
-@SuppressLint("AndroidFrameworkBluetoothPermission")
-public final class ScanRecord {
-
-    private static final String TAG = "ScanRecord";
-
-    // The following data type values are assigned by Bluetooth SIG.
-    // For more details refer to Bluetooth 4.1 specification, Volume 3, Part C, Section 18.
-    private static final int DATA_TYPE_FLAGS = 0x01;
-    private static final int DATA_TYPE_SERVICE_UUIDS_16_BIT_PARTIAL = 0x02;
-    private static final int DATA_TYPE_SERVICE_UUIDS_16_BIT_COMPLETE = 0x03;
-    private static final int DATA_TYPE_SERVICE_UUIDS_32_BIT_PARTIAL = 0x04;
-    private static final int DATA_TYPE_SERVICE_UUIDS_32_BIT_COMPLETE = 0x05;
-    private static final int DATA_TYPE_SERVICE_UUIDS_128_BIT_PARTIAL = 0x06;
-    private static final int DATA_TYPE_SERVICE_UUIDS_128_BIT_COMPLETE = 0x07;
-    private static final int DATA_TYPE_LOCAL_NAME_SHORT = 0x08;
-    private static final int DATA_TYPE_LOCAL_NAME_COMPLETE = 0x09;
-    private static final int DATA_TYPE_TX_POWER_LEVEL = 0x0A;
-    private static final int DATA_TYPE_SERVICE_DATA_16_BIT = 0x16;
-    private static final int DATA_TYPE_SERVICE_DATA_32_BIT = 0x20;
-    private static final int DATA_TYPE_SERVICE_DATA_128_BIT = 0x21;
-    private static final int DATA_TYPE_SERVICE_SOLICITATION_UUIDS_16_BIT = 0x14;
-    private static final int DATA_TYPE_SERVICE_SOLICITATION_UUIDS_32_BIT = 0x1F;
-    private static final int DATA_TYPE_SERVICE_SOLICITATION_UUIDS_128_BIT = 0x15;
-    private static final int DATA_TYPE_MANUFACTURER_SPECIFIC_DATA = 0xFF;
-
-    // Flags of the advertising data.
-    private final int mAdvertiseFlags;
-
-    @Nullable
-    private final List<ParcelUuid> mServiceUuids;
-    @Nullable
-    private final List<ParcelUuid> mServiceSolicitationUuids;
-
-    private final SparseArray<byte[]> mManufacturerSpecificData;
-
-    private final Map<ParcelUuid, byte[]> mServiceData;
-
-    // Transmission power level(in dB).
-    private final int mTxPowerLevel;
-
-    // Local name of the Bluetooth LE device.
-    private final String mDeviceName;
-
-    // Raw bytes of scan record.
-    private final byte[] mBytes;
-
-    /**
-     * Returns the advertising flags indicating the discoverable mode and capability of the device.
-     * Returns -1 if the flag field is not set.
-     */
-    public int getAdvertiseFlags() {
-        return mAdvertiseFlags;
-    }
-
-    /**
-     * Returns a list of service UUIDs within the advertisement that are used to identify the
-     * bluetooth GATT services.
-     */
-    public List<ParcelUuid> getServiceUuids() {
-        return mServiceUuids;
-    }
-
-    /**
-     * Returns a list of service solicitation UUIDs within the advertisement that are used to
-     * identify the Bluetooth GATT services.
-     */
-    @NonNull
-    public List<ParcelUuid> getServiceSolicitationUuids() {
-        return mServiceSolicitationUuids;
-    }
-
-    /**
-     * Returns a sparse array of manufacturer identifier and its corresponding manufacturer specific
-     * data.
-     */
-    public SparseArray<byte[]> getManufacturerSpecificData() {
-        return mManufacturerSpecificData;
-    }
-
-    /**
-     * Returns the manufacturer specific data associated with the manufacturer id. Returns
-     * {@code null} if the {@code manufacturerId} is not found.
-     */
-    @Nullable
-    public byte[] getManufacturerSpecificData(int manufacturerId) {
-        if (mManufacturerSpecificData == null) {
-            return null;
-        }
-        return mManufacturerSpecificData.get(manufacturerId);
-    }
-
-    /**
-     * Returns a map of service UUID and its corresponding service data.
-     */
-    public Map<ParcelUuid, byte[]> getServiceData() {
-        return mServiceData;
-    }
-
-    /**
-     * Returns the service data byte array associated with the {@code serviceUuid}. Returns
-     * {@code null} if the {@code serviceDataUuid} is not found.
-     */
-    @Nullable
-    public byte[] getServiceData(ParcelUuid serviceDataUuid) {
-        if (serviceDataUuid == null || mServiceData == null) {
-            return null;
-        }
-        return mServiceData.get(serviceDataUuid);
-    }
-
-    /**
-     * Returns the transmission power level of the packet in dBm. Returns {@link Integer#MIN_VALUE}
-     * if the field is not set. This value can be used to calculate the path loss of a received
-     * packet using the following equation:
-     * <p>
-     * <code>pathloss = txPowerLevel - rssi</code>
-     */
-    public int getTxPowerLevel() {
-        return mTxPowerLevel;
-    }
-
-    /**
-     * Returns the local name of the BLE device. This is a UTF-8 encoded string.
-     */
-    @Nullable
-    public String getDeviceName() {
-        return mDeviceName;
-    }
-
-    /**
-     * Returns raw bytes of scan record.
-     */
-    public byte[] getBytes() {
-        return mBytes;
-    }
-
-    /**
-     * Test if any fields contained inside this scan record are matched by the
-     * given matcher.
-     *
-     * @hide
-     */
-    public boolean matchesAnyField(@NonNull Predicate<byte[]> matcher) {
-        int pos = 0;
-        while (pos < mBytes.length) {
-            final int length = mBytes[pos] & 0xFF;
-            if (length == 0) {
-                break;
-            }
-            if (matcher.test(Arrays.copyOfRange(mBytes, pos, pos + length + 1))) {
-                return true;
-            }
-            pos += length + 1;
-        }
-        return false;
-    }
-
-    private ScanRecord(List<ParcelUuid> serviceUuids,
-            List<ParcelUuid> serviceSolicitationUuids,
-            SparseArray<byte[]> manufacturerData,
-            Map<ParcelUuid, byte[]> serviceData,
-            int advertiseFlags, int txPowerLevel,
-            String localName, byte[] bytes) {
-        mServiceSolicitationUuids = serviceSolicitationUuids;
-        mServiceUuids = serviceUuids;
-        mManufacturerSpecificData = manufacturerData;
-        mServiceData = serviceData;
-        mDeviceName = localName;
-        mAdvertiseFlags = advertiseFlags;
-        mTxPowerLevel = txPowerLevel;
-        mBytes = bytes;
-    }
-
-    /**
-     * Parse scan record bytes to {@link ScanRecord}.
-     * <p>
-     * The format is defined in Bluetooth 4.1 specification, Volume 3, Part C, Section 11 and 18.
-     * <p>
-     * All numerical multi-byte entities and values shall use little-endian <strong>byte</strong>
-     * order.
-     *
-     * @param scanRecord The scan record of Bluetooth LE advertisement and/or scan response.
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public static ScanRecord parseFromBytes(byte[] scanRecord) {
-        if (scanRecord == null) {
-            return null;
-        }
-
-        int currentPos = 0;
-        int advertiseFlag = -1;
-        List<ParcelUuid> serviceUuids = new ArrayList<ParcelUuid>();
-        List<ParcelUuid> serviceSolicitationUuids = new ArrayList<ParcelUuid>();
-        String localName = null;
-        int txPowerLevel = Integer.MIN_VALUE;
-
-        SparseArray<byte[]> manufacturerData = new SparseArray<byte[]>();
-        Map<ParcelUuid, byte[]> serviceData = new ArrayMap<ParcelUuid, byte[]>();
-
-        try {
-            while (currentPos < scanRecord.length) {
-                // length is unsigned int.
-                int length = scanRecord[currentPos++] & 0xFF;
-                if (length == 0) {
-                    break;
-                }
-                // Note the length includes the length of the field type itself.
-                int dataLength = length - 1;
-                // fieldType is unsigned int.
-                int fieldType = scanRecord[currentPos++] & 0xFF;
-                switch (fieldType) {
-                    case DATA_TYPE_FLAGS:
-                        advertiseFlag = scanRecord[currentPos] & 0xFF;
-                        break;
-                    case DATA_TYPE_SERVICE_UUIDS_16_BIT_PARTIAL:
-                    case DATA_TYPE_SERVICE_UUIDS_16_BIT_COMPLETE:
-                        parseServiceUuid(scanRecord, currentPos,
-                                dataLength, BluetoothUuid.UUID_BYTES_16_BIT, serviceUuids);
-                        break;
-                    case DATA_TYPE_SERVICE_UUIDS_32_BIT_PARTIAL:
-                    case DATA_TYPE_SERVICE_UUIDS_32_BIT_COMPLETE:
-                        parseServiceUuid(scanRecord, currentPos, dataLength,
-                                BluetoothUuid.UUID_BYTES_32_BIT, serviceUuids);
-                        break;
-                    case DATA_TYPE_SERVICE_UUIDS_128_BIT_PARTIAL:
-                    case DATA_TYPE_SERVICE_UUIDS_128_BIT_COMPLETE:
-                        parseServiceUuid(scanRecord, currentPos, dataLength,
-                                BluetoothUuid.UUID_BYTES_128_BIT, serviceUuids);
-                        break;
-                    case DATA_TYPE_SERVICE_SOLICITATION_UUIDS_16_BIT:
-                        parseServiceSolicitationUuid(scanRecord, currentPos, dataLength,
-                                BluetoothUuid.UUID_BYTES_16_BIT, serviceSolicitationUuids);
-                        break;
-                    case DATA_TYPE_SERVICE_SOLICITATION_UUIDS_32_BIT:
-                        parseServiceSolicitationUuid(scanRecord, currentPos, dataLength,
-                                BluetoothUuid.UUID_BYTES_32_BIT, serviceSolicitationUuids);
-                        break;
-                    case DATA_TYPE_SERVICE_SOLICITATION_UUIDS_128_BIT:
-                        parseServiceSolicitationUuid(scanRecord, currentPos, dataLength,
-                                BluetoothUuid.UUID_BYTES_128_BIT, serviceSolicitationUuids);
-                        break;
-                    case DATA_TYPE_LOCAL_NAME_SHORT:
-                    case DATA_TYPE_LOCAL_NAME_COMPLETE:
-                        localName = new String(
-                                extractBytes(scanRecord, currentPos, dataLength));
-                        break;
-                    case DATA_TYPE_TX_POWER_LEVEL:
-                        txPowerLevel = scanRecord[currentPos];
-                        break;
-                    case DATA_TYPE_SERVICE_DATA_16_BIT:
-                    case DATA_TYPE_SERVICE_DATA_32_BIT:
-                    case DATA_TYPE_SERVICE_DATA_128_BIT:
-                        int serviceUuidLength = BluetoothUuid.UUID_BYTES_16_BIT;
-                        if (fieldType == DATA_TYPE_SERVICE_DATA_32_BIT) {
-                            serviceUuidLength = BluetoothUuid.UUID_BYTES_32_BIT;
-                        } else if (fieldType == DATA_TYPE_SERVICE_DATA_128_BIT) {
-                            serviceUuidLength = BluetoothUuid.UUID_BYTES_128_BIT;
-                        }
-
-                        byte[] serviceDataUuidBytes = extractBytes(scanRecord, currentPos,
-                                serviceUuidLength);
-                        ParcelUuid serviceDataUuid = BluetoothUuid.parseUuidFrom(
-                                serviceDataUuidBytes);
-                        byte[] serviceDataArray = extractBytes(scanRecord,
-                                currentPos + serviceUuidLength, dataLength - serviceUuidLength);
-                        serviceData.put(serviceDataUuid, serviceDataArray);
-                        break;
-                    case DATA_TYPE_MANUFACTURER_SPECIFIC_DATA:
-                        // The first two bytes of the manufacturer specific data are
-                        // manufacturer ids in little endian.
-                        int manufacturerId = ((scanRecord[currentPos + 1] & 0xFF) << 8)
-                                + (scanRecord[currentPos] & 0xFF);
-                        byte[] manufacturerDataBytes = extractBytes(scanRecord, currentPos + 2,
-                                dataLength - 2);
-                        manufacturerData.put(manufacturerId, manufacturerDataBytes);
-                        break;
-                    default:
-                        // Just ignore, we don't handle such data type.
-                        break;
-                }
-                currentPos += dataLength;
-            }
-
-            if (serviceUuids.isEmpty()) {
-                serviceUuids = null;
-            }
-            return new ScanRecord(serviceUuids, serviceSolicitationUuids, manufacturerData,
-                    serviceData, advertiseFlag, txPowerLevel, localName, scanRecord);
-        } catch (Exception e) {
-            Log.e(TAG, "unable to parse scan record: " + Arrays.toString(scanRecord));
-            // As the record is invalid, ignore all the parsed results for this packet
-            // and return an empty record with raw scanRecord bytes in results
-            return new ScanRecord(null, null, null, null, -1, Integer.MIN_VALUE, null, scanRecord);
-        }
-    }
-
-    @Override
-    public String toString() {
-        return "ScanRecord [mAdvertiseFlags=" + mAdvertiseFlags + ", mServiceUuids=" + mServiceUuids
-                + ", mServiceSolicitationUuids=" + mServiceSolicitationUuids
-                + ", mManufacturerSpecificData=" + BluetoothLeUtils.toString(
-                mManufacturerSpecificData)
-                + ", mServiceData=" + BluetoothLeUtils.toString(mServiceData)
-                + ", mTxPowerLevel=" + mTxPowerLevel + ", mDeviceName=" + mDeviceName + "]";
-    }
-
-    // Parse service UUIDs.
-    private static int parseServiceUuid(byte[] scanRecord, int currentPos, int dataLength,
-            int uuidLength, List<ParcelUuid> serviceUuids) {
-        while (dataLength > 0) {
-            byte[] uuidBytes = extractBytes(scanRecord, currentPos,
-                    uuidLength);
-            serviceUuids.add(BluetoothUuid.parseUuidFrom(uuidBytes));
-            dataLength -= uuidLength;
-            currentPos += uuidLength;
-        }
-        return currentPos;
-    }
-
-    /**
-     * Parse service Solicitation UUIDs.
-     */
-    private static int parseServiceSolicitationUuid(byte[] scanRecord, int currentPos,
-            int dataLength, int uuidLength, List<ParcelUuid> serviceSolicitationUuids) {
-        while (dataLength > 0) {
-            byte[] uuidBytes = extractBytes(scanRecord, currentPos, uuidLength);
-            serviceSolicitationUuids.add(BluetoothUuid.parseUuidFrom(uuidBytes));
-            dataLength -= uuidLength;
-            currentPos += uuidLength;
-        }
-        return currentPos;
-    }
-
-    // Helper method to extract bytes from byte array.
-    private static byte[] extractBytes(byte[] scanRecord, int start, int length) {
-        byte[] bytes = new byte[length];
-        System.arraycopy(scanRecord, start, bytes, 0, length);
-        return bytes;
-    }
-}
diff --git a/core/java/android/bluetooth/le/ScanResult.java b/core/java/android/bluetooth/le/ScanResult.java
deleted file mode 100644
index f437d86..0000000
--- a/core/java/android/bluetooth/le/ScanResult.java
+++ /dev/null
@@ -1,361 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.le;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.bluetooth.Attributable;
-import android.bluetooth.BluetoothDevice;
-import android.content.AttributionSource;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.Objects;
-
-/**
- * ScanResult for Bluetooth LE scan.
- */
-public final class ScanResult implements Parcelable, Attributable {
-
-    /**
-     * For chained advertisements, inidcates tha the data contained in this
-     * scan result is complete.
-     */
-    public static final int DATA_COMPLETE = 0x00;
-
-    /**
-     * For chained advertisements, indicates that the controller was
-     * unable to receive all chained packets and the scan result contains
-     * incomplete truncated data.
-     */
-    public static final int DATA_TRUNCATED = 0x02;
-
-    /**
-     * Indicates that the secondary physical layer was not used.
-     */
-    public static final int PHY_UNUSED = 0x00;
-
-    /**
-     * Advertising Set ID is not present in the packet.
-     */
-    public static final int SID_NOT_PRESENT = 0xFF;
-
-    /**
-     * TX power is not present in the packet.
-     */
-    public static final int TX_POWER_NOT_PRESENT = 0x7F;
-
-    /**
-     * Periodic advertising interval is not present in the packet.
-     */
-    public static final int PERIODIC_INTERVAL_NOT_PRESENT = 0x00;
-
-    /**
-     * Mask for checking whether event type represents legacy advertisement.
-     */
-    private static final int ET_LEGACY_MASK = 0x10;
-
-    /**
-     * Mask for checking whether event type represents connectable advertisement.
-     */
-    private static final int ET_CONNECTABLE_MASK = 0x01;
-
-    // Remote Bluetooth device.
-    private BluetoothDevice mDevice;
-
-    // Scan record, including advertising data and scan response data.
-    @Nullable
-    private ScanRecord mScanRecord;
-
-    // Received signal strength.
-    private int mRssi;
-
-    // Device timestamp when the result was last seen.
-    private long mTimestampNanos;
-
-    private int mEventType;
-    private int mPrimaryPhy;
-    private int mSecondaryPhy;
-    private int mAdvertisingSid;
-    private int mTxPower;
-    private int mPeriodicAdvertisingInterval;
-
-    /**
-     * Constructs a new ScanResult.
-     *
-     * @param device Remote Bluetooth device found.
-     * @param scanRecord Scan record including both advertising data and scan response data.
-     * @param rssi Received signal strength.
-     * @param timestampNanos Timestamp at which the scan result was observed.
-     * @deprecated use {@link #ScanResult(BluetoothDevice, int, int, int, int, int, int, int,
-     * ScanRecord, long)}
-     */
-    @Deprecated
-    public ScanResult(BluetoothDevice device, ScanRecord scanRecord, int rssi,
-            long timestampNanos) {
-        mDevice = device;
-        mScanRecord = scanRecord;
-        mRssi = rssi;
-        mTimestampNanos = timestampNanos;
-        mEventType = (DATA_COMPLETE << 5) | ET_LEGACY_MASK | ET_CONNECTABLE_MASK;
-        mPrimaryPhy = BluetoothDevice.PHY_LE_1M;
-        mSecondaryPhy = PHY_UNUSED;
-        mAdvertisingSid = SID_NOT_PRESENT;
-        mTxPower = 127;
-        mPeriodicAdvertisingInterval = 0;
-    }
-
-    /**
-     * Constructs a new ScanResult.
-     *
-     * @param device Remote Bluetooth device found.
-     * @param eventType Event type.
-     * @param primaryPhy Primary advertising phy.
-     * @param secondaryPhy Secondary advertising phy.
-     * @param advertisingSid Advertising set ID.
-     * @param txPower Transmit power.
-     * @param rssi Received signal strength.
-     * @param periodicAdvertisingInterval Periodic advertising interval.
-     * @param scanRecord Scan record including both advertising data and scan response data.
-     * @param timestampNanos Timestamp at which the scan result was observed.
-     */
-    public ScanResult(BluetoothDevice device, int eventType, int primaryPhy, int secondaryPhy,
-            int advertisingSid, int txPower, int rssi, int periodicAdvertisingInterval,
-            ScanRecord scanRecord, long timestampNanos) {
-        mDevice = device;
-        mEventType = eventType;
-        mPrimaryPhy = primaryPhy;
-        mSecondaryPhy = secondaryPhy;
-        mAdvertisingSid = advertisingSid;
-        mTxPower = txPower;
-        mRssi = rssi;
-        mPeriodicAdvertisingInterval = periodicAdvertisingInterval;
-        mScanRecord = scanRecord;
-        mTimestampNanos = timestampNanos;
-    }
-
-    private ScanResult(Parcel in) {
-        readFromParcel(in);
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        if (mDevice != null) {
-            dest.writeInt(1);
-            mDevice.writeToParcel(dest, flags);
-        } else {
-            dest.writeInt(0);
-        }
-        if (mScanRecord != null) {
-            dest.writeInt(1);
-            dest.writeByteArray(mScanRecord.getBytes());
-        } else {
-            dest.writeInt(0);
-        }
-        dest.writeInt(mRssi);
-        dest.writeLong(mTimestampNanos);
-        dest.writeInt(mEventType);
-        dest.writeInt(mPrimaryPhy);
-        dest.writeInt(mSecondaryPhy);
-        dest.writeInt(mAdvertisingSid);
-        dest.writeInt(mTxPower);
-        dest.writeInt(mPeriodicAdvertisingInterval);
-    }
-
-    private void readFromParcel(Parcel in) {
-        if (in.readInt() == 1) {
-            mDevice = BluetoothDevice.CREATOR.createFromParcel(in);
-        }
-        if (in.readInt() == 1) {
-            mScanRecord = ScanRecord.parseFromBytes(in.createByteArray());
-        }
-        mRssi = in.readInt();
-        mTimestampNanos = in.readLong();
-        mEventType = in.readInt();
-        mPrimaryPhy = in.readInt();
-        mSecondaryPhy = in.readInt();
-        mAdvertisingSid = in.readInt();
-        mTxPower = in.readInt();
-        mPeriodicAdvertisingInterval = in.readInt();
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    /** {@hide} */
-    public void setAttributionSource(@NonNull AttributionSource attributionSource) {
-        Attributable.setAttributionSource(mDevice, attributionSource);
-    }
-
-    /**
-     * Returns the remote Bluetooth device identified by the Bluetooth device address.
-     */
-    public BluetoothDevice getDevice() {
-        return mDevice;
-    }
-
-    /**
-     * Returns the scan record, which is a combination of advertisement and scan response.
-     */
-    @Nullable
-    public ScanRecord getScanRecord() {
-        return mScanRecord;
-    }
-
-    /**
-     * Returns the received signal strength in dBm. The valid range is [-127, 126].
-     */
-    public int getRssi() {
-        return mRssi;
-    }
-
-    /**
-     * Returns timestamp since boot when the scan record was observed.
-     */
-    public long getTimestampNanos() {
-        return mTimestampNanos;
-    }
-
-    /**
-     * Returns true if this object represents legacy scan result.
-     * Legacy scan results do not contain advanced advertising information
-     * as specified in the Bluetooth Core Specification v5.
-     */
-    public boolean isLegacy() {
-        return (mEventType & ET_LEGACY_MASK) != 0;
-    }
-
-    /**
-     * Returns true if this object represents connectable scan result.
-     */
-    public boolean isConnectable() {
-        return (mEventType & ET_CONNECTABLE_MASK) != 0;
-    }
-
-    /**
-     * Returns the data status.
-     * Can be one of {@link ScanResult#DATA_COMPLETE} or
-     * {@link ScanResult#DATA_TRUNCATED}.
-     */
-    public int getDataStatus() {
-        // return bit 5 and 6
-        return (mEventType >> 5) & 0x03;
-    }
-
-    /**
-     * Returns the primary Physical Layer
-     * on which this advertisment was received.
-     * Can be one of {@link BluetoothDevice#PHY_LE_1M} or
-     * {@link BluetoothDevice#PHY_LE_CODED}.
-     */
-    public int getPrimaryPhy() {
-        return mPrimaryPhy;
-    }
-
-    /**
-     * Returns the secondary Physical Layer
-     * on which this advertisment was received.
-     * Can be one of {@link BluetoothDevice#PHY_LE_1M},
-     * {@link BluetoothDevice#PHY_LE_2M}, {@link BluetoothDevice#PHY_LE_CODED}
-     * or {@link ScanResult#PHY_UNUSED} - if the advertisement
-     * was not received on a secondary physical channel.
-     */
-    public int getSecondaryPhy() {
-        return mSecondaryPhy;
-    }
-
-    /**
-     * Returns the advertising set id.
-     * May return {@link ScanResult#SID_NOT_PRESENT} if
-     * no set id was is present.
-     */
-    public int getAdvertisingSid() {
-        return mAdvertisingSid;
-    }
-
-    /**
-     * Returns the transmit power in dBm.
-     * Valid range is [-127, 126]. A value of {@link ScanResult#TX_POWER_NOT_PRESENT}
-     * indicates that the TX power is not present.
-     */
-    public int getTxPower() {
-        return mTxPower;
-    }
-
-    /**
-     * Returns the periodic advertising interval in units of 1.25ms.
-     * Valid range is 6 (7.5ms) to 65536 (81918.75ms). A value of
-     * {@link ScanResult#PERIODIC_INTERVAL_NOT_PRESENT} means periodic
-     * advertising interval is not present.
-     */
-    public int getPeriodicAdvertisingInterval() {
-        return mPeriodicAdvertisingInterval;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(mDevice, mRssi, mScanRecord, mTimestampNanos,
-                mEventType, mPrimaryPhy, mSecondaryPhy,
-                mAdvertisingSid, mTxPower,
-                mPeriodicAdvertisingInterval);
-    }
-
-    @Override
-    public boolean equals(@Nullable Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj == null || getClass() != obj.getClass()) {
-            return false;
-        }
-        ScanResult other = (ScanResult) obj;
-        return Objects.equals(mDevice, other.mDevice) && (mRssi == other.mRssi)
-                && Objects.equals(mScanRecord, other.mScanRecord)
-                && (mTimestampNanos == other.mTimestampNanos)
-                && mEventType == other.mEventType
-                && mPrimaryPhy == other.mPrimaryPhy
-                && mSecondaryPhy == other.mSecondaryPhy
-                && mAdvertisingSid == other.mAdvertisingSid
-                && mTxPower == other.mTxPower
-                && mPeriodicAdvertisingInterval == other.mPeriodicAdvertisingInterval;
-    }
-
-    @Override
-    public String toString() {
-        return "ScanResult{" + "device=" + mDevice + ", scanRecord="
-                + Objects.toString(mScanRecord) + ", rssi=" + mRssi
-                + ", timestampNanos=" + mTimestampNanos + ", eventType=" + mEventType
-                + ", primaryPhy=" + mPrimaryPhy + ", secondaryPhy=" + mSecondaryPhy
-                + ", advertisingSid=" + mAdvertisingSid + ", txPower=" + mTxPower
-                + ", periodicAdvertisingInterval=" + mPeriodicAdvertisingInterval + '}';
-    }
-
-    public static final @android.annotation.NonNull Parcelable.Creator<ScanResult> CREATOR = new Creator<ScanResult>() {
-        @Override
-        public ScanResult createFromParcel(Parcel source) {
-            return new ScanResult(source);
-        }
-
-        @Override
-        public ScanResult[] newArray(int size) {
-            return new ScanResult[size];
-        }
-    };
-
-}
diff --git a/core/java/android/bluetooth/le/ScanSettings.java b/core/java/android/bluetooth/le/ScanSettings.java
deleted file mode 100644
index 1aa7cb5..0000000
--- a/core/java/android/bluetooth/le/ScanSettings.java
+++ /dev/null
@@ -1,438 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.le;
-
-import android.annotation.SystemApi;
-import android.bluetooth.BluetoothDevice;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Bluetooth LE scan settings are passed to {@link BluetoothLeScanner#startScan} to define the
- * parameters for the scan.
- */
-public final class ScanSettings implements Parcelable {
-
-    /**
-     * A special Bluetooth LE scan mode. Applications using this scan mode will passively listen for
-     * other scan results without starting BLE scans themselves.
-     */
-    public static final int SCAN_MODE_OPPORTUNISTIC = -1;
-
-    /**
-     * Perform Bluetooth LE scan in low power mode. This is the default scan mode as it consumes the
-     * least power. This mode is enforced if the scanning application is not in foreground.
-     */
-    public static final int SCAN_MODE_LOW_POWER = 0;
-
-    /**
-     * Perform Bluetooth LE scan in balanced power mode. Scan results are returned at a rate that
-     * provides a good trade-off between scan frequency and power consumption.
-     */
-    public static final int SCAN_MODE_BALANCED = 1;
-
-    /**
-     * Scan using highest duty cycle. It's recommended to only use this mode when the application is
-     * running in the foreground.
-     */
-    public static final int SCAN_MODE_LOW_LATENCY = 2;
-
-    /**
-     * Perform Bluetooth LE scan in ambient discovery mode. This mode has lower duty cycle and more
-     * aggressive scan interval than balanced mode that provides a good trade-off between scan
-     * latency and power consumption.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int SCAN_MODE_AMBIENT_DISCOVERY = 3;
-
-    /**
-     * Trigger a callback for every Bluetooth advertisement found that matches the filter criteria.
-     * If no filter is active, all advertisement packets are reported.
-     */
-    public static final int CALLBACK_TYPE_ALL_MATCHES = 1;
-
-    /**
-     * A result callback is only triggered for the first advertisement packet received that matches
-     * the filter criteria.
-     */
-    public static final int CALLBACK_TYPE_FIRST_MATCH = 2;
-
-    /**
-     * Receive a callback when advertisements are no longer received from a device that has been
-     * previously reported by a first match callback.
-     */
-    public static final int CALLBACK_TYPE_MATCH_LOST = 4;
-
-
-    /**
-     * Determines how many advertisements to match per filter, as this is scarce hw resource
-     */
-    /**
-     * Match one advertisement per filter
-     */
-    public static final int MATCH_NUM_ONE_ADVERTISEMENT = 1;
-
-    /**
-     * Match few advertisement per filter, depends on current capability and availibility of
-     * the resources in hw
-     */
-    public static final int MATCH_NUM_FEW_ADVERTISEMENT = 2;
-
-    /**
-     * Match as many advertisement per filter as hw could allow, depends on current
-     * capability and availibility of the resources in hw
-     */
-    public static final int MATCH_NUM_MAX_ADVERTISEMENT = 3;
-
-
-    /**
-     * In Aggressive mode, hw will determine a match sooner even with feeble signal strength
-     * and few number of sightings/match in a duration.
-     */
-    public static final int MATCH_MODE_AGGRESSIVE = 1;
-
-    /**
-     * For sticky mode, higher threshold of signal strength and sightings is required
-     * before reporting by hw
-     */
-    public static final int MATCH_MODE_STICKY = 2;
-
-    /**
-     * Request full scan results which contain the device, rssi, advertising data, scan response
-     * as well as the scan timestamp.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int SCAN_RESULT_TYPE_FULL = 0;
-
-    /**
-     * Request abbreviated scan results which contain the device, rssi and scan timestamp.
-     * <p>
-     * <b>Note:</b> It is possible for an application to get more scan results than it asked for, if
-     * there are multiple apps using this type.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int SCAN_RESULT_TYPE_ABBREVIATED = 1;
-
-    /**
-     * Use all supported PHYs for scanning.
-     * This will check the controller capabilities, and start
-     * the scan on 1Mbit and LE Coded PHYs if supported, or on
-     * the 1Mbit PHY only.
-     */
-    public static final int PHY_LE_ALL_SUPPORTED = 255;
-
-    // Bluetooth LE scan mode.
-    private int mScanMode;
-
-    // Bluetooth LE scan callback type
-    private int mCallbackType;
-
-    // Bluetooth LE scan result type
-    private int mScanResultType;
-
-    // Time of delay for reporting the scan result
-    private long mReportDelayMillis;
-
-    private int mMatchMode;
-
-    private int mNumOfMatchesPerFilter;
-
-    // Include only legacy advertising results
-    private boolean mLegacy;
-
-    private int mPhy;
-
-    public int getScanMode() {
-        return mScanMode;
-    }
-
-    public int getCallbackType() {
-        return mCallbackType;
-    }
-
-    public int getScanResultType() {
-        return mScanResultType;
-    }
-
-    /**
-     * @hide
-     */
-    public int getMatchMode() {
-        return mMatchMode;
-    }
-
-    /**
-     * @hide
-     */
-    public int getNumOfMatches() {
-        return mNumOfMatchesPerFilter;
-    }
-
-    /**
-     * Returns whether only legacy advertisements will be returned.
-     * Legacy advertisements include advertisements as specified
-     * by the Bluetooth core specification 4.2 and below.
-     */
-    public boolean getLegacy() {
-        return mLegacy;
-    }
-
-    /**
-     * Returns the physical layer used during a scan.
-     */
-    public int getPhy() {
-        return mPhy;
-    }
-
-    /**
-     * Returns report delay timestamp based on the device clock.
-     */
-    public long getReportDelayMillis() {
-        return mReportDelayMillis;
-    }
-
-    private ScanSettings(int scanMode, int callbackType, int scanResultType,
-            long reportDelayMillis, int matchMode,
-            int numOfMatchesPerFilter, boolean legacy, int phy) {
-        mScanMode = scanMode;
-        mCallbackType = callbackType;
-        mScanResultType = scanResultType;
-        mReportDelayMillis = reportDelayMillis;
-        mNumOfMatchesPerFilter = numOfMatchesPerFilter;
-        mMatchMode = matchMode;
-        mLegacy = legacy;
-        mPhy = phy;
-    }
-
-    private ScanSettings(Parcel in) {
-        mScanMode = in.readInt();
-        mCallbackType = in.readInt();
-        mScanResultType = in.readInt();
-        mReportDelayMillis = in.readLong();
-        mMatchMode = in.readInt();
-        mNumOfMatchesPerFilter = in.readInt();
-        mLegacy = in.readInt() != 0;
-        mPhy = in.readInt();
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(mScanMode);
-        dest.writeInt(mCallbackType);
-        dest.writeInt(mScanResultType);
-        dest.writeLong(mReportDelayMillis);
-        dest.writeInt(mMatchMode);
-        dest.writeInt(mNumOfMatchesPerFilter);
-        dest.writeInt(mLegacy ? 1 : 0);
-        dest.writeInt(mPhy);
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    public static final @android.annotation.NonNull Parcelable.Creator<ScanSettings> CREATOR =
-            new Creator<ScanSettings>() {
-        @Override
-        public ScanSettings[] newArray(int size) {
-            return new ScanSettings[size];
-        }
-
-        @Override
-        public ScanSettings createFromParcel(Parcel in) {
-            return new ScanSettings(in);
-        }
-    };
-
-    /**
-     * Builder for {@link ScanSettings}.
-     */
-    public static final class Builder {
-        private int mScanMode = SCAN_MODE_LOW_POWER;
-        private int mCallbackType = CALLBACK_TYPE_ALL_MATCHES;
-        private int mScanResultType = SCAN_RESULT_TYPE_FULL;
-        private long mReportDelayMillis = 0;
-        private int mMatchMode = MATCH_MODE_AGGRESSIVE;
-        private int mNumOfMatchesPerFilter = MATCH_NUM_MAX_ADVERTISEMENT;
-        private boolean mLegacy = true;
-        private int mPhy = PHY_LE_ALL_SUPPORTED;
-
-        /**
-         * Set scan mode for Bluetooth LE scan.
-         *
-         * @param scanMode The scan mode can be one of {@link ScanSettings#SCAN_MODE_LOW_POWER},
-         * {@link ScanSettings#SCAN_MODE_BALANCED} or {@link ScanSettings#SCAN_MODE_LOW_LATENCY}.
-         * @throws IllegalArgumentException If the {@code scanMode} is invalid.
-         */
-        public Builder setScanMode(int scanMode) {
-            switch (scanMode) {
-                case SCAN_MODE_OPPORTUNISTIC:
-                case SCAN_MODE_LOW_POWER:
-                case SCAN_MODE_BALANCED:
-                case SCAN_MODE_LOW_LATENCY:
-                case SCAN_MODE_AMBIENT_DISCOVERY:
-                    mScanMode = scanMode;
-                    break;
-                default:
-                    throw new IllegalArgumentException("invalid scan mode " + scanMode);
-            }
-            return this;
-        }
-
-        /**
-         * Set callback type for Bluetooth LE scan.
-         *
-         * @param callbackType The callback type flags for the scan.
-         * @throws IllegalArgumentException If the {@code callbackType} is invalid.
-         */
-        public Builder setCallbackType(int callbackType) {
-
-            if (!isValidCallbackType(callbackType)) {
-                throw new IllegalArgumentException("invalid callback type - " + callbackType);
-            }
-            mCallbackType = callbackType;
-            return this;
-        }
-
-        // Returns true if the callbackType is valid.
-        private boolean isValidCallbackType(int callbackType) {
-            if (callbackType == CALLBACK_TYPE_ALL_MATCHES
-                    || callbackType == CALLBACK_TYPE_FIRST_MATCH
-                    || callbackType == CALLBACK_TYPE_MATCH_LOST) {
-                return true;
-            }
-            return callbackType == (CALLBACK_TYPE_FIRST_MATCH | CALLBACK_TYPE_MATCH_LOST);
-        }
-
-        /**
-         * Set scan result type for Bluetooth LE scan.
-         *
-         * @param scanResultType Type for scan result, could be either {@link
-         * ScanSettings#SCAN_RESULT_TYPE_FULL} or {@link ScanSettings#SCAN_RESULT_TYPE_ABBREVIATED}.
-         * @throws IllegalArgumentException If the {@code scanResultType} is invalid.
-         * @hide
-         */
-        @SystemApi
-        public Builder setScanResultType(int scanResultType) {
-            if (scanResultType < SCAN_RESULT_TYPE_FULL
-                    || scanResultType > SCAN_RESULT_TYPE_ABBREVIATED) {
-                throw new IllegalArgumentException(
-                        "invalid scanResultType - " + scanResultType);
-            }
-            mScanResultType = scanResultType;
-            return this;
-        }
-
-        /**
-         * Set report delay timestamp for Bluetooth LE scan. If set to 0, you will be notified of
-         * scan results immediately. If &gt; 0, scan results are queued up and delivered after the
-         * requested delay or 5000 milliseconds (whichever is higher). Note scan results may be
-         * delivered sooner if the internal buffers fill up.
-         *
-         * @param reportDelayMillis         how frequently scan results should be delivered in
-         *                                  milliseconds
-         * @throws IllegalArgumentException if {@code reportDelayMillis} &lt; 0
-         */
-        public Builder setReportDelay(long reportDelayMillis) {
-            if (reportDelayMillis < 0) {
-                throw new IllegalArgumentException("reportDelay must be > 0");
-            }
-            mReportDelayMillis = reportDelayMillis;
-            return this;
-        }
-
-        /**
-         * Set the number of matches for Bluetooth LE scan filters hardware match
-         *
-         * @param numOfMatches The num of matches can be one of
-         * {@link ScanSettings#MATCH_NUM_ONE_ADVERTISEMENT}
-         * or {@link ScanSettings#MATCH_NUM_FEW_ADVERTISEMENT} or {@link
-         * ScanSettings#MATCH_NUM_MAX_ADVERTISEMENT}
-         * @throws IllegalArgumentException If the {@code matchMode} is invalid.
-         */
-        public Builder setNumOfMatches(int numOfMatches) {
-            if (numOfMatches < MATCH_NUM_ONE_ADVERTISEMENT
-                    || numOfMatches > MATCH_NUM_MAX_ADVERTISEMENT) {
-                throw new IllegalArgumentException("invalid numOfMatches " + numOfMatches);
-            }
-            mNumOfMatchesPerFilter = numOfMatches;
-            return this;
-        }
-
-        /**
-         * Set match mode for Bluetooth LE scan filters hardware match
-         *
-         * @param matchMode The match mode can be one of {@link ScanSettings#MATCH_MODE_AGGRESSIVE}
-         * or {@link ScanSettings#MATCH_MODE_STICKY}
-         * @throws IllegalArgumentException If the {@code matchMode} is invalid.
-         */
-        public Builder setMatchMode(int matchMode) {
-            if (matchMode < MATCH_MODE_AGGRESSIVE
-                    || matchMode > MATCH_MODE_STICKY) {
-                throw new IllegalArgumentException("invalid matchMode " + matchMode);
-            }
-            mMatchMode = matchMode;
-            return this;
-        }
-
-        /**
-         * Set whether only legacy advertisments should be returned in scan results.
-         * Legacy advertisements include advertisements as specified by the
-         * Bluetooth core specification 4.2 and below. This is true by default
-         * for compatibility with older apps.
-         *
-         * @param legacy true if only legacy advertisements will be returned
-         */
-        public Builder setLegacy(boolean legacy) {
-            mLegacy = legacy;
-            return this;
-        }
-
-        /**
-         * Set the Physical Layer to use during this scan.
-         * This is used only if {@link ScanSettings.Builder#setLegacy}
-         * is set to false.
-         * {@link android.bluetooth.BluetoothAdapter#isLeCodedPhySupported}
-         * may be used to check whether LE Coded phy is supported by calling
-         * {@link android.bluetooth.BluetoothAdapter#isLeCodedPhySupported}.
-         * Selecting an unsupported phy will result in failure to start scan.
-         *
-         * @param phy Can be one of {@link BluetoothDevice#PHY_LE_1M}, {@link
-         * BluetoothDevice#PHY_LE_CODED} or {@link ScanSettings#PHY_LE_ALL_SUPPORTED}
-         */
-        public Builder setPhy(int phy) {
-            mPhy = phy;
-            return this;
-        }
-
-        /**
-         * Build {@link ScanSettings}.
-         */
-        public ScanSettings build() {
-            return new ScanSettings(mScanMode, mCallbackType, mScanResultType,
-                    mReportDelayMillis, mMatchMode,
-                    mNumOfMatchesPerFilter, mLegacy, mPhy);
-        }
-    }
-}
diff --git a/core/java/android/bluetooth/le/TransportBlock.java b/core/java/android/bluetooth/le/TransportBlock.java
deleted file mode 100644
index 18bad9c..0000000
--- a/core/java/android/bluetooth/le/TransportBlock.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.le;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.Log;
-
-import java.nio.BufferOverflowException;
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-
-/**
- * Wrapper for Transport Discovery Data Transport Blocks.
- * This class represents a Transport Block from a Transport Discovery Data.
- *
- * @see TransportDiscoveryData
- * @see AdvertiseData
- */
-public final class TransportBlock implements Parcelable {
-    private static final String TAG = "TransportBlock";
-    private final int mOrgId;
-    private final int mTdsFlags;
-    private final int mTransportDataLength;
-    private final byte[] mTransportData;
-
-    /**
-     * Creates an instance of TransportBlock from raw data.
-     *
-     * @param orgId the Organization ID
-     * @param tdsFlags the TDS flags
-     * @param transportDataLength the total length of the Transport Data
-     * @param transportData the Transport Data
-     */
-    public TransportBlock(int orgId, int tdsFlags, int transportDataLength,
-            @Nullable byte[] transportData) {
-        mOrgId = orgId;
-        mTdsFlags = tdsFlags;
-        mTransportDataLength = transportDataLength;
-        mTransportData = transportData;
-    }
-
-    private TransportBlock(Parcel in) {
-        mOrgId = in.readInt();
-        mTdsFlags = in.readInt();
-        mTransportDataLength = in.readInt();
-        if (mTransportDataLength > 0) {
-            mTransportData = new byte[mTransportDataLength];
-            in.readByteArray(mTransportData);
-        } else {
-            mTransportData = null;
-        }
-    }
-
-    @Override
-    public void writeToParcel(@NonNull Parcel dest, int flags) {
-        dest.writeInt(mOrgId);
-        dest.writeInt(mTdsFlags);
-        dest.writeInt(mTransportDataLength);
-        if (mTransportData != null) {
-            dest.writeByteArray(mTransportData);
-        }
-    }
-
-    /**
-     * @hide
-     */
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    /**
-     * @hide
-     */
-    @Override
-    public boolean equals(@Nullable Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj == null || getClass() != obj.getClass()) {
-            return false;
-        }
-        TransportBlock other = (TransportBlock) obj;
-        return Arrays.equals(toByteArray(), other.toByteArray());
-    }
-
-    public static final @NonNull Creator<TransportBlock> CREATOR = new Creator<TransportBlock>() {
-        @Override
-        public TransportBlock createFromParcel(Parcel in) {
-            return new TransportBlock(in);
-        }
-
-        @Override
-        public TransportBlock[] newArray(int size) {
-            return new TransportBlock[size];
-        }
-    };
-
-    /**
-     * Gets the Organization ID of the Transport Block which corresponds to one of the
-     * the Bluetooth SIG Assigned Numbers.
-     */
-    public int getOrgId() {
-        return mOrgId;
-    }
-
-    /**
-     * Gets the TDS flags of the Transport Block which represents the role of the device and
-     * information about its state and supported features.
-     */
-    public int getTdsFlags() {
-        return mTdsFlags;
-    }
-
-    /**
-     * Gets the total number of octets in the Transport Data field in this Transport Block.
-     */
-    public int getTransportDataLength() {
-        return mTransportDataLength;
-    }
-
-    /**
-     * Gets the Transport Data of the Transport Block which contains organization-specific data.
-     */
-    @Nullable
-    public byte[] getTransportData() {
-        return mTransportData;
-    }
-
-    /**
-     * Converts this TransportBlock to byte array
-     *
-     * @return byte array representation of this Transport Block or null if the conversion failed
-     */
-    @Nullable
-    public byte[] toByteArray() {
-        try {
-            ByteBuffer buffer = ByteBuffer.allocate(totalBytes());
-            buffer.put((byte) mOrgId);
-            buffer.put((byte) mTdsFlags);
-            buffer.put((byte) mTransportDataLength);
-            if (mTransportData != null) {
-                buffer.put(mTransportData);
-            }
-            return buffer.array();
-        } catch (BufferOverflowException e) {
-            Log.e(TAG, "Error converting to byte array: " + e.toString());
-            return null;
-        }
-    }
-
-    /**
-     * @return total byte count of this TransportBlock
-     */
-    public int totalBytes() {
-        // 3 uint8 + byte[] length
-        int size = 3 + mTransportDataLength;
-        return size;
-    }
-}
diff --git a/core/java/android/bluetooth/le/TransportDiscoveryData.java b/core/java/android/bluetooth/le/TransportDiscoveryData.java
deleted file mode 100644
index 2b52f19..0000000
--- a/core/java/android/bluetooth/le/TransportDiscoveryData.java
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.le;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.Log;
-
-import java.nio.BufferOverflowException;
-import java.nio.BufferUnderflowException;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Wrapper for Transport Discovery Data AD Type.
- * This class contains the Transport Discovery Data AD Type Code as well as
- * a list of potential Transport Blocks.
- *
- * @see AdvertiseData
- */
-public final class TransportDiscoveryData implements Parcelable {
-    private static final String TAG = "TransportDiscoveryData";
-    private final int mTransportDataType;
-    private final List<TransportBlock> mTransportBlocks;
-
-    /**
-     * Creates a TransportDiscoveryData instance.
-     *
-     * @param transportDataType the Transport Discovery Data AD Type
-     * @param transportBlocks the list of Transport Blocks
-     */
-    public TransportDiscoveryData(int transportDataType,
-            @NonNull List<TransportBlock> transportBlocks) {
-        mTransportDataType = transportDataType;
-        mTransportBlocks = transportBlocks;
-    }
-
-    /**
-     * Creates a TransportDiscoveryData instance from byte arrays.
-     *
-     * Uses the transport discovery data bytes and parses them into an usable class.
-     *
-     * @param transportDiscoveryData the raw discovery data
-     */
-    public TransportDiscoveryData(@NonNull byte[] transportDiscoveryData) {
-        ByteBuffer byteBuffer = ByteBuffer.wrap(transportDiscoveryData);
-        mTransportBlocks = new ArrayList();
-        if (byteBuffer.remaining() > 0) {
-            mTransportDataType = byteBuffer.get();
-        } else {
-            mTransportDataType = -1;
-        }
-        try {
-            while (byteBuffer.remaining() > 0) {
-                int orgId = byteBuffer.get();
-                int tdsFlags = byteBuffer.get();
-                int transportDataLength = byteBuffer.get();
-                byte[] transportData = new byte[transportDataLength];
-                byteBuffer.get(transportData, 0, transportDataLength);
-                mTransportBlocks.add(new TransportBlock(orgId, tdsFlags,
-                        transportDataLength, transportData));
-            }
-        } catch (BufferUnderflowException e) {
-            Log.e(TAG, "Error while parsing data: " + e.toString());
-        }
-    }
-
-    private TransportDiscoveryData(Parcel in) {
-        mTransportDataType = in.readInt();
-        mTransportBlocks = in.createTypedArrayList(TransportBlock.CREATOR);
-    }
-
-    /**
-     * @hide
-     */
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    /**
-     * @hide
-     */
-    @Override
-    public boolean equals(@Nullable Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj == null || getClass() != obj.getClass()) {
-            return false;
-        }
-        TransportDiscoveryData other = (TransportDiscoveryData) obj;
-        return Arrays.equals(toByteArray(), other.toByteArray());
-    }
-
-    @Override
-    public void writeToParcel(@NonNull Parcel dest, int flags) {
-        dest.writeInt(mTransportDataType);
-        dest.writeTypedList(mTransportBlocks);
-    }
-
-    public static final @NonNull Creator<TransportDiscoveryData> CREATOR =
-            new Creator<TransportDiscoveryData>() {
-                @Override
-                public TransportDiscoveryData createFromParcel(Parcel in) {
-                    return new TransportDiscoveryData(in);
-                }
-
-                @Override
-                public TransportDiscoveryData[] newArray(int size) {
-                    return new TransportDiscoveryData[size];
-                }
-    };
-
-    /**
-     * Gets the transport data type.
-     */
-    public int getTransportDataType() {
-        return mTransportDataType;
-    }
-
-    /**
-     * @return the list of {@link TransportBlock} in this TransportDiscoveryData
-     *         or an empty list if there are no Transport Blocks
-     */
-    @NonNull
-    public List<TransportBlock> getTransportBlocks() {
-        if (mTransportBlocks == null) {
-            return Collections.emptyList();
-        }
-        return mTransportBlocks;
-    }
-
-    /**
-     * Converts this TransportDiscoveryData to byte array
-     *
-     * @return byte array representation of this Transport Discovery Data or null if the
-     *         conversion failed
-     */
-    @Nullable
-    public byte[] toByteArray() {
-        try {
-            ByteBuffer buffer = ByteBuffer.allocate(totalBytes());
-            buffer.put((byte) mTransportDataType);
-            for (TransportBlock transportBlock : getTransportBlocks()) {
-                buffer.put(transportBlock.toByteArray());
-            }
-            return buffer.array();
-        } catch (BufferOverflowException e) {
-            Log.e(TAG, "Error converting to byte array: " + e.toString());
-            return null;
-        }
-    }
-
-    /**
-     * @return total byte count of this TransportDataDiscovery
-     */
-    public int totalBytes() {
-        int size = 1; // Counting Transport Data Type here.
-        for (TransportBlock transportBlock : getTransportBlocks()) {
-            size += transportBlock.totalBytes();
-        }
-        return size;
-    }
-}
diff --git a/core/java/android/bluetooth/le/TruncatedFilter.java b/core/java/android/bluetooth/le/TruncatedFilter.java
deleted file mode 100644
index 2592588..0000000
--- a/core/java/android/bluetooth/le/TruncatedFilter.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.le;
-
-import android.annotation.SuppressLint;
-import android.annotation.SystemApi;
-
-import java.util.List;
-
-/**
- * A special scan filter that lets the client decide how the scan record should be stored.
- *
- * @deprecated this is not used anywhere
- *
- * @hide
- */
-@Deprecated
-@SystemApi
-@SuppressLint("AndroidFrameworkBluetoothPermission")
-public final class TruncatedFilter {
-    private final ScanFilter mFilter;
-    private final List<ResultStorageDescriptor> mStorageDescriptors;
-
-    /**
-     * Constructor for {@link TruncatedFilter}.
-     *
-     * @param filter Scan filter of the truncated filter.
-     * @param storageDescriptors Describes how the scan should be stored.
-     */
-    public TruncatedFilter(ScanFilter filter, List<ResultStorageDescriptor> storageDescriptors) {
-        mFilter = filter;
-        mStorageDescriptors = storageDescriptors;
-    }
-
-    /**
-     * Returns the scan filter.
-     */
-    public ScanFilter getFilter() {
-        return mFilter;
-    }
-
-    /**
-     * Returns a list of descriptor for scan result storage.
-     */
-    public List<ResultStorageDescriptor> getStorageDescriptors() {
-        return mStorageDescriptors;
-    }
-
-
-}
diff --git a/core/java/android/bluetooth/package.html b/core/java/android/bluetooth/package.html
deleted file mode 100644
index d9ca4f1..0000000
--- a/core/java/android/bluetooth/package.html
+++ /dev/null
@@ -1,38 +0,0 @@
-<HTML>
-<BODY>
-<p>Provides classes that manage Bluetooth functionality, such as scanning for
-devices, connecting with devices, and managing data transfer between devices.
-The Bluetooth API supports both "Classic Bluetooth" and Bluetooth Low Energy.</p>
-
-<p>For more information about Classic Bluetooth, see the
-<a href="{@docRoot}guide/topics/connectivity/bluetooth.html">Bluetooth</a> guide.
-For more information about Bluetooth Low Energy, see the
-<a href="{@docRoot}guide/topics/connectivity/bluetooth-le.html">
-Bluetooth Low Energy</a> (BLE) guide.</p>
-{@more}
-
-<p>The Bluetooth APIs let applications:</p>
-<ul>
-  <li>Scan for other Bluetooth devices (including BLE devices).</li>
-  <li>Query the local Bluetooth adapter for paired Bluetooth devices.</li>
-  <li>Establish RFCOMM channels/sockets.</li>
-  <li>Connect to specified sockets on other devices.</li>
-  <li>Transfer data to and from other devices.</li>
-  <li>Communicate with BLE devices, such as proximity sensors, heart rate
-    monitors, fitness devices, and so on.</li>
-  <li>Act as a GATT client or a GATT server (BLE).</li>
-</ul>
-
-<p>
-To perform Bluetooth communication using these APIs, an application must
-declare the {@link android.Manifest.permission#BLUETOOTH} permission. Some
-additional functionality, such as requesting device discovery,
-also requires the {@link android.Manifest.permission#BLUETOOTH_ADMIN}
-permission.
-</p>
-
-<p class="note"><strong>Note:</strong>
-Not all Android-powered devices provide Bluetooth functionality.</p>
-
-</BODY>
-</HTML>
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 2ed00b5..7cd7e7ac 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -2485,6 +2485,8 @@
      * API shipped in Android 11.
      * <li><code>202101</code>: corresponds to the features included in the Identity Credential
      * API shipped in Android 12.
+     * <li><code>202201</code>: corresponds to the features included in the Identity Credential
+     * API shipped in Android 13.
      * </ul>
      */
     @SdkConstant(SdkConstantType.FEATURE)
diff --git a/core/java/android/content/res/ColorStateList.java b/core/java/android/content/res/ColorStateList.java
index 5b727cc..5031faa 100644
--- a/core/java/android/content/res/ColorStateList.java
+++ b/core/java/android/content/res/ColorStateList.java
@@ -198,7 +198,7 @@
             // Prune the cache before adding new items.
             final int N = sCache.size();
             for (int i = N - 1; i >= 0; i--) {
-                if (sCache.valueAt(i).get() == null) {
+                if (sCache.valueAt(i).refersTo(null)) {
                     sCache.removeAt(i);
                 }
             }
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index 12e41e2..932cc8e 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -2011,7 +2011,7 @@
 
             // Clean up references to garbage collected themes
             if (mThemeRefs.size() > mThemeRefsNextFlushSize) {
-                mThemeRefs.removeIf(ref -> ref.get() == null);
+                mThemeRefs.removeIf(ref -> ref.refersTo(null));
                 mThemeRefsNextFlushSize = Math.max(MIN_THEME_REFS_FLUSH_SIZE,
                         2 * mThemeRefs.size());
             }
diff --git a/core/java/android/content/res/loader/ResourcesLoader.java b/core/java/android/content/res/loader/ResourcesLoader.java
index c308400..cf6e166 100644
--- a/core/java/android/content/res/loader/ResourcesLoader.java
+++ b/core/java/android/content/res/loader/ResourcesLoader.java
@@ -257,7 +257,7 @@
 
         for (int i = mChangeCallbacks.size() - 1; i >= 0; i--) {
             final WeakReference<Object> key = mChangeCallbacks.keyAt(i);
-            if (key.get() == null) {
+            if (key.refersTo(null)) {
                 mChangeCallbacks.removeAt(i);
             } else {
                 uniqueCallbacks.add(mChangeCallbacks.valueAt(i));
diff --git a/core/java/android/hardware/ISerialManager.aidl b/core/java/android/hardware/ISerialManager.aidl
index 74d30f7..65a0fa4 100644
--- a/core/java/android/hardware/ISerialManager.aidl
+++ b/core/java/android/hardware/ISerialManager.aidl
@@ -22,8 +22,10 @@
 interface ISerialManager
 {
     /* Returns a list of all available serial ports */
+    @EnforcePermission("SERIAL_PORT")
     String[] getSerialPorts();
 
     /* Returns a file descriptor for the serial port. */
+    @EnforcePermission("SERIAL_PORT")
     ParcelFileDescriptor openSerialPort(String name);
 }
diff --git a/core/java/android/hardware/biometrics/BiometricPrompt.java b/core/java/android/hardware/biometrics/BiometricPrompt.java
index c8c122d..9fb70d6 100644
--- a/core/java/android/hardware/biometrics/BiometricPrompt.java
+++ b/core/java/android/hardware/biometrics/BiometricPrompt.java
@@ -38,6 +38,7 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.security.identity.IdentityCredential;
+import android.security.identity.PresentationSession;
 import android.security.keystore.KeyProperties;
 import android.text.TextUtils;
 import android.util.Log;
@@ -653,8 +654,8 @@
     /**
      * A wrapper class for the cryptographic operations supported by BiometricPrompt.
      *
-     * <p>Currently the framework supports {@link Signature}, {@link Cipher}, {@link Mac}, and
-     * {@link IdentityCredential}.
+     * <p>Currently the framework supports {@link Signature}, {@link Cipher}, {@link Mac},
+     * {@link IdentityCredential}, and {@link PresentationSession}.
      *
      * <p>Cryptographic operations in Android can be split into two categories: auth-per-use and
      * time-based. This is specified during key creation via the timeout parameter of the
@@ -684,10 +685,21 @@
             super(mac);
         }
 
+        /**
+         * Create from a {@link IdentityCredential} object.
+         *
+         * @param credential a {@link IdentityCredential} object.
+         * @deprecated Use {@link PresentationSession} instead of {@link IdentityCredential}.
+         */
+        @Deprecated
         public CryptoObject(@NonNull IdentityCredential credential) {
             super(credential);
         }
 
+        public CryptoObject(@NonNull PresentationSession session) {
+            super(session);
+        }
+
         /**
          * Get {@link Signature} object.
          * @return {@link Signature} object or null if this doesn't contain one.
@@ -715,10 +727,20 @@
         /**
          * Get {@link IdentityCredential} object.
          * @return {@link IdentityCredential} object or null if this doesn't contain one.
+         * @deprecated Use {@link PresentationSession} instead of {@link IdentityCredential}.
          */
+        @Deprecated
         public @Nullable IdentityCredential getIdentityCredential() {
             return super.getIdentityCredential();
         }
+
+        /**
+         * Get {@link PresentationSession} object.
+         * @return {@link PresentationSession} object or null if this doesn't contain one.
+         */
+        public @Nullable PresentationSession getPresentationSession() {
+            return super.getPresentationSession();
+        }
     }
 
     /**
diff --git a/core/java/android/hardware/biometrics/CryptoObject.java b/core/java/android/hardware/biometrics/CryptoObject.java
index 7648cf2..d415706 100644
--- a/core/java/android/hardware/biometrics/CryptoObject.java
+++ b/core/java/android/hardware/biometrics/CryptoObject.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.security.identity.IdentityCredential;
+import android.security.identity.PresentationSession;
 import android.security.keystore2.AndroidKeyStoreProvider;
 
 import java.security.Signature;
@@ -27,8 +28,8 @@
 
 /**
  * A wrapper class for the crypto objects supported by BiometricPrompt and FingerprintManager.
- * Currently the framework supports {@link Signature}, {@link Cipher}, {@link Mac} and
- * {@link IdentityCredential} objects.
+ * Currently the framework supports {@link Signature}, {@link Cipher}, {@link Mac},
+ * {@link IdentityCredential}, and {@link PresentationSession} objects.
  * @hide
  */
 public class CryptoObject {
@@ -46,10 +47,21 @@
         mCrypto = mac;
     }
 
+    /**
+     * Create from a {@link IdentityCredential} object.
+     *
+     * @param credential a {@link IdentityCredential} object.
+     * @deprecated Use {@link PresentationSession} instead of {@link IdentityCredential}.
+     */
+    @Deprecated
     public CryptoObject(@NonNull IdentityCredential credential) {
         mCrypto = credential;
     }
 
+    public CryptoObject(@NonNull PresentationSession session) {
+        mCrypto = session;
+    }
+
     /**
      * Get {@link Signature} object.
      * @return {@link Signature} object or null if this doesn't contain one.
@@ -77,12 +89,22 @@
     /**
      * Get {@link IdentityCredential} object.
      * @return {@link IdentityCredential} object or null if this doesn't contain one.
+     * @deprecated Use {@link PresentationSession} instead of {@link IdentityCredential}.
      */
+    @Deprecated
     public IdentityCredential getIdentityCredential() {
         return mCrypto instanceof IdentityCredential ? (IdentityCredential) mCrypto : null;
     }
 
     /**
+     * Get {@link PresentationSession} object.
+     * @return {@link PresentationSession} object or null if this doesn't contain one.
+     */
+    public PresentationSession getPresentationSession() {
+        return mCrypto instanceof PresentationSession ? (PresentationSession) mCrypto : null;
+    }
+
+    /**
      * @hide
      * @return the opId associated with this object or 0 if none
      */
@@ -91,6 +113,8 @@
             return 0;
         } else if (mCrypto instanceof IdentityCredential) {
             return ((IdentityCredential) mCrypto).getCredstoreOperationHandle();
+        } else if (mCrypto instanceof PresentationSession) {
+            return ((PresentationSession) mCrypto).getCredstoreOperationHandle();
         }
         return AndroidKeyStoreProvider.getKeyStoreOperationHandle(mCrypto);
     }
diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java
index a3d595c..480923e 100644
--- a/core/java/android/hardware/fingerprint/FingerprintManager.java
+++ b/core/java/android/hardware/fingerprint/FingerprintManager.java
@@ -58,6 +58,7 @@
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.security.identity.IdentityCredential;
+import android.security.identity.PresentationSession;
 import android.util.Slog;
 import android.view.Surface;
 
@@ -264,10 +265,21 @@
          * Get {@link IdentityCredential} object.
          * @return {@link IdentityCredential} object or null if this doesn't contain one.
          * @hide
+         * @deprecated Use {@link PresentationSession} instead of {@link IdentityCredential}.
          */
+        @Deprecated
         public IdentityCredential getIdentityCredential() {
             return super.getIdentityCredential();
         }
+
+        /**
+         * Get {@link PresentationSession} object.
+         * @return {@link PresentationSession} object or null if this doesn't contain one.
+         * @hide
+         */
+        public PresentationSession getPresentationSession() {
+            return super.getPresentationSession();
+        }
     }
 
     /**
diff --git a/core/java/android/net/INetworkPolicyManager.aidl b/core/java/android/net/INetworkPolicyManager.aidl
index f50aa99..6284f56 100644
--- a/core/java/android/net/INetworkPolicyManager.aidl
+++ b/core/java/android/net/INetworkPolicyManager.aidl
@@ -69,6 +69,8 @@
 
     int getMultipathPreference(in Network network);
 
+    SubscriptionPlan getSubscriptionPlan(in NetworkTemplate template);
+    void notifyStatsProviderWarningOrLimitReached();
     SubscriptionPlan[] getSubscriptionPlans(int subId, String callingPackage);
     void setSubscriptionPlans(int subId, in SubscriptionPlan[] plans, String callingPackage);
     String getSubscriptionPlansOwner(int subId);
diff --git a/core/java/android/net/LocalServerSocket.java b/core/java/android/net/LocalServerSocket.java
index d1f49d2..506cbcb 100644
--- a/core/java/android/net/LocalServerSocket.java
+++ b/core/java/android/net/LocalServerSocket.java
@@ -55,7 +55,9 @@
      * Create a LocalServerSocket from a file descriptor that's already
      * been created and bound. listen() will be called immediately on it.
      * Used for cases where file descriptors are passed in via environment
-     * variables
+     * variables. The passed-in FileDescriptor is not managed by this class
+     * and must be closed by the caller. Calling {@link #close()} on a socket
+     * created by this method has no effect.
      *
      * @param fd bound file descriptor
      * @throws IOException
diff --git a/core/java/android/net/LocalSocket.java b/core/java/android/net/LocalSocket.java
index 5b38f78..b69410c 100644
--- a/core/java/android/net/LocalSocket.java
+++ b/core/java/android/net/LocalSocket.java
@@ -16,7 +16,14 @@
 
 package android.net;
 
+import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
+
+import android.annotation.NonNull;
+import android.annotation.SuppressLint;
+import android.annotation.SystemApi;
 import android.compat.annotation.UnsupportedAppUsage;
+import android.system.ErrnoException;
+import android.system.Os;
 
 import java.io.Closeable;
 import java.io.FileDescriptor;
@@ -74,32 +81,39 @@
         this.isBound = false;
     }
 
+    private void checkConnected() {
+        try {
+            Os.getpeername(impl.getFileDescriptor());
+        } catch (ErrnoException e) {
+            throw new IllegalArgumentException("Not a connected socket", e);
+        }
+        isConnected = true;
+        isBound = true;
+        implCreated = true;
+    }
+
     /**
-     * Creates a LocalSocket instances using the FileDescriptor for an already-connected
-     * AF_LOCAL/UNIX domain stream socket. Note: the FileDescriptor must be closed by the caller:
-     * closing the LocalSocket will not close it.
+     * Creates a LocalSocket instance using the {@link FileDescriptor} for an already-connected
+     * AF_LOCAL/UNIX domain stream socket. The passed-in FileDescriptor is not managed by this class
+     * and must be closed by the caller. Calling {@link #close()} on a socket created by this
+     * method has no effect.
      *
-     * @hide - used by BluetoothSocket.
+     * @param fd the filedescriptor to adopt
+     *
+     * @hide
      */
-    public static LocalSocket createConnectedLocalSocket(FileDescriptor fd) {
-        return createConnectedLocalSocket(new LocalSocketImpl(fd), SOCKET_UNKNOWN);
+    @SystemApi(client = MODULE_LIBRARIES)
+    public LocalSocket(@NonNull @SuppressLint("UseParcelFileDescriptor") FileDescriptor fd) {
+        this(new LocalSocketImpl(fd), SOCKET_UNKNOWN);
+        checkConnected();
     }
 
     /**
      * for use with LocalServerSocket.accept()
      */
     static LocalSocket createLocalSocketForAccept(LocalSocketImpl impl) {
-        return createConnectedLocalSocket(impl, SOCKET_UNKNOWN);
-    }
-
-    /**
-     * Creates a LocalSocket from an existing LocalSocketImpl that is already connected.
-     */
-    private static LocalSocket createConnectedLocalSocket(LocalSocketImpl impl, int sockType) {
-        LocalSocket socket = new LocalSocket(impl, sockType);
-        socket.isConnected = true;
-        socket.isBound = true;
-        socket.implCreated = true;
+        LocalSocket socket = new LocalSocket(impl, SOCKET_UNKNOWN);
+        socket.checkConnected();
         return socket;
     }
 
diff --git a/core/java/android/net/NetworkPolicyManager.java b/core/java/android/net/NetworkPolicyManager.java
index 7ebb646..c936bfa 100644
--- a/core/java/android/net/NetworkPolicyManager.java
+++ b/core/java/android/net/NetworkPolicyManager.java
@@ -535,6 +535,46 @@
     }
 
     /**
+     * Get subscription plan for the given networkTemplate.
+     *
+     * @param template the networkTemplate to get the subscription plan for.
+     * @return the active {@link SubscriptionPlan} for the given template, or
+     *         {@code null} if not found.
+     * @hide
+     */
+    @Nullable
+    @RequiresPermission(anyOf = {
+            NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
+            android.Manifest.permission.NETWORK_STACK})
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public SubscriptionPlan getSubscriptionPlan(@NonNull NetworkTemplate template) {
+        try {
+            return mService.getSubscriptionPlan(template);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Notifies that the specified {@link NetworkStatsProvider} has reached its quota
+     * which was set through {@link NetworkStatsProvider#onSetLimit(String, long)} or
+     * {@link NetworkStatsProvider#onSetWarningAndLimit(String, long, long)}.
+     *
+     * @hide
+     */
+    @RequiresPermission(anyOf = {
+            NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
+            android.Manifest.permission.NETWORK_STACK})
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public void notifyStatsProviderWarningOrLimitReached() {
+        try {
+            mService.notifyStatsProviderWarningOrLimitReached();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Resets network policy settings back to factory defaults.
      *
      * @hide
diff --git a/core/java/android/net/PrivateDnsConnectivityChecker.java b/core/java/android/net/PrivateDnsConnectivityChecker.java
index cfd458c..ac97b36 100644
--- a/core/java/android/net/PrivateDnsConnectivityChecker.java
+++ b/core/java/android/net/PrivateDnsConnectivityChecker.java
@@ -44,7 +44,7 @@
      */
     public static boolean canConnectToPrivateDnsServer(@NonNull String hostname) {
         final SocketFactory factory = SSLSocketFactory.getDefault();
-        TrafficStats.setThreadStatsTag(TrafficStats.TAG_SYSTEM_APP);
+        TrafficStats.setThreadStatsTagApp();
 
         try (SSLSocket socket = (SSLSocket) factory.createSocket()) {
             socket.setSoTimeout(CONNECTION_TIMEOUT_MS);
diff --git a/core/java/android/net/VpnManager.java b/core/java/android/net/VpnManager.java
index 5c28553..3193826 100644
--- a/core/java/android/net/VpnManager.java
+++ b/core/java/android/net/VpnManager.java
@@ -96,6 +96,141 @@
      */
     public static final String NOTIFICATION_CHANNEL_VPN = "VPN";
 
+    /**
+     * Action sent in the intent when an error occurred.
+     *
+     * @hide
+     */
+    public static final String ACTION_VPN_MANAGER_ERROR = "android.net.action.VPN_MANAGER_ERROR";
+
+    /**
+     * An IKE protocol error. Codes are the codes from IkeProtocolException, RFC 7296.
+     *
+     * @hide
+     */
+    public static final String CATEGORY_ERROR_IKE = "android.net.category.ERROR_IKE";
+
+    /**
+     * User deactivated the VPN, either by turning it off or selecting a different VPN provider.
+     * The error code is always 0.
+     *
+     * @hide
+     */
+    public static final String CATEGORY_ERROR_USER_DEACTIVATED =
+            "android.net.category.ERROR_USER_DEACTIVATED";
+
+    /**
+     * Network error. Error codes are ERROR_CODE_NETWORK_*.
+     *
+     * @hide
+     */
+    public static final String CATEGORY_ERROR_NETWORK = "android.net.category.ERROR_NETWORK";
+
+    /**
+     * The key of the session that experienced this error, as returned by
+     * startProvisionedVpnProfileSession.
+     *
+     * @hide
+     */
+    public static final String EXTRA_SESSION_KEY = "android.net.extra.SESSION_KEY";
+
+    /**
+     * Extra for the Network object that was the underlying network at the time of the failure, or
+     * null if none.
+     *
+     * @hide
+     */
+    public static final String EXTRA_UNDERLYING_NETWORK = "android.net.extra.UNDERLYING_NETWORK";
+
+    /**
+     * The NetworkCapabilities of the underlying network.
+     *
+     * @hide
+     */
+    public static final String EXTRA_UNDERLYING_NETWORK_CAPABILITIES =
+            "android.net.extra.UNDERLYING_NETWORK_CAPABILITIES";
+
+    /**
+     * The LinkProperties of the underlying network.
+     *
+     * @hide
+     */
+    public static final String EXTRA_UNDERLYING_LINK_PROPERTIES =
+            "android.net.extra.UNDERLYING_LINK_PROPERTIES";
+
+    /**
+     * A long timestamp with SystemClock.elapsedRealtime base for when the event happened.
+     *
+     * @hide
+     */
+    public static final String EXTRA_TIMESTAMP = "android.net.extra.TIMESTAMP";
+
+    /**
+     * Extra for the error type. This is ERROR_NOT_RECOVERABLE or ERROR_RECOVERABLE.
+     *
+     * @hide
+     */
+    public static final String EXTRA_ERROR_TYPE = "android.net.extra.ERROR_TYPE";
+
+    /**
+     * Extra for the error code. The value will be 0 for CATEGORY_ERROR_USER_DEACTIVATED, one of
+     * ERROR_CODE_NETWORK_* for ERROR_CATEGORY_NETWORK or one of values defined in
+     * IkeProtocolException#ErrorType for CATEGORY_ERROR_IKE.
+     *
+     * @hide
+     */
+    public static final String EXTRA_ERROR_CODE = "android.net.extra.ERROR_CODE";
+
+    /**
+     * This error is fatal, e.g. the VPN was disabled or configuration error. The stack will not
+     * retry connection.
+     *
+     * @hide
+     */
+    public static final int ERROR_NOT_RECOVERABLE = 1;
+
+    /**
+     * The stack experienced an error but will retry with exponential backoff, e.g. network timeout.
+     *
+     * @hide
+     */
+    public static final int ERROR_RECOVERABLE = 2;
+
+    /**
+     * An error code to indicate that there was an UnknownHostException.
+     *
+     * @hide
+     */
+    public static final int ERROR_CODE_NETWORK_UNKNOWN_HOST = 0;
+
+    /**
+     * An error code to indicate that there is a SocketTimeoutException.
+     *
+     * @hide
+     */
+    public static final int ERROR_CODE_NETWORK_TIMEOUT = 1;
+
+    /**
+     * An error code to indicate that the connection is refused.
+     *
+     * @hide
+     */
+    public static final int ERROR_CODE_NETWORK_CONNECT = 2;
+
+    /**
+     * An error code to indicate the connection was reset. (e.g. SocketException)
+     *
+     * @hide
+     */
+    public static final int ERROR_CODE_NETWORK_CONNECTION_RESET = 3;
+
+    /**
+     * An error code to indicate that there is an IOException.
+     *
+     * @hide
+     */
+    public static final int ERROR_CODE_NETWORK_IO = 4;
+
     /** @hide */
     @IntDef(value = {TYPE_VPN_NONE, TYPE_VPN_SERVICE, TYPE_VPN_PLATFORM, TYPE_VPN_LEGACY,
             TYPE_VPN_OEM})
diff --git a/core/java/android/net/annotations/PolicyDirection.java b/core/java/android/net/annotations/PolicyDirection.java
index febd9b4..3f7521a 100644
--- a/core/java/android/net/annotations/PolicyDirection.java
+++ b/core/java/android/net/annotations/PolicyDirection.java
@@ -24,10 +24,6 @@
 
 /**
  * IPsec traffic direction.
- *
- * <p>Mainline modules cannot reference hidden @IntDef. Moving this annotation to a separate class
- * to allow others to statically include it.
- *
  * @hide
  */
 @IntDef(value = {IpSecManager.DIRECTION_IN, IpSecManager.DIRECTION_OUT})
diff --git a/core/java/android/net/vcn/VcnCellUnderlyingNetworkTemplate.java b/core/java/android/net/vcn/VcnCellUnderlyingNetworkTemplate.java
index 125b573..69e6313 100644
--- a/core/java/android/net/vcn/VcnCellUnderlyingNetworkTemplate.java
+++ b/core/java/android/net/vcn/VcnCellUnderlyingNetworkTemplate.java
@@ -63,13 +63,22 @@
     private final int mOpportunisticMatchCriteria;
 
     private VcnCellUnderlyingNetworkTemplate(
-            int networkQuality,
             int meteredMatchCriteria,
+            int minEntryUpstreamBandwidthKbps,
+            int minExitUpstreamBandwidthKbps,
+            int minEntryDownstreamBandwidthKbps,
+            int minExitDownstreamBandwidthKbps,
             Set<String> allowedNetworkPlmnIds,
             Set<Integer> allowedSpecificCarrierIds,
             int roamingMatchCriteria,
             int opportunisticMatchCriteria) {
-        super(NETWORK_PRIORITY_TYPE_CELL, networkQuality, meteredMatchCriteria);
+        super(
+                NETWORK_PRIORITY_TYPE_CELL,
+                meteredMatchCriteria,
+                minEntryUpstreamBandwidthKbps,
+                minExitUpstreamBandwidthKbps,
+                minEntryDownstreamBandwidthKbps,
+                minExitDownstreamBandwidthKbps);
         mAllowedNetworkPlmnIds = new ArraySet<>(allowedNetworkPlmnIds);
         mAllowedSpecificCarrierIds = new ArraySet<>(allowedSpecificCarrierIds);
         mRoamingMatchCriteria = roamingMatchCriteria;
@@ -109,9 +118,17 @@
             @NonNull PersistableBundle in) {
         Objects.requireNonNull(in, "PersistableBundle is null");
 
-        final int networkQuality = in.getInt(NETWORK_QUALITY_KEY);
         final int meteredMatchCriteria = in.getInt(METERED_MATCH_KEY);
 
+        final int minEntryUpstreamBandwidthKbps =
+                in.getInt(MIN_ENTRY_UPSTREAM_BANDWIDTH_KBPS_KEY, DEFAULT_MIN_BANDWIDTH_KBPS);
+        final int minExitUpstreamBandwidthKbps =
+                in.getInt(MIN_EXIT_UPSTREAM_BANDWIDTH_KBPS_KEY, DEFAULT_MIN_BANDWIDTH_KBPS);
+        final int minEntryDownstreamBandwidthKbps =
+                in.getInt(MIN_ENTRY_DOWNSTREAM_BANDWIDTH_KBPS_KEY, DEFAULT_MIN_BANDWIDTH_KBPS);
+        final int minExitDownstreamBandwidthKbps =
+                in.getInt(MIN_EXIT_DOWNSTREAM_BANDWIDTH_KBPS_KEY, DEFAULT_MIN_BANDWIDTH_KBPS);
+
         final PersistableBundle plmnIdsBundle =
                 in.getPersistableBundle(ALLOWED_NETWORK_PLMN_IDS_KEY);
         Objects.requireNonNull(plmnIdsBundle, "plmnIdsBundle is null");
@@ -131,8 +148,11 @@
         final int opportunisticMatchCriteria = in.getInt(OPPORTUNISTIC_MATCH_KEY);
 
         return new VcnCellUnderlyingNetworkTemplate(
-                networkQuality,
                 meteredMatchCriteria,
+                minEntryUpstreamBandwidthKbps,
+                minExitUpstreamBandwidthKbps,
+                minEntryDownstreamBandwidthKbps,
+                minExitDownstreamBandwidthKbps,
                 allowedNetworkPlmnIds,
                 allowedSpecificCarrierIds,
                 roamingMatchCriteria,
@@ -243,7 +263,6 @@
 
     /** This class is used to incrementally build VcnCellUnderlyingNetworkTemplate objects. */
     public static final class Builder {
-        private int mNetworkQuality = NETWORK_QUALITY_ANY;
         private int mMeteredMatchCriteria = MATCH_ANY;
 
         @NonNull private final Set<String> mAllowedNetworkPlmnIds = new ArraySet<>();
@@ -252,29 +271,15 @@
         private int mRoamingMatchCriteria = MATCH_ANY;
         private int mOpportunisticMatchCriteria = MATCH_ANY;
 
+        private int mMinEntryUpstreamBandwidthKbps = DEFAULT_MIN_BANDWIDTH_KBPS;
+        private int mMinExitUpstreamBandwidthKbps = DEFAULT_MIN_BANDWIDTH_KBPS;
+        private int mMinEntryDownstreamBandwidthKbps = DEFAULT_MIN_BANDWIDTH_KBPS;
+        private int mMinExitDownstreamBandwidthKbps = DEFAULT_MIN_BANDWIDTH_KBPS;
+
         /** Construct a Builder object. */
         public Builder() {}
 
         /**
-         * Set the required network quality to match this template.
-         *
-         * <p>Network quality is a aggregation of multiple signals that reflect the network link
-         * metrics. For example, the network validation bit (see {@link
-         * NetworkCapabilities#NET_CAPABILITY_VALIDATED}), estimated first hop transport bandwidth
-         * and signal strength.
-         *
-         * @param networkQuality the required network quality. Defaults to NETWORK_QUALITY_ANY
-         * @hide
-         */
-        @NonNull
-        public Builder setNetworkQuality(@NetworkQuality int networkQuality) {
-            validateNetworkQuality(networkQuality);
-
-            mNetworkQuality = networkQuality;
-            return this;
-        }
-
-        /**
          * Set the matching criteria for metered networks.
          *
          * <p>A template where setMetered(MATCH_REQUIRED) will only match metered networks (one
@@ -369,12 +374,92 @@
             return this;
         }
 
+        /**
+         * Set the minimum upstream bandwidths that this template will match.
+         *
+         * <p>This template will not match a network that does not provide at least the bandwidth
+         * passed as the entry bandwidth, except in the case that the network is selected as the VCN
+         * Gateway Connection's underlying network, where it will continue to match until the
+         * bandwidth drops under the exit bandwidth.
+         *
+         * <p>The entry criteria MUST be greater than, or equal to the exit criteria to avoid the
+         * invalid case where a network fulfills the entry criteria, but at the same time fails the
+         * exit criteria.
+         *
+         * <p>Estimated bandwidth of a network is provided by the transport layer, and reported in
+         * {@link NetworkCapabilities}. The provided estimates will be used without modification.
+         *
+         * @param minEntryUpstreamBandwidthKbps the minimum accepted upstream bandwidth for networks
+         *     that ARE NOT the already-selected underlying network, or {@code 0} to disable this
+         *     requirement. Disabled by default.
+         * @param minExitUpstreamBandwidthKbps the minimum accepted upstream bandwidth for a network
+         *     that IS the already-selected underlying network, or {@code 0} to disable this
+         *     requirement. Disabled by default.
+         * @return this {@link Builder} instance, for chaining
+         */
+        @NonNull
+        // The getter for the two integers are separated, and in the superclass. Please see {@link
+        // VcnUnderlyingNetworkTemplate#getMinEntryUpstreamBandwidthKbps()} and {@link
+        // VcnUnderlyingNetworkTemplate#getMinExitUpstreamBandwidthKbps()}
+        @SuppressLint("MissingGetterMatchingBuilder")
+        public Builder setMinUpstreamBandwidthKbps(
+                int minEntryUpstreamBandwidthKbps, int minExitUpstreamBandwidthKbps) {
+            validateMinBandwidthKbps(minEntryUpstreamBandwidthKbps, minExitUpstreamBandwidthKbps);
+
+            mMinEntryUpstreamBandwidthKbps = minEntryUpstreamBandwidthKbps;
+            mMinExitUpstreamBandwidthKbps = minExitUpstreamBandwidthKbps;
+
+            return this;
+        }
+
+        /**
+         * Set the minimum upstream bandwidths that this template will match.
+         *
+         * <p>This template will not match a network that does not provide at least the bandwidth
+         * passed as the entry bandwidth, except in the case that the network is selected as the VCN
+         * Gateway Connection's underlying network, where it will continue to match until the
+         * bandwidth drops under the exit bandwidth.
+         *
+         * <p>The entry criteria MUST be greater than, or equal to the exit criteria to avoid the
+         * invalid case where a network fulfills the entry criteria, but at the same time fails the
+         * exit criteria.
+         *
+         * <p>Estimated bandwidth of a network is provided by the transport layer, and reported in
+         * {@link NetworkCapabilities}. The provided estimates will be used without modification.
+         *
+         * @param minEntryDownstreamBandwidthKbps the minimum accepted downstream bandwidth for
+         *     networks that ARE NOT the already-selected underlying network, or {@code 0} to
+         *     disable this requirement. Disabled by default.
+         * @param minExitDownstreamBandwidthKbps the minimum accepted downstream bandwidth for a
+         *     network that IS the already-selected underlying network, or {@code 0} to disable this
+         *     requirement. Disabled by default.
+         * @return this {@link Builder} instance, for chaining
+         */
+        @NonNull
+        // The getter for the two integers are separated, and in the superclass. Please see {@link
+        // VcnUnderlyingNetworkTemplate#getMinEntryDownstreamBandwidthKbps()} and {@link
+        // VcnUnderlyingNetworkTemplate#getMinExitDownstreamBandwidthKbps()}
+        @SuppressLint("MissingGetterMatchingBuilder")
+        public Builder setMinDownstreamBandwidthKbps(
+                int minEntryDownstreamBandwidthKbps, int minExitDownstreamBandwidthKbps) {
+            validateMinBandwidthKbps(
+                    minEntryDownstreamBandwidthKbps, minExitDownstreamBandwidthKbps);
+
+            mMinEntryDownstreamBandwidthKbps = minEntryDownstreamBandwidthKbps;
+            mMinExitDownstreamBandwidthKbps = minExitDownstreamBandwidthKbps;
+
+            return this;
+        }
+
         /** Build the VcnCellUnderlyingNetworkTemplate. */
         @NonNull
         public VcnCellUnderlyingNetworkTemplate build() {
             return new VcnCellUnderlyingNetworkTemplate(
-                    mNetworkQuality,
                     mMeteredMatchCriteria,
+                    mMinEntryUpstreamBandwidthKbps,
+                    mMinExitUpstreamBandwidthKbps,
+                    mMinEntryDownstreamBandwidthKbps,
+                    mMinExitDownstreamBandwidthKbps,
                     mAllowedNetworkPlmnIds,
                     mAllowedSpecificCarrierIds,
                     mRoamingMatchCriteria,
diff --git a/core/java/android/net/vcn/VcnGatewayConnectionConfig.java b/core/java/android/net/vcn/VcnGatewayConnectionConfig.java
index 92956e8..2339656 100644
--- a/core/java/android/net/vcn/VcnGatewayConnectionConfig.java
+++ b/core/java/android/net/vcn/VcnGatewayConnectionConfig.java
@@ -17,7 +17,6 @@
 
 import static android.net.ipsec.ike.IkeSessionParams.IKE_OPTION_MOBIKE;
 import static android.net.vcn.VcnUnderlyingNetworkTemplate.MATCH_REQUIRED;
-import static android.net.vcn.VcnUnderlyingNetworkTemplate.NETWORK_QUALITY_OK;
 
 import static com.android.internal.annotations.VisibleForTesting.Visibility;
 
@@ -169,18 +168,15 @@
     static {
         DEFAULT_UNDERLYING_NETWORK_TEMPLATES.add(
                 new VcnCellUnderlyingNetworkTemplate.Builder()
-                        .setNetworkQuality(NETWORK_QUALITY_OK)
                         .setOpportunistic(MATCH_REQUIRED)
                         .build());
 
         DEFAULT_UNDERLYING_NETWORK_TEMPLATES.add(
                 new VcnWifiUnderlyingNetworkTemplate.Builder()
-                        .setNetworkQuality(NETWORK_QUALITY_OK)
                         .build());
 
         DEFAULT_UNDERLYING_NETWORK_TEMPLATES.add(
                 new VcnCellUnderlyingNetworkTemplate.Builder()
-                        .setNetworkQuality(NETWORK_QUALITY_OK)
                         .build());
     }
 
@@ -553,8 +549,8 @@
          * networks, a network will be chosen arbitrarily amongst the networks matching the highest
          * priority rule.
          *
-         * <p>If all networks fail to match the rules provided, an underlying network will still be
-         * selected (at random if necessary).
+         * <p>If all networks fail to match the rules provided, a carrier-owned underlying network
+         * will still be selected (if available, at random if necessary).
          *
          * @param underlyingNetworkTemplates a list of unique VcnUnderlyingNetworkTemplates that are
          *     ordered from most to least preferred, or an empty list to use the default
diff --git a/core/java/android/net/vcn/VcnUnderlyingNetworkTemplate.java b/core/java/android/net/vcn/VcnUnderlyingNetworkTemplate.java
index 60fc936..3a9ca3e 100644
--- a/core/java/android/net/vcn/VcnUnderlyingNetworkTemplate.java
+++ b/core/java/android/net/vcn/VcnUnderlyingNetworkTemplate.java
@@ -48,23 +48,6 @@
     /** @hide */
     static final int NETWORK_PRIORITY_TYPE_CELL = 2;
 
-    /** Denotes that any network quality is acceptable. @hide */
-    public static final int NETWORK_QUALITY_ANY = 0;
-    /** Denotes that network quality needs to be OK. @hide */
-    public static final int NETWORK_QUALITY_OK = 100000;
-
-    private static final SparseArray<String> NETWORK_QUALITY_TO_STRING_MAP = new SparseArray<>();
-
-    static {
-        NETWORK_QUALITY_TO_STRING_MAP.put(NETWORK_QUALITY_ANY, "NETWORK_QUALITY_ANY");
-        NETWORK_QUALITY_TO_STRING_MAP.put(NETWORK_QUALITY_OK, "NETWORK_QUALITY_OK");
-    }
-
-    /** @hide */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef({NETWORK_QUALITY_OK, NETWORK_QUALITY_ANY})
-    public @interface NetworkQuality {}
-
     /**
      * Used to configure the matching criteria of a network characteristic. This may include network
      * capabilities, or cellular subscription information. Denotes that networks with or without the
@@ -103,44 +86,73 @@
     private final int mNetworkPriorityType;
 
     /** @hide */
-    static final String NETWORK_QUALITY_KEY = "mNetworkQuality";
-
-    private final int mNetworkQuality;
-
-    /** @hide */
     static final String METERED_MATCH_KEY = "mMeteredMatchCriteria";
 
     private final int mMeteredMatchCriteria;
 
     /** @hide */
+    public static final int DEFAULT_MIN_BANDWIDTH_KBPS = 0;
+
+    /** @hide */
+    static final String MIN_ENTRY_UPSTREAM_BANDWIDTH_KBPS_KEY = "mMinEntryUpstreamBandwidthKbps";
+
+    private final int mMinEntryUpstreamBandwidthKbps;
+
+    /** @hide */
+    static final String MIN_EXIT_UPSTREAM_BANDWIDTH_KBPS_KEY = "mMinExitUpstreamBandwidthKbps";
+
+    private final int mMinExitUpstreamBandwidthKbps;
+
+    /** @hide */
+    static final String MIN_ENTRY_DOWNSTREAM_BANDWIDTH_KBPS_KEY =
+            "mMinEntryDownstreamBandwidthKbps";
+
+    private final int mMinEntryDownstreamBandwidthKbps;
+
+    /** @hide */
+    static final String MIN_EXIT_DOWNSTREAM_BANDWIDTH_KBPS_KEY = "mMinExitDownstreamBandwidthKbps";
+
+    private final int mMinExitDownstreamBandwidthKbps;
+
+    /** @hide */
     VcnUnderlyingNetworkTemplate(
-            int networkPriorityType, int networkQuality, int meteredMatchCriteria) {
+            int networkPriorityType,
+            int meteredMatchCriteria,
+            int minEntryUpstreamBandwidthKbps,
+            int minExitUpstreamBandwidthKbps,
+            int minEntryDownstreamBandwidthKbps,
+            int minExitDownstreamBandwidthKbps) {
         mNetworkPriorityType = networkPriorityType;
-        mNetworkQuality = networkQuality;
         mMeteredMatchCriteria = meteredMatchCriteria;
+        mMinEntryUpstreamBandwidthKbps = minEntryUpstreamBandwidthKbps;
+        mMinExitUpstreamBandwidthKbps = minExitUpstreamBandwidthKbps;
+        mMinEntryDownstreamBandwidthKbps = minEntryDownstreamBandwidthKbps;
+        mMinExitDownstreamBandwidthKbps = minExitDownstreamBandwidthKbps;
     }
 
     /** @hide */
-    static void validateNetworkQuality(int networkQuality) {
+    static void validateMatchCriteria(int matchCriteria, String matchingCapability) {
         Preconditions.checkArgument(
-                networkQuality == NETWORK_QUALITY_ANY || networkQuality == NETWORK_QUALITY_OK,
-                "Invalid networkQuality:" + networkQuality);
+                MATCH_CRITERIA_TO_STRING_MAP.contains(matchCriteria),
+                "Invalid matching criteria: " + matchCriteria + " for " + matchingCapability);
     }
 
     /** @hide */
-    static void validateMatchCriteria(int meteredMatchCriteria, String matchingCapability) {
+    static void validateMinBandwidthKbps(int minEntryBandwidth, int minExitBandwidth) {
         Preconditions.checkArgument(
-                MATCH_CRITERIA_TO_STRING_MAP.contains(meteredMatchCriteria),
-                "Invalid matching criteria: "
-                        + meteredMatchCriteria
-                        + " for "
-                        + matchingCapability);
+                minEntryBandwidth >= 0, "Invalid minEntryBandwidth, must be >= 0");
+        Preconditions.checkArgument(
+                minExitBandwidth >= 0, "Invalid minExitBandwidth, must be >= 0");
+        Preconditions.checkArgument(
+                minEntryBandwidth >= minExitBandwidth,
+                "Minimum entry bandwidth must be >= exit bandwidth");
     }
 
     /** @hide */
     protected void validate() {
-        validateNetworkQuality(mNetworkQuality);
         validateMatchCriteria(mMeteredMatchCriteria, "mMeteredMatchCriteria");
+        validateMinBandwidthKbps(mMinEntryUpstreamBandwidthKbps, mMinExitUpstreamBandwidthKbps);
+        validateMinBandwidthKbps(mMinEntryDownstreamBandwidthKbps, mMinExitDownstreamBandwidthKbps);
     }
 
     /** @hide */
@@ -168,15 +180,24 @@
         final PersistableBundle result = new PersistableBundle();
 
         result.putInt(NETWORK_PRIORITY_TYPE_KEY, mNetworkPriorityType);
-        result.putInt(NETWORK_QUALITY_KEY, mNetworkQuality);
         result.putInt(METERED_MATCH_KEY, mMeteredMatchCriteria);
+        result.putInt(MIN_ENTRY_UPSTREAM_BANDWIDTH_KBPS_KEY, mMinEntryUpstreamBandwidthKbps);
+        result.putInt(MIN_EXIT_UPSTREAM_BANDWIDTH_KBPS_KEY, mMinExitUpstreamBandwidthKbps);
+        result.putInt(MIN_ENTRY_DOWNSTREAM_BANDWIDTH_KBPS_KEY, mMinEntryDownstreamBandwidthKbps);
+        result.putInt(MIN_EXIT_DOWNSTREAM_BANDWIDTH_KBPS_KEY, mMinExitDownstreamBandwidthKbps);
 
         return result;
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(mNetworkPriorityType, mNetworkQuality, mMeteredMatchCriteria);
+        return Objects.hash(
+                mNetworkPriorityType,
+                mMeteredMatchCriteria,
+                mMinEntryUpstreamBandwidthKbps,
+                mMinExitUpstreamBandwidthKbps,
+                mMinEntryDownstreamBandwidthKbps,
+                mMinExitDownstreamBandwidthKbps);
     }
 
     @Override
@@ -187,8 +208,11 @@
 
         final VcnUnderlyingNetworkTemplate rhs = (VcnUnderlyingNetworkTemplate) other;
         return mNetworkPriorityType == rhs.mNetworkPriorityType
-                && mNetworkQuality == rhs.mNetworkQuality
-                && mMeteredMatchCriteria == rhs.mMeteredMatchCriteria;
+                && mMeteredMatchCriteria == rhs.mMeteredMatchCriteria
+                && mMinEntryUpstreamBandwidthKbps == rhs.mMinEntryUpstreamBandwidthKbps
+                && mMinExitUpstreamBandwidthKbps == rhs.mMinExitUpstreamBandwidthKbps
+                && mMinEntryDownstreamBandwidthKbps == rhs.mMinEntryDownstreamBandwidthKbps
+                && mMinExitDownstreamBandwidthKbps == rhs.mMinExitDownstreamBandwidthKbps;
     }
 
     /** @hide */
@@ -197,8 +221,8 @@
     }
 
     /** @hide */
-    static String getMatchCriteriaString(int meteredMatchCriteria) {
-        return getNameString(MATCH_CRITERIA_TO_STRING_MAP, meteredMatchCriteria);
+    static String getMatchCriteriaString(int matchCriteria) {
+        return getNameString(MATCH_CRITERIA_TO_STRING_MAP, matchCriteria);
     }
 
     /** @hide */
@@ -213,34 +237,63 @@
         pw.println(this.getClass().getSimpleName() + ":");
         pw.increaseIndent();
 
-        pw.println(
-                "mNetworkQuality: "
-                        + getNameString(NETWORK_QUALITY_TO_STRING_MAP, mNetworkQuality));
         pw.println("mMeteredMatchCriteria: " + getMatchCriteriaString(mMeteredMatchCriteria));
+        pw.println("mMinEntryUpstreamBandwidthKbps: " + mMinEntryUpstreamBandwidthKbps);
+        pw.println("mMinExitUpstreamBandwidthKbps: " + mMinExitUpstreamBandwidthKbps);
+        pw.println("mMinEntryDownstreamBandwidthKbps: " + mMinEntryDownstreamBandwidthKbps);
+        pw.println("mMinExitDownstreamBandwidthKbps: " + mMinExitDownstreamBandwidthKbps);
         dumpTransportSpecificFields(pw);
 
         pw.decreaseIndent();
     }
 
     /**
-     * Retrieve the required network quality to match this template.
-     *
-     * @see Builder#setNetworkQuality(int)
-     * @hide
-     */
-    @NetworkQuality
-    public int getNetworkQuality() {
-        return mNetworkQuality;
-    }
-
-    /**
      * Return the matching criteria for metered networks.
      *
      * @see VcnWifiUnderlyingNetworkTemplate.Builder#setMetered(int)
      * @see VcnCellUnderlyingNetworkTemplate.Builder#setMetered(int)
      */
-    @MatchCriteria
     public int getMetered() {
         return mMeteredMatchCriteria;
     }
+
+    /**
+     * Returns the minimum entry upstream bandwidth allowed by this template.
+     *
+     * @see VcnWifiUnderlyingNetworkTemplate.Builder#setMinUpstreamBandwidthKbps(int, int)
+     * @see VcnCellUnderlyingNetworkTemplate.Builder#setMinUpstreamBandwidthKbps(int, int)
+     */
+    public int getMinEntryUpstreamBandwidthKbps() {
+        return mMinEntryUpstreamBandwidthKbps;
+    }
+
+    /**
+     * Returns the minimum exit upstream bandwidth allowed by this template.
+     *
+     * @see VcnWifiUnderlyingNetworkTemplate.Builder#setMinUpstreamBandwidthKbps(int, int)
+     * @see VcnCellUnderlyingNetworkTemplate.Builder#setMinUpstreamBandwidthKbps(int, int)
+     */
+    public int getMinExitUpstreamBandwidthKbps() {
+        return mMinExitUpstreamBandwidthKbps;
+    }
+
+    /**
+     * Returns the minimum entry downstream bandwidth allowed by this template.
+     *
+     * @see VcnWifiUnderlyingNetworkTemplate.Builder#setMinDownstreamBandwidthKbps(int, int)
+     * @see VcnCellUnderlyingNetworkTemplate.Builder#setMinDownstreamBandwidthKbps(int, int)
+     */
+    public int getMinEntryDownstreamBandwidthKbps() {
+        return mMinEntryDownstreamBandwidthKbps;
+    }
+
+    /**
+     * Returns the minimum exit downstream bandwidth allowed by this template.
+     *
+     * @see VcnWifiUnderlyingNetworkTemplate.Builder#setMinDownstreamBandwidthKbps(int, int)
+     * @see VcnCellUnderlyingNetworkTemplate.Builder#setMinDownstreamBandwidthKbps(int, int)
+     */
+    public int getMinExitDownstreamBandwidthKbps() {
+        return mMinExitDownstreamBandwidthKbps;
+    }
 }
diff --git a/core/java/android/net/vcn/VcnWifiUnderlyingNetworkTemplate.java b/core/java/android/net/vcn/VcnWifiUnderlyingNetworkTemplate.java
index 272ca9d..23a07ab 100644
--- a/core/java/android/net/vcn/VcnWifiUnderlyingNetworkTemplate.java
+++ b/core/java/android/net/vcn/VcnWifiUnderlyingNetworkTemplate.java
@@ -46,8 +46,19 @@
     @Nullable private final Set<String> mSsids;
 
     private VcnWifiUnderlyingNetworkTemplate(
-            int networkQuality, int meteredMatchCriteria, Set<String> ssids) {
-        super(NETWORK_PRIORITY_TYPE_WIFI, networkQuality, meteredMatchCriteria);
+            int meteredMatchCriteria,
+            int minEntryUpstreamBandwidthKbps,
+            int minExitUpstreamBandwidthKbps,
+            int minEntryDownstreamBandwidthKbps,
+            int minExitDownstreamBandwidthKbps,
+            Set<String> ssids) {
+        super(
+                NETWORK_PRIORITY_TYPE_WIFI,
+                meteredMatchCriteria,
+                minEntryUpstreamBandwidthKbps,
+                minExitUpstreamBandwidthKbps,
+                minEntryDownstreamBandwidthKbps,
+                minExitDownstreamBandwidthKbps);
         mSsids = new ArraySet<>(ssids);
 
         validate();
@@ -75,15 +86,29 @@
             @NonNull PersistableBundle in) {
         Objects.requireNonNull(in, "PersistableBundle is null");
 
-        final int networkQuality = in.getInt(NETWORK_QUALITY_KEY);
         final int meteredMatchCriteria = in.getInt(METERED_MATCH_KEY);
 
+        final int minEntryUpstreamBandwidthKbps =
+                in.getInt(MIN_ENTRY_UPSTREAM_BANDWIDTH_KBPS_KEY, DEFAULT_MIN_BANDWIDTH_KBPS);
+        final int minExitUpstreamBandwidthKbps =
+                in.getInt(MIN_EXIT_UPSTREAM_BANDWIDTH_KBPS_KEY, DEFAULT_MIN_BANDWIDTH_KBPS);
+        final int minEntryDownstreamBandwidthKbps =
+                in.getInt(MIN_ENTRY_DOWNSTREAM_BANDWIDTH_KBPS_KEY, DEFAULT_MIN_BANDWIDTH_KBPS);
+        final int minExitDownstreamBandwidthKbps =
+                in.getInt(MIN_EXIT_DOWNSTREAM_BANDWIDTH_KBPS_KEY, DEFAULT_MIN_BANDWIDTH_KBPS);
+
         final PersistableBundle ssidsBundle = in.getPersistableBundle(SSIDS_KEY);
         Objects.requireNonNull(ssidsBundle, "ssidsBundle is null");
         final Set<String> ssids =
                 new ArraySet<String>(
                         PersistableBundleUtils.toList(ssidsBundle, STRING_DESERIALIZER));
-        return new VcnWifiUnderlyingNetworkTemplate(networkQuality, meteredMatchCriteria, ssids);
+        return new VcnWifiUnderlyingNetworkTemplate(
+                meteredMatchCriteria,
+                minEntryUpstreamBandwidthKbps,
+                minExitUpstreamBandwidthKbps,
+                minEntryDownstreamBandwidthKbps,
+                minExitDownstreamBandwidthKbps,
+                ssids);
     }
 
     /** @hide */
@@ -137,33 +162,18 @@
 
     /** This class is used to incrementally build VcnWifiUnderlyingNetworkTemplate objects. */
     public static final class Builder {
-        private int mNetworkQuality = NETWORK_QUALITY_ANY;
         private int mMeteredMatchCriteria = MATCH_ANY;
         @NonNull private final Set<String> mSsids = new ArraySet<>();
 
+        private int mMinEntryUpstreamBandwidthKbps = DEFAULT_MIN_BANDWIDTH_KBPS;
+        private int mMinExitUpstreamBandwidthKbps = DEFAULT_MIN_BANDWIDTH_KBPS;
+        private int mMinEntryDownstreamBandwidthKbps = DEFAULT_MIN_BANDWIDTH_KBPS;
+        private int mMinExitDownstreamBandwidthKbps = DEFAULT_MIN_BANDWIDTH_KBPS;
+
         /** Construct a Builder object. */
         public Builder() {}
 
         /**
-         * Set the required network quality to match this template.
-         *
-         * <p>Network quality is a aggregation of multiple signals that reflect the network link
-         * metrics. For example, the network validation bit (see {@link
-         * NetworkCapabilities#NET_CAPABILITY_VALIDATED}), estimated first hop transport bandwidth
-         * and signal strength.
-         *
-         * @param networkQuality the required network quality. Defaults to NETWORK_QUALITY_ANY
-         * @hide
-         */
-        @NonNull
-        public Builder setNetworkQuality(@NetworkQuality int networkQuality) {
-            validateNetworkQuality(networkQuality);
-
-            mNetworkQuality = networkQuality;
-            return this;
-        }
-
-        /**
          * Set the matching criteria for metered networks.
          *
          * <p>A template where setMetered(MATCH_REQUIRED) will only match metered networks (one
@@ -200,11 +210,93 @@
             return this;
         }
 
+        /**
+         * Set the minimum upstream bandwidths that this template will match.
+         *
+         * <p>This template will not match a network that does not provide at least the bandwidth
+         * passed as the entry bandwidth, except in the case that the network is selected as the VCN
+         * Gateway Connection's underlying network, where it will continue to match until the
+         * bandwidth drops under the exit bandwidth.
+         *
+         * <p>The entry criteria MUST be greater than, or equal to the exit criteria to avoid the
+         * invalid case where a network fulfills the entry criteria, but at the same time fails the
+         * exit criteria.
+         *
+         * <p>Estimated bandwidth of a network is provided by the transport layer, and reported in
+         * {@link NetworkCapabilities}. The provided estimates will be used without modification.
+         *
+         * @param minEntryUpstreamBandwidthKbps the minimum accepted upstream bandwidth for networks
+         *     that ARE NOT the already-selected underlying network, or {@code 0} to disable this
+         *     requirement. Disabled by default.
+         * @param minExitUpstreamBandwidthKbps the minimum accepted upstream bandwidth for a network
+         *     that IS the already-selected underlying network, or {@code 0} to disable this
+         *     requirement. Disabled by default.
+         * @return this {@link Builder} instance, for chaining
+         */
+        @NonNull
+        // The getter for the two integers are separated, and in the superclass. Please see {@link
+        // VcnUnderlyingNetworkTemplate#getMinEntryUpstreamBandwidthKbps()} and {@link
+        // VcnUnderlyingNetworkTemplate#getMinExitUpstreamBandwidthKbps()}
+        @SuppressLint("MissingGetterMatchingBuilder")
+        public Builder setMinUpstreamBandwidthKbps(
+                int minEntryUpstreamBandwidthKbps, int minExitUpstreamBandwidthKbps) {
+            validateMinBandwidthKbps(minEntryUpstreamBandwidthKbps, minExitUpstreamBandwidthKbps);
+
+            mMinEntryUpstreamBandwidthKbps = minEntryUpstreamBandwidthKbps;
+            mMinExitUpstreamBandwidthKbps = minExitUpstreamBandwidthKbps;
+
+            return this;
+        }
+
+        /**
+         * Set the minimum upstream bandwidths that this template will match.
+         *
+         * <p>This template will not match a network that does not provide at least the bandwidth
+         * passed as the entry bandwidth, except in the case that the network is selected as the VCN
+         * Gateway Connection's underlying network, where it will continue to match until the
+         * bandwidth drops under the exit bandwidth.
+         *
+         * <p>The entry criteria MUST be greater than, or equal to the exit criteria to avoid the
+         * invalid case where a network fulfills the entry criteria, but at the same time fails the
+         * exit criteria.
+         *
+         * <p>Estimated bandwidth of a network is provided by the transport layer, and reported in
+         * {@link NetworkCapabilities}. The provided estimates will be used without modification.
+         *
+         * @param minEntryDownstreamBandwidthKbps the minimum accepted downstream bandwidth for
+         *     networks that ARE NOT the already-selected underlying network, or {@code 0} to
+         *     disable this requirement. Disabled by default.
+         * @param minExitDownstreamBandwidthKbps the minimum accepted downstream bandwidth for a
+         *     network that IS the already-selected underlying network, or {@code 0} to disable this
+         *     requirement. Disabled by default.
+         * @return this {@link Builder} instance, for chaining
+         */
+        @NonNull
+        // The getter for the two integers are separated, and in the superclass. Please see {@link
+        // VcnUnderlyingNetworkTemplate#getMinEntryDownstreamBandwidthKbps()} and {@link
+        // VcnUnderlyingNetworkTemplate#getMinExitDownstreamBandwidthKbps()}
+        @SuppressLint("MissingGetterMatchingBuilder")
+        public Builder setMinDownstreamBandwidthKbps(
+                int minEntryDownstreamBandwidthKbps, int minExitDownstreamBandwidthKbps) {
+            validateMinBandwidthKbps(
+                    minEntryDownstreamBandwidthKbps, minExitDownstreamBandwidthKbps);
+
+            mMinEntryDownstreamBandwidthKbps = minEntryDownstreamBandwidthKbps;
+            mMinExitDownstreamBandwidthKbps = minExitDownstreamBandwidthKbps;
+
+            return this;
+        }
+
         /** Build the VcnWifiUnderlyingNetworkTemplate. */
         @NonNull
         public VcnWifiUnderlyingNetworkTemplate build() {
             return new VcnWifiUnderlyingNetworkTemplate(
-                    mNetworkQuality, mMeteredMatchCriteria, mSsids);
+                    mMeteredMatchCriteria,
+                    mMinEntryUpstreamBandwidthKbps,
+                    mMinExitUpstreamBandwidthKbps,
+                    mMinEntryDownstreamBandwidthKbps,
+                    mMinExitDownstreamBandwidthKbps,
+                    mSsids);
         }
     }
 }
diff --git a/core/java/android/os/BatteryUsageStats.java b/core/java/android/os/BatteryUsageStats.java
index 0f94cbe..86e6db1 100644
--- a/core/java/android/os/BatteryUsageStats.java
+++ b/core/java/android/os/BatteryUsageStats.java
@@ -127,6 +127,7 @@
     private final AggregateBatteryConsumer[] mAggregateBatteryConsumers;
     private final Parcel mHistoryBuffer;
     private final List<BatteryStats.HistoryTag> mHistoryTagPool;
+    private final BatteryStatsHistory mBatteryStatsHistory;
 
     private BatteryUsageStats(@NonNull Builder builder) {
         mStatsStartTimestampMs = builder.mStatsStartTimestampMs;
@@ -138,6 +139,7 @@
         mDischargedPowerUpperBound = builder.mDischargedPowerUpperBoundMah;
         mHistoryBuffer = builder.mHistoryBuffer;
         mHistoryTagPool = builder.mHistoryTagPool;
+        mBatteryStatsHistory = builder.mBatteryStatsHistory;
         mBatteryTimeRemainingMs = builder.mBatteryTimeRemainingMs;
         mChargeTimeRemainingMs = builder.mChargeTimeRemainingMs;
         mCustomPowerComponentNames = builder.mCustomPowerComponentNames;
@@ -289,8 +291,8 @@
             throw new IllegalStateException(
                     "Battery history was not requested in the BatteryUsageStatsQuery");
         }
-        return new BatteryStatsHistoryIterator(new BatteryStatsHistory(mHistoryBuffer),
-                mHistoryTagPool);
+
+        return new BatteryStatsHistoryIterator(mBatteryStatsHistory, mHistoryTagPool);
     }
 
     @Override
@@ -356,7 +358,10 @@
                 tag.poolIdx = source.readInt();
                 mHistoryTagPool.add(tag);
             }
+            mBatteryStatsHistory = new BatteryStatsHistory(mHistoryBuffer);
+            mBatteryStatsHistory.readFromBatteryUsageStatsParcel(source);
         } else {
+            mBatteryStatsHistory = null;
             mHistoryBuffer = null;
             mHistoryTagPool = null;
         }
@@ -404,6 +409,7 @@
                 dest.writeInt(tag.uid);
                 dest.writeInt(tag.poolIdx);
             }
+            mBatteryStatsHistory.writeToBatteryUsageStatsParcel(dest);
         } else {
             dest.writeBoolean(false);
         }
@@ -757,6 +763,7 @@
                 new SparseArray<>();
         private Parcel mHistoryBuffer;
         private List<BatteryStats.HistoryTag> mHistoryTagPool;
+        private BatteryStatsHistory mBatteryStatsHistory;
 
         public Builder(@NonNull String[] customPowerComponentNames) {
             this(customPowerComponentNames, false);
@@ -865,10 +872,12 @@
          * Sets the parceled recent history.
          */
         @NonNull
-        public Builder setBatteryHistory(Parcel historyBuffer,
-                List<BatteryStats.HistoryTag> historyTagPool) {
+        public Builder setBatteryHistory(@NonNull Parcel historyBuffer,
+                @NonNull List<BatteryStats.HistoryTag> historyTagPool,
+                @NonNull BatteryStatsHistory batteryStatsHistory) {
             mHistoryBuffer = historyBuffer;
             mHistoryTagPool = historyTagPool;
+            mBatteryStatsHistory = batteryStatsHistory;
             return this;
         }
 
diff --git a/core/java/android/os/BinderProxy.java b/core/java/android/os/BinderProxy.java
index c646623..2a2cbb9 100644
--- a/core/java/android/os/BinderProxy.java
+++ b/core/java/android/os/BinderProxy.java
@@ -116,7 +116,7 @@
             for (ArrayList<WeakReference<BinderProxy>> a : mMainIndexValues) {
                 if (a != null) {
                     for (WeakReference<BinderProxy> ref : a) {
-                        if (ref.get() != null) {
+                        if (!ref.refersTo(null)) {
                             ++size;
                         }
                     }
@@ -187,7 +187,7 @@
             // This ensures that ArrayList size is bounded by the maximum occupancy of
             // that bucket.
             for (int i = 0; i < size; ++i) {
-                if (valueArray.get(i).get() == null) {
+                if (valueArray.get(i).refersTo(null)) {
                     valueArray.set(i, newWr);
                     Long[] keyArray = mMainIndexKeys[myHash];
                     keyArray[i] = key;
@@ -195,7 +195,7 @@
                         // "Randomly" check one of the remaining entries in [i+1, size), so that
                         // needlessly long buckets are eventually pruned.
                         int rnd = Math.floorMod(++mRandom, size - (i + 1));
-                        if (valueArray.get(i + 1 + rnd).get() == null) {
+                        if (valueArray.get(i + 1 + rnd).refersTo(null)) {
                             remove(myHash, i + 1 + rnd);
                         }
                     }
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index 09eac79..ffaff95 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -3704,10 +3704,10 @@
         final int m = list.size();
         int i = 0;
         for (; i < m && i < n; i++) {
-            list.set(i, (T) readParcelableInternal(cl, clazz));
+            list.set(i, readParcelableInternal(cl, clazz));
         }
         for (; i < n; i++) {
-            list.add((T) readParcelableInternal(cl, clazz));
+            list.add(readParcelableInternal(cl, clazz));
         }
         for (; i < m; i++) {
             list.remove(n);
@@ -4210,7 +4210,8 @@
      * trying to instantiate an element.
      */
     @Nullable
-    public <T> T readParcelable(@Nullable ClassLoader loader, @NonNull Class<T> clazz) {
+    public <T extends Parcelable> T readParcelable(@Nullable ClassLoader loader,
+            @NonNull Class<? super T> clazz) {
         Objects.requireNonNull(clazz);
         return readParcelableInternal(loader, clazz);
     }
@@ -4220,7 +4221,8 @@
      */
     @SuppressWarnings("unchecked")
     @Nullable
-    private <T> T readParcelableInternal(@Nullable ClassLoader loader, @Nullable Class<T> clazz) {
+    private <T extends Parcelable> T readParcelableInternal(@Nullable ClassLoader loader,
+            @Nullable Class<? super T> clazz) {
         Parcelable.Creator<?> creator = readParcelableCreatorInternal(loader, clazz);
         if (creator == null) {
             return null;
@@ -4456,7 +4458,8 @@
      * deserializing the object.
      */
     @Nullable
-    public <T> T readSerializable(@Nullable ClassLoader loader, @NonNull Class<T> clazz) {
+    public <T extends Serializable> T readSerializable(@Nullable ClassLoader loader,
+            @NonNull Class<? super T> clazz) {
         Objects.requireNonNull(clazz);
         return readSerializableInternal(
                 loader == null ? getClass().getClassLoader() : loader, clazz);
@@ -4466,8 +4469,8 @@
      * @param clazz The type of the serializable expected or {@code null} for performing no checks
      */
     @Nullable
-    private <T> T readSerializableInternal(@Nullable final ClassLoader loader,
-            @Nullable Class<T> clazz) {
+    private <T extends Serializable> T readSerializableInternal(@Nullable final ClassLoader loader,
+            @Nullable Class<? super T> clazz) {
         String name = readString();
         if (name == null) {
             // For some reason we were unable to read the name of the Serializable (either there
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index 9f37c48..2030571 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -129,6 +129,7 @@
      */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     @TestApi
+    @SystemApi(client = MODULE_LIBRARIES)
     public static final int NFC_UID = 1027;
 
     /**
diff --git a/core/java/android/os/Trace.java b/core/java/android/os/Trace.java
index d974e0c..6b869f1 100644
--- a/core/java/android/os/Trace.java
+++ b/core/java/android/os/Trace.java
@@ -16,7 +16,10 @@
 
 package android.os;
 
+import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
+
 import android.annotation.NonNull;
+import android.annotation.SystemApi;
 import android.compat.annotation.UnsupportedAppUsage;
 
 import dalvik.annotation.optimization.CriticalNative;
@@ -90,6 +93,7 @@
     /** @hide */
     public static final long TRACE_TAG_DATABASE = 1L << 20;
     /** @hide */
+    @SystemApi(client = MODULE_LIBRARIES)
     public static final long TRACE_TAG_NETWORK = 1L << 21;
     /** @hide */
     public static final long TRACE_TAG_ADB = 1L << 22;
@@ -148,6 +152,7 @@
      * @hide
      */
     @UnsupportedAppUsage
+    @SystemApi(client = MODULE_LIBRARIES)
     public static boolean isTagEnabled(long traceTag) {
         long tags = nativeGetEnabledTags();
         return (tags & traceTag) != 0;
@@ -163,7 +168,8 @@
      * @hide
      */
     @UnsupportedAppUsage
-    public static void traceCounter(long traceTag, String counterName, int counterValue) {
+    @SystemApi(client = MODULE_LIBRARIES)
+    public static void traceCounter(long traceTag, @NonNull String counterName, int counterValue) {
         if (isTagEnabled(traceTag)) {
             nativeTraceCounter(traceTag, counterName, counterValue);
         }
@@ -202,7 +208,8 @@
      * @hide
      */
     @UnsupportedAppUsage
-    public static void traceBegin(long traceTag, String methodName) {
+    @SystemApi(client = MODULE_LIBRARIES)
+    public static void traceBegin(long traceTag, @NonNull String methodName) {
         if (isTagEnabled(traceTag)) {
             nativeTraceBegin(traceTag, methodName);
         }
@@ -217,6 +224,7 @@
      * @hide
      */
     @UnsupportedAppUsage
+    @SystemApi(client = MODULE_LIBRARIES)
     public static void traceEnd(long traceTag) {
         if (isTagEnabled(traceTag)) {
             nativeTraceEnd(traceTag);
@@ -237,7 +245,8 @@
      * @hide
      */
     @UnsupportedAppUsage
-    public static void asyncTraceBegin(long traceTag, String methodName, int cookie) {
+    @SystemApi(client = MODULE_LIBRARIES)
+    public static void asyncTraceBegin(long traceTag, @NonNull String methodName, int cookie) {
         if (isTagEnabled(traceTag)) {
             nativeAsyncTraceBegin(traceTag, methodName, cookie);
         }
@@ -255,7 +264,8 @@
      * @hide
      */
     @UnsupportedAppUsage
-    public static void asyncTraceEnd(long traceTag, String methodName, int cookie) {
+    @SystemApi(client = MODULE_LIBRARIES)
+    public static void asyncTraceEnd(long traceTag, @NonNull String methodName, int cookie) {
         if (isTagEnabled(traceTag)) {
             nativeAsyncTraceEnd(traceTag, methodName, cookie);
         }
diff --git a/core/java/android/service/security/attestationverification/OWNERS b/core/java/android/service/security/attestationverification/OWNERS
new file mode 100644
index 0000000..12c9978
--- /dev/null
+++ b/core/java/android/service/security/attestationverification/OWNERS
@@ -0,0 +1 @@
+include platform/frameworks/base:/core/java/android/security/attestationverification/OWNERS
diff --git a/core/java/android/service/wallpapereffectsgeneration/OWNERS b/core/java/android/service/wallpapereffectsgeneration/OWNERS
new file mode 100644
index 0000000..d2d3e2c0
--- /dev/null
+++ b/core/java/android/service/wallpapereffectsgeneration/OWNERS
@@ -0,0 +1,4 @@
+susharon@google.com
+shanh@google.com
+huiwu@google.com
+srazdan@google.com
diff --git a/core/java/android/text/method/TextKeyListener.java b/core/java/android/text/method/TextKeyListener.java
index 9cbda9c..2eb917b 100644
--- a/core/java/android/text/method/TextKeyListener.java
+++ b/core/java/android/text/method/TextKeyListener.java
@@ -306,7 +306,7 @@
 
     /* package */ int getPrefs(Context context) {
         synchronized (this) {
-            if (!mPrefsInited || mResolver.get() == null) {
+            if (!mPrefsInited || mResolver.refersTo(null)) {
                 initPrefs(context);
             }
         }
diff --git a/core/java/com/android/internal/midi/OWNERS b/core/java/com/android/internal/midi/OWNERS
new file mode 100644
index 0000000..af273a6
--- /dev/null
+++ b/core/java/com/android/internal/midi/OWNERS
@@ -0,0 +1 @@
+include /services/midi/OWNERS
diff --git a/core/java/com/android/internal/os/BatteryStatsHistory.java b/core/java/com/android/internal/os/BatteryStatsHistory.java
index 879e0a8..8ebb11d 100644
--- a/core/java/com/android/internal/os/BatteryStatsHistory.java
+++ b/core/java/com/android/internal/os/BatteryStatsHistory.java
@@ -160,6 +160,11 @@
         mHistoryDir = null;
         mHistoryBuffer = historyBuffer;
     }
+
+    public File getHistoryDirectory() {
+        return mHistoryDir;
+    }
+
     /**
      * Set the active file that mHistoryBuffer is backed up into.
      *
@@ -375,12 +380,24 @@
     }
 
     /**
-     * Read all history files and serialize into a big Parcel. This is to send history files to
-     * Settings app since Settings app can not access /data/system directory.
-     * Checkin file also call this method.
+     * Read all history files and serialize into a big Parcel.
+     * Checkin file calls this method.
      * @param out the output parcel
      */
     public void writeToParcel(Parcel out) {
+        writeToParcel(out, false /* useBlobs */);
+    }
+
+    /**
+     * Read all history files and serialize into a big Parcel. This is to send history files to
+     * Settings app since Settings app can not access /data/system directory.
+     * @param out the output parcel
+     */
+    public void writeToBatteryUsageStatsParcel(Parcel out) {
+        writeToParcel(out, true /* useBlobs */);
+    }
+
+    private void writeToParcel(Parcel out, boolean useBlobs) {
         final long start = SystemClock.uptimeMillis();
         out.writeInt(mFileNumbers.size() - 1);
         for(int i = 0;  i < mFileNumbers.size() - 1; i++) {
@@ -391,7 +408,12 @@
             } catch(Exception e) {
                 Slog.e(TAG, "Error reading file "+ file.getBaseFile().getPath(), e);
             }
-            out.writeByteArray(raw);
+            if (useBlobs) {
+                out.writeBlob(raw);
+            } else {
+                // Avoiding blobs in the check-in file for compatibility
+                out.writeByteArray(raw);
+            }
         }
         if (DEBUG) {
             Slog.d(TAG, "writeToParcel duration ms:" + (SystemClock.uptimeMillis() - start));
@@ -399,18 +421,29 @@
     }
 
     /**
-     * This is for Settings app, when Settings app receives big history parcel, it call
-     * this method to parse it into list of parcels.
-     * Checkin file also call this method.
+     * This is for the check-in file, which has all history files embedded.
      * @param in the input parcel.
      */
     public void readFromParcel(Parcel in) {
+        readFromParcel(in, false /* useBlobs */);
+    }
+
+    /**
+     * This is for Settings app, when Settings app receives big history parcel, it calls
+     * this method to parse it into list of parcels.
+     * @param in the input parcel.
+     */
+    public void readFromBatteryUsageStatsParcel(Parcel in) {
+        readFromParcel(in, true /* useBlobs */);
+    }
+
+    private void readFromParcel(Parcel in, boolean useBlobs) {
         final long start = SystemClock.uptimeMillis();
         mHistoryParcels = new ArrayList<>();
         final int count = in.readInt();
         for(int i = 0; i < count; i++) {
-            byte[] temp = in.createByteArray();
-            if (temp.length == 0) {
+            byte[] temp = useBlobs ? in.readBlob() : in.createByteArray();
+            if (temp == null || temp.length == 0) {
                 continue;
             }
             Parcel p = Parcel.obtain();
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 270b5d6..58a0622 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -83,7 +83,6 @@
 import android.util.LongSparseArray;
 import android.util.LongSparseLongArray;
 import android.util.MutableInt;
-import android.util.Pools;
 import android.util.PrintWriterPrinter;
 import android.util.Printer;
 import android.util.Slog;
@@ -136,9 +135,7 @@
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
-import java.util.Objects;
 import java.util.Queue;
-import java.util.Set;
 import java.util.concurrent.Future;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.locks.ReentrantLock;
@@ -1203,12 +1200,21 @@
     }
 
     public BatteryStatsImpl(Clocks clocks) {
+        this(clocks, (File) null);
+    }
+
+    public BatteryStatsImpl(Clocks clocks, File historyDirectory) {
         init(clocks);
         mStartClockTimeMs = clocks.currentTimeMillis();
-        mStatsFile = null;
         mCheckinFile = null;
         mDailyFile = null;
-        mBatteryStatsHistory = new BatteryStatsHistory(mHistoryBuffer);
+        if (historyDirectory == null) {
+            mStatsFile = null;
+            mBatteryStatsHistory = new BatteryStatsHistory(mHistoryBuffer);
+        } else {
+            mStatsFile = new AtomicFile(new File(historyDirectory, "batterystats.bin"));
+            mBatteryStatsHistory = new BatteryStatsHistory(this, historyDirectory, mHistoryBuffer);
+        }
         mHandler = null;
         mPlatformIdleStateCallback = null;
         mMeasuredEnergyRetriever = null;
@@ -11522,8 +11528,6 @@
         }
     }
 
-    private final Pools.Pool<NetworkStats> mNetworkStatsPool = new Pools.SynchronizedPool<>(6);
-
     private final Object mWifiNetworkLock = new Object();
 
     @GuardedBy("mWifiNetworkLock")
@@ -11541,13 +11545,15 @@
     private NetworkStats mLastModemNetworkStats = new NetworkStats(0, -1);
 
     @VisibleForTesting
-    protected NetworkStats readNetworkStatsLocked(@NonNull NetworkStatsManager networkStatsManager,
-            String[] ifaces) {
-        Objects.requireNonNull(networkStatsManager);
-        if (!ArrayUtils.isEmpty(ifaces)) {
-            return networkStatsManager.getDetailedUidStats(Set.of(ifaces));
-        }
-        return null;
+    protected NetworkStats readMobileNetworkStatsLocked(
+            @NonNull NetworkStatsManager networkStatsManager) {
+        return networkStatsManager.getMobileUidStats();
+    }
+
+    @VisibleForTesting
+    protected NetworkStats readWifiNetworkStatsLocked(
+            @NonNull NetworkStatsManager networkStatsManager) {
+        return networkStatsManager.getWifiUidStats();
     }
 
     /**
@@ -11564,21 +11570,15 @@
         // Grab a separate lock to acquire the network stats, which may do I/O.
         NetworkStats delta = null;
         synchronized (mWifiNetworkLock) {
-            final NetworkStats latestStats = readNetworkStatsLocked(networkStatsManager,
-                    mWifiIfaces);
+            final NetworkStats latestStats = readWifiNetworkStatsLocked(networkStatsManager);
             if (latestStats != null) {
-                delta = NetworkStats.subtract(latestStats, mLastWifiNetworkStats, null, null,
-                        mNetworkStatsPool.acquire());
-                mNetworkStatsPool.release(mLastWifiNetworkStats);
+                delta = latestStats.subtract(mLastWifiNetworkStats);
                 mLastWifiNetworkStats = latestStats;
             }
         }
 
         synchronized (this) {
             if (!mOnBatteryInternal || mIgnoreNextExternalStats) {
-                if (delta != null) {
-                    mNetworkStatsPool.release(delta);
-                }
                 if (mIgnoreNextExternalStats) {
                     // TODO: Strictly speaking, we should re-mark all 5 timers for each uid (and the
                     //  global one) here like we do for display. But I'm not sure it's worth the
@@ -11599,61 +11599,60 @@
             long totalTxPackets = 0;
             long totalRxPackets = 0;
             if (delta != null) {
-                NetworkStats.Entry entry = new NetworkStats.Entry();
-                final int size = delta.size();
-                for (int i = 0; i < size; i++) {
-                    entry = delta.getValues(i, entry);
-
+                for (NetworkStats.Entry entry : delta) {
                     if (DEBUG_ENERGY) {
-                        Slog.d(TAG, "Wifi uid " + entry.uid + ": delta rx=" + entry.rxBytes
-                                + " tx=" + entry.txBytes + " rxPackets=" + entry.rxPackets
-                                + " txPackets=" + entry.txPackets);
+                        Slog.d(TAG, "Wifi uid " + entry.getUid()
+                                + ": delta rx=" + entry.getRxBytes()
+                                + " tx=" + entry.getTxBytes()
+                                + " rxPackets=" + entry.getRxPackets()
+                                + " txPackets=" + entry.getTxPackets());
                     }
 
-                    if (entry.rxBytes == 0 && entry.txBytes == 0) {
+                    if (entry.getRxBytes() == 0 && entry.getTxBytes() == 0) {
                         // Skip the lookup below since there is no work to do.
                         continue;
                     }
 
-                    final Uid u = getUidStatsLocked(mapUid(entry.uid), elapsedRealtimeMs, uptimeMs);
-                    if (entry.rxBytes != 0) {
-                        u.noteNetworkActivityLocked(NETWORK_WIFI_RX_DATA, entry.rxBytes,
-                                entry.rxPackets);
-                        if (entry.set == NetworkStats.SET_DEFAULT) { // Background transfers
-                            u.noteNetworkActivityLocked(NETWORK_WIFI_BG_RX_DATA, entry.rxBytes,
-                                    entry.rxPackets);
+                    final Uid u = getUidStatsLocked(mapUid(entry.getUid()),
+                            elapsedRealtimeMs, uptimeMs);
+                    if (entry.getRxBytes() != 0) {
+                        u.noteNetworkActivityLocked(NETWORK_WIFI_RX_DATA, entry.getRxBytes(),
+                                entry.getRxPackets());
+                        if (entry.getSet() == NetworkStats.SET_DEFAULT) { // Background transfers
+                            u.noteNetworkActivityLocked(NETWORK_WIFI_BG_RX_DATA, entry.getRxBytes(),
+                                    entry.getRxPackets());
                         }
                         mNetworkByteActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked(
-                                entry.rxBytes);
+                                entry.getRxBytes());
                         mNetworkPacketActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked(
-                                entry.rxPackets);
+                                entry.getRxPackets());
 
                         // TODO(b/182845426): What if u was a mapped isolated uid? Shouldn't we sum?
-                        rxPackets.put(u.getUid(), entry.rxPackets);
+                        rxPackets.put(u.getUid(), entry.getRxPackets());
 
                         // Sum the total number of packets so that the Rx Power can
                         // be evenly distributed amongst the apps.
-                        totalRxPackets += entry.rxPackets;
+                        totalRxPackets += entry.getRxPackets();
                     }
 
-                    if (entry.txBytes != 0) {
-                        u.noteNetworkActivityLocked(NETWORK_WIFI_TX_DATA, entry.txBytes,
-                                entry.txPackets);
-                        if (entry.set == NetworkStats.SET_DEFAULT) { // Background transfers
-                            u.noteNetworkActivityLocked(NETWORK_WIFI_BG_TX_DATA, entry.txBytes,
-                                    entry.txPackets);
+                    if (entry.getTxBytes() != 0) {
+                        u.noteNetworkActivityLocked(NETWORK_WIFI_TX_DATA, entry.getTxBytes(),
+                                entry.getTxPackets());
+                        if (entry.getSet() == NetworkStats.SET_DEFAULT) { // Background transfers
+                            u.noteNetworkActivityLocked(NETWORK_WIFI_BG_TX_DATA, entry.getTxBytes(),
+                                    entry.getTxPackets());
                         }
                         mNetworkByteActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked(
-                                entry.txBytes);
+                                entry.getTxBytes());
                         mNetworkPacketActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked(
-                                entry.txPackets);
+                                entry.getTxPackets());
 
                         // TODO(b/182845426): What if u was a mapped isolated uid? Shouldn't we sum?
-                        txPackets.put(u.getUid(), entry.txPackets);
+                        txPackets.put(u.getUid(), entry.getTxPackets());
 
                         // Sum the total number of packets so that the Tx Power can
                         // be evenly distributed amongst the apps.
-                        totalTxPackets += entry.txPackets;
+                        totalTxPackets += entry.getTxPackets();
                     }
 
                     // Calculate consumed energy for this uid. Only do so if WifiReporting isn't
@@ -11681,11 +11680,10 @@
 
                         uidEstimatedConsumptionMah.add(u.getUid(),
                                 mWifiPowerCalculator.calcPowerWithoutControllerDataMah(
-                                        entry.rxPackets, entry.txPackets,
+                                        entry.getRxPackets(), entry.getTxPackets(),
                                         uidRunningMs, uidScanMs, uidBatchScanMs));
                     }
                 }
-                mNetworkStatsPool.release(delta);
                 delta = null;
             }
 
@@ -11932,21 +11930,15 @@
         // Grab a separate lock to acquire the network stats, which may do I/O.
         NetworkStats delta = null;
         synchronized (mModemNetworkLock) {
-            final NetworkStats latestStats = readNetworkStatsLocked(networkStatsManager,
-                    mModemIfaces);
+            final NetworkStats latestStats = readMobileNetworkStatsLocked(networkStatsManager);
             if (latestStats != null) {
-                delta = NetworkStats.subtract(latestStats, mLastModemNetworkStats, null, null,
-                        mNetworkStatsPool.acquire());
-                mNetworkStatsPool.release(mLastModemNetworkStats);
+                delta = latestStats.subtract(mLastModemNetworkStats);
                 mLastModemNetworkStats = latestStats;
             }
         }
 
         synchronized (this) {
             if (!mOnBatteryInternal || mIgnoreNextExternalStats) {
-                if (delta != null) {
-                    mNetworkStatsPool.release(delta);
-                }
                 return;
             }
 
@@ -12148,7 +12140,6 @@
                             totalEstimatedConsumptionMah);
                 }
 
-                mNetworkStatsPool.release(delta);
                 delta = null;
             }
         }
diff --git a/core/java/com/android/internal/os/BatteryUsageStatsProvider.java b/core/java/com/android/internal/os/BatteryUsageStatsProvider.java
index 980aec1..7983286 100644
--- a/core/java/com/android/internal/os/BatteryUsageStatsProvider.java
+++ b/core/java/com/android/internal/os/BatteryUsageStatsProvider.java
@@ -21,6 +21,7 @@
 import android.os.BatteryStats;
 import android.os.BatteryUsageStats;
 import android.os.BatteryUsageStatsQuery;
+import android.os.Parcel;
 import android.os.SystemClock;
 import android.os.UidBatteryConsumer;
 import android.util.Log;
@@ -28,6 +29,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 
+import java.io.File;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
@@ -186,16 +188,28 @@
             }
 
             BatteryStatsImpl batteryStatsImpl = (BatteryStatsImpl) mStats;
+
+            // Make a copy of battery history to avoid concurrent modification.
+            Parcel historyBuffer = Parcel.obtain();
+            historyBuffer.appendFrom(batteryStatsImpl.mHistoryBuffer, 0,
+                    batteryStatsImpl.mHistoryBuffer.dataSize());
+
             ArrayList<BatteryStats.HistoryTag> tags = new ArrayList<>(
                     batteryStatsImpl.mHistoryTagPool.size());
             for (Map.Entry<BatteryStats.HistoryTag, Integer> entry :
                     batteryStatsImpl.mHistoryTagPool.entrySet()) {
-                final BatteryStats.HistoryTag tag = entry.getKey();
+                final BatteryStats.HistoryTag tag = new BatteryStats.HistoryTag();
+                tag.setTo(entry.getKey());
                 tag.poolIdx = entry.getValue();
                 tags.add(tag);
             }
 
-            batteryUsageStatsBuilder.setBatteryHistory(batteryStatsImpl.mHistoryBuffer, tags);
+            final File systemDir =
+                    batteryStatsImpl.mBatteryStatsHistory.getHistoryDirectory().getParentFile();
+            final BatteryStatsHistory batteryStatsHistory =
+                    new BatteryStatsHistory(batteryStatsImpl, systemDir, historyBuffer);
+
+            batteryUsageStatsBuilder.setBatteryHistory(historyBuffer, tags, batteryStatsHistory);
         }
 
         return batteryUsageStatsBuilder.build();
diff --git a/core/java/com/android/internal/os/BinderLatencyObserver.java b/core/java/com/android/internal/os/BinderLatencyObserver.java
index 20cf102..e9d55db 100644
--- a/core/java/com/android/internal/os/BinderLatencyObserver.java
+++ b/core/java/com/android/internal/os/BinderLatencyObserver.java
@@ -19,7 +19,6 @@
 import android.annotation.Nullable;
 import android.os.Binder;
 import android.os.Handler;
-import android.os.Looper;
 import android.os.SystemClock;
 import android.util.ArrayMap;
 import android.util.Slog;
@@ -181,7 +180,7 @@
         }
 
         public Handler getHandler() {
-            return new Handler(Looper.getMainLooper());
+            return BackgroundThread.getHandler();
         }
     }
 
diff --git a/core/java/com/android/internal/os/RuntimeInit.java b/core/java/com/android/internal/os/RuntimeInit.java
index 8d1f16b..44c7f54 100644
--- a/core/java/com/android/internal/os/RuntimeInit.java
+++ b/core/java/com/android/internal/os/RuntimeInit.java
@@ -22,6 +22,7 @@
 import android.app.IActivityManager;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.type.DefaultMimeMapFactory;
+import android.net.TrafficStats;
 import android.os.Build;
 import android.os.DeadObjectException;
 import android.os.IBinder;
@@ -32,7 +33,6 @@
 import android.util.Slog;
 
 import com.android.internal.logging.AndroidConfig;
-import com.android.server.NetworkManagementSocketTagger;
 
 import dalvik.system.RuntimeHooks;
 import dalvik.system.VMRuntime;
@@ -254,7 +254,7 @@
         /*
          * Wire socket tagging to traffic stats.
          */
-        NetworkManagementSocketTagger.install();
+        TrafficStats.attachSocketTagger();
 
         initialized = true;
     }
diff --git a/core/java/com/android/internal/util/FileRotator.java b/core/java/com/android/internal/util/FileRotator.java
index 3ca3320..4b3af15 100644
--- a/core/java/com/android/internal/util/FileRotator.java
+++ b/core/java/com/android/internal/util/FileRotator.java
@@ -17,7 +17,7 @@
 package com.android.internal.util;
 
 import android.os.FileUtils;
-import android.util.Slog;
+import android.util.Log;
 
 import java.io.BufferedInputStream;
 import java.io.BufferedOutputStream;
@@ -32,7 +32,6 @@
 import java.util.zip.ZipOutputStream;
 
 import libcore.io.IoUtils;
-import libcore.io.Streams;
 
 /**
  * Utility that rotates files over time, similar to {@code logrotate}. There is
@@ -47,6 +46,8 @@
  * <p>
  * Users must periodically call {@link #maybeRotate(long)} to perform actual
  * rotation. Not inherently thread safe.
+ *
+ * @hide
  */
 public class FileRotator {
     private static final String TAG = "FileRotator";
@@ -110,7 +111,7 @@
             if (!name.startsWith(mPrefix)) continue;
 
             if (name.endsWith(SUFFIX_BACKUP)) {
-                if (LOGD) Slog.d(TAG, "recovering " + name);
+                if (LOGD) Log.d(TAG, "recovering " + name);
 
                 final File backupFile = new File(mBasePath, name);
                 final File file = new File(
@@ -120,7 +121,7 @@
                 backupFile.renameTo(file);
 
             } else if (name.endsWith(SUFFIX_NO_BACKUP)) {
-                if (LOGD) Slog.d(TAG, "recovering " + name);
+                if (LOGD) Log.d(TAG, "recovering " + name);
 
                 final File noBackupFile = new File(mBasePath, name);
                 final File file = new File(
@@ -231,7 +232,7 @@
      * if the write fails.
      */
     private void rewriteSingle(Rewriter rewriter, String name) throws IOException {
-        if (LOGD) Slog.d(TAG, "rewriting " + name);
+        if (LOGD) Log.d(TAG, "rewriting " + name);
 
         final File file = new File(mBasePath, name);
         final File backupFile;
@@ -291,7 +292,7 @@
 
             // read file when it overlaps
             if (info.startMillis <= matchEndMillis && matchStartMillis <= info.endMillis) {
-                if (LOGD) Slog.d(TAG, "reading matching " + name);
+                if (LOGD) Log.d(TAG, "reading matching " + name);
 
                 final File file = new File(mBasePath, name);
                 readFile(file, reader);
@@ -348,7 +349,7 @@
             if (info.isActive()) {
                 if (info.startMillis <= rotateBefore) {
                     // found active file; rotate if old enough
-                    if (LOGD) Slog.d(TAG, "rotating " + name);
+                    if (LOGD) Log.d(TAG, "rotating " + name);
 
                     info.endMillis = currentTimeMillis;
 
@@ -358,7 +359,7 @@
                 }
             } else if (info.endMillis <= deleteBefore) {
                 // found rotated file; delete if old enough
-                if (LOGD) Slog.d(TAG, "deleting " + name);
+                if (LOGD) Log.d(TAG, "deleting " + name);
 
                 final File file = new File(mBasePath, name);
                 file.delete();
@@ -383,7 +384,10 @@
             writer.write(bos);
             bos.flush();
         } finally {
-            FileUtils.sync(fos);
+            try {
+                fos.getFD().sync();
+            } catch (IOException e) {
+            }
             IoUtils.closeQuietly(bos);
         }
     }
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 2cfec4b..adcbb425 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -242,9 +242,9 @@
                 "audioflinger-aidl-cpp",
                 "av-types-aidl-cpp",
                 "android.hardware.camera.device@3.2",
+                "libandroid_net",
                 "libandroidicu",
                 "libbpf_android",
-                "libnetdbpf",
                 "libnetdutils",
                 "libmemtrack",
                 "libandroidfw",
diff --git a/core/jni/OWNERS b/core/jni/OWNERS
index 832c498..80e83ad 100644
--- a/core/jni/OWNERS
+++ b/core/jni/OWNERS
@@ -72,6 +72,9 @@
 per-file AndroidRuntime.cpp = calin@google.com, ngeoffray@google.com, oth@google.com
 # Although marked "view" this is mostly graphics stuff
 per-file android_view_* = file:/graphics/java/android/graphics/OWNERS
+# File used for Android Studio layoutlib
+per-file LayoutlibLoader.cpp = file:/graphics/java/android/graphics/OWNERS
+per-file LayoutlibLoader.cpp = diegoperez@google.com, jgaillard@google.com
 
 # Verity
 per-file com_android_internal_security_Verity* = ebiggers@google.com, victorhsieh@google.com
diff --git a/core/jni/android_hardware_UsbDeviceConnection.cpp b/core/jni/android_hardware_UsbDeviceConnection.cpp
index 845d65c..a022842 100644
--- a/core/jni/android_hardware_UsbDeviceConnection.cpp
+++ b/core/jni/android_hardware_UsbDeviceConnection.cpp
@@ -16,20 +16,19 @@
 
 #define LOG_TAG "UsbDeviceConnectionJNI"
 
-#include "utils/Log.h"
-
-#include "jni.h"
+#include <fcntl.h>
 #include <nativehelper/JNIPlatformHelp.h>
-#include "core_jni_helpers.h"
-
+#include <stdio.h>
+#include <sys/stat.h>
+#include <sys/types.h>
 #include <usbhost/usbhost.h>
+#include <usbhost/usbhost_jni.h>
 
 #include <chrono>
 
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
+#include "core_jni_helpers.h"
+#include "jni.h"
+#include "utils/Log.h"
 
 using namespace android;
 using namespace std::chrono;
@@ -91,22 +90,8 @@
 static jbyteArray
 android_hardware_UsbDeviceConnection_get_desc(JNIEnv *env, jobject thiz)
 {
-    char buffer[16384];
     int fd = android_hardware_UsbDeviceConnection_get_fd(env, thiz);
-    if (fd < 0) return NULL;
-    lseek(fd, 0, SEEK_SET);
-    int length = read(fd, buffer, sizeof(buffer));
-    if (length < 0) return NULL;
-
-    jbyteArray ret = env->NewByteArray(length);
-    if (ret) {
-        jbyte* bytes = (jbyte*)env->GetPrimitiveArrayCritical(ret, 0);
-        if (bytes) {
-            memcpy(bytes, buffer, length);
-            env->ReleasePrimitiveArrayCritical(ret, bytes, 0);
-        }
-    }
-    return ret;
+    return usb_jni_read_descriptors(env, fd);
 }
 
 static jboolean
diff --git a/core/jni/android_server_NetworkManagementSocketTagger.cpp b/core/jni/android_server_NetworkManagementSocketTagger.cpp
index afad08a..1be1873 100644
--- a/core/jni/android_server_NetworkManagementSocketTagger.cpp
+++ b/core/jni/android_server_NetworkManagementSocketTagger.cpp
@@ -15,24 +15,23 @@
  */
 
 #define LOG_TAG "NMST_QTagUidNative"
-#include <utils/Log.h>
 
-#include <nativehelper/JNIPlatformHelp.h>
-
-#include "jni.h"
-#include <utils/misc.h>
+#include <android/multinetwork.h>
 #include <cutils/qtaguid.h>
-
 #include <errno.h>
 #include <fcntl.h>
-#include <sys/types.h>
+#include <nativehelper/JNIPlatformHelp.h>
 #include <sys/socket.h>
+#include <sys/types.h>
+#include <utils/Log.h>
+#include <utils/misc.h>
+
+#include "jni.h"
 
 namespace android {
 
-static jint QTagUid_tagSocketFd(JNIEnv* env, jclass,
-                                jobject fileDescriptor,
-                                jint tagNum, jint uid) {
+static jint tagSocketFd(JNIEnv* env, jclass, jobject fileDescriptor,
+                        jint tagNum, jint uid) {
   int userFd = jniGetFDFromFileDescriptor(env, fileDescriptor);
 
   if (env->ExceptionCheck()) {
@@ -40,15 +39,14 @@
     return (jint)-1;
   }
 
-  int res = qtaguid_tagSocket(userFd, tagNum, uid);
+  int res = android_tag_socket_with_uid(userFd, tagNum, uid);
   if (res < 0) {
     return (jint)-errno;
   }
   return (jint)res;
 }
 
-static jint QTagUid_untagSocketFd(JNIEnv* env, jclass,
-                                  jobject fileDescriptor) {
+static jint untagSocketFd(JNIEnv* env, jclass, jobject fileDescriptor) {
   int userFd = jniGetFDFromFileDescriptor(env, fileDescriptor);
 
   if (env->ExceptionCheck()) {
@@ -56,16 +54,14 @@
     return (jint)-1;
   }
 
-  int res = qtaguid_untagSocket(userFd);
+  int res = android_untag_socket(userFd);
   if (res < 0) {
     return (jint)-errno;
   }
   return (jint)res;
 }
 
-static jint QTagUid_setCounterSet(JNIEnv* env, jclass,
-                                  jint setNum, jint uid) {
-
+static jint setCounterSet(JNIEnv* env, jclass, jint setNum, jint uid) {
   int res = qtaguid_setCounterSet(setNum, uid);
   if (res < 0) {
     return (jint)-errno;
@@ -73,9 +69,7 @@
   return (jint)res;
 }
 
-static jint QTagUid_deleteTagData(JNIEnv* env, jclass,
-                                  jint tagNum, jint uid) {
-
+static jint deleteTagData(JNIEnv* env, jclass, jint tagNum, jint uid) {
   int res = qtaguid_deleteTagData(tagNum, uid);
   if (res < 0) {
     return (jint)-errno;
@@ -84,10 +78,10 @@
 }
 
 static const JNINativeMethod gQTagUidMethods[] = {
-  { "native_tagSocketFd", "(Ljava/io/FileDescriptor;II)I", (void*)QTagUid_tagSocketFd},
-  { "native_untagSocketFd", "(Ljava/io/FileDescriptor;)I", (void*)QTagUid_untagSocketFd},
-  { "native_setCounterSet", "(II)I", (void*)QTagUid_setCounterSet},
-  { "native_deleteTagData", "(II)I", (void*)QTagUid_deleteTagData},
+  { "native_tagSocketFd", "(Ljava/io/FileDescriptor;II)I", (void*)tagSocketFd},
+  { "native_untagSocketFd", "(Ljava/io/FileDescriptor;)I", (void*)untagSocketFd},
+  { "native_setCounterSet", "(II)I", (void*)setCounterSet},
+  { "native_deleteTagData", "(II)I", (void*)deleteTagData},
 };
 
 int register_android_server_NetworkManagementSocketTagger(JNIEnv* env) {
diff --git a/core/proto/OWNERS b/core/proto/OWNERS
index 931ef44..43d2439 100644
--- a/core/proto/OWNERS
+++ b/core/proto/OWNERS
@@ -17,7 +17,8 @@
 per-file apphibernationservice.proto = file:/core/java/android/apphibernation/OWNERS
 
 # Biometrics
-kchyn@google.com
+jaggies@google.com
+jbolinger@google.com
 
 # Launcher
 hyunyoungs@google.com
diff --git a/core/proto/android/os/incident.proto b/core/proto/android/os/incident.proto
index 998ec96..51e150e 100644
--- a/core/proto/android/os/incident.proto
+++ b/core/proto/android/os/incident.proto
@@ -249,7 +249,8 @@
 
     optional android.service.NetworkStatsServiceDumpProto netstats = 3001 [
         (section).type = SECTION_DUMPSYS,
-        (section).args = "netstats --proto"
+        (section).args = "netstats --proto",
+        (section).userdebug_and_eng_only = true
     ];
 
     optional android.providers.settings.SettingsServiceDumpProto settings = 3002 [
diff --git a/core/proto/android/service/netstats.proto b/core/proto/android/service/netstats.proto
index c8cdfdd..ba2b6d6b 100644
--- a/core/proto/android/service/netstats.proto
+++ b/core/proto/android/service/netstats.proto
@@ -17,15 +17,11 @@
 syntax = "proto2";
 package android.service;
 
-import "frameworks/base/core/proto/android/privacy.proto";
-
 option java_multiple_files = true;
 option java_outer_classname = "NetworkStatsServiceProto";
 
 // Represents dumpsys from NetworkStatsService (netstats).
 message NetworkStatsServiceDumpProto {
-    option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
     repeated NetworkInterfaceProto active_interfaces = 1;
 
     repeated NetworkInterfaceProto active_uid_interfaces = 2;
@@ -45,8 +41,6 @@
 
 // Corresponds to NetworkStatsService.mActiveIfaces/mActiveUidIfaces.
 message NetworkInterfaceProto {
-    option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
     // Name of the network interface (eg: wlan).
     optional string interface = 1;
 
@@ -55,26 +49,14 @@
 
 // Corresponds to NetworkIdentitySet.
 message NetworkIdentitySetProto {
-    option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
     repeated NetworkIdentityProto identities = 1;
 }
 
 // Corresponds to NetworkIdentity.
 message NetworkIdentityProto {
-    option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
     // Constants from ConnectivityManager.TYPE_*.
     optional int32 type = 1;
 
-    // Full subscriber ID on eng builds. The IMSI is scrubbed on user & userdebug
-    // builds to only include the info about the GSM network operator (the info
-    // that uniquely identifies the subscriber is removed).
-    optional string subscriber_id = 2 [ (android.privacy).dest = DEST_EXPLICIT ];
-
-    // Name of the network (eg: MyWifi).
-    optional string network_id = 3 [ (android.privacy).dest = DEST_EXPLICIT ];
-
     optional bool roaming = 4;
 
     optional bool metered = 5;
@@ -86,8 +68,6 @@
 
 // Corresponds to NetworkStatsRecorder.
 message NetworkStatsRecorderProto {
-    option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
     optional int64 pending_total_bytes = 1;
 
     optional NetworkStatsCollectionProto complete_history = 2;
@@ -95,15 +75,11 @@
 
 // Corresponds to NetworkStatsCollection.
 message NetworkStatsCollectionProto {
-    option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
     repeated NetworkStatsCollectionStatsProto stats = 1;
 }
 
 // Corresponds to NetworkStatsCollection.mStats.
 message NetworkStatsCollectionStatsProto {
-    option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
     optional NetworkStatsCollectionKeyProto key = 1;
 
     optional NetworkStatsHistoryProto history = 2;
@@ -111,8 +87,6 @@
 
 // Corresponds to NetworkStatsCollection.Key.
 message NetworkStatsCollectionKeyProto {
-    option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
     optional NetworkIdentitySetProto identity = 1;
 
     optional int32 uid = 2;
@@ -124,8 +98,6 @@
 
 // Corresponds to NetworkStatsHistory.
 message NetworkStatsHistoryProto {
-    option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
     // Duration for this bucket in milliseconds.
     optional int64 bucket_duration_ms = 1;
 
@@ -134,8 +106,6 @@
 
 // Corresponds to each bucket in NetworkStatsHistory.
 message NetworkStatsHistoryBucketProto {
-    option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
     // Bucket start time in milliseconds since epoch.
     optional int64 bucket_start_ms = 1;
 
diff --git a/core/res/Android.bp b/core/res/Android.bp
index 6063062..c42517d 100644
--- a/core/res/Android.bp
+++ b/core/res/Android.bp
@@ -37,7 +37,6 @@
     visibility: [":__subpackages__"],
     license_kinds: [
         "SPDX-license-identifier-Apache-2.0",
-        "SPDX-license-identifier-GPL",
     ],
     license_text: [
         "NOTICE",
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 6ecfcec..6bcaace9 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2114,8 +2114,9 @@
     <permission android:name="android.permission.NFC_HANDOVER_STATUS"
         android:protectionLevel="signature|privileged" />
 
-    <!-- @hide Allows internal management of Bluetooth state when on wireless consent mode.
-         <p>Not for use by third-party applications. -->
+    <!-- @SystemApi Allows internal management of Bluetooth state when on wireless consent mode.
+         <p>Not for use by third-party applications.
+         @hide -->
     <permission android:name="android.permission.MANAGE_BLUETOOTH_WHEN_WIRELESS_CONSENT_REQUIRED"
         android:protectionLevel="signature" />
 
@@ -2723,6 +2724,10 @@
     <permission android:name="android.permission.INTERACT_ACROSS_PROFILES"
         android:protectionLevel="signature|appop" />
 
+    <!-- @SystemApi @hide Allows starting activities across profiles in the same profile group. -->
+    <permission android:name="android.permission.START_CROSS_PROFILE_ACTIVITIES"
+                android:protectionLevel="signature|role" />
+
     <!-- Allows configuring apps to have the INTERACT_ACROSS_PROFILES permission so that they can
          interact across profiles in the same profile group.
          @hide -->
@@ -6234,6 +6239,11 @@
                  android:permission="android.permission.BIND_JOB_SERVICE" >
         </service>
 
+        <service android:name="com.android.server.SmartStorageMaintIdler"
+                android:exported="true"
+                android:permission="android.permission.BIND_JOB_SERVICE" >
+        </service>
+
         <service android:name="com.android.server.ZramWriteback"
                  android:exported="false"
                  android:permission="android.permission.BIND_JOB_SERVICE" >
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 2f33498..ba647d7 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -134,9 +134,6 @@
          be sent during a change to the audio output device. -->
     <bool name="config_sendAudioBecomingNoisy">true</bool>
 
-    <!-- Whether Hearing Aid profile is supported -->
-    <bool name="config_hearing_aid_profile_supported">false</bool>
-
     <!-- Flag to disable all transition animations -->
     <bool name="config_disableTransitionAnimation">false</bool>
 
@@ -404,10 +401,6 @@
     <string-array translatable="false" name="config_tether_bluetooth_regexs">
     </string-array>
 
-    <!-- Max number of Bluetooth tethering connections allowed. If this is
-         updated config_tether_dhcp_range has to be updated appropriately. -->
-    <integer translatable="false" name="config_max_pan_devices">5</integer>
-
     <!-- This setting is deprecated, please use
          com.android.networkstack.tethering.R.array.config_dhcp_range instead. -->
     <string-array translatable="false" name="config_tether_dhcp_range">
@@ -1820,53 +1813,38 @@
     <!-- Integer to set a max latency the accelerometer will batch sensor requests with. -->
     <integer name="config_flipToScreenOffMaxLatencyMicros">2000000</integer>
 
-    <!-- Boolean indicating if current platform supports bluetooth SCO for off call
-    use cases -->
+    <!-- Note: This config is deprecated
+          Boolean indicating if current platform supports bluetooth SCO for off call
+          use cases
+    -->
     <bool name="config_bluetooth_sco_off_call">true</bool>
 
-    <!-- Boolean indicating if current platform supports bluetooth wide band
-         speech -->
-    <bool name="config_bluetooth_wide_band_speech">true</bool>
-
-    <!-- Boolean indicating if current platform need do one-time bluetooth address
-         re-validation -->
+    <!-- Note: This config is deprecated
+          Boolean indicating if current platform need do one-time bluetooth address
+          re-validation
+    -->
     <bool name="config_bluetooth_address_validation">false</bool>
 
-    <!-- Boolean indicating if current platform supports BLE peripheral mode -->
-    <bool name="config_bluetooth_le_peripheral_mode_supported">false</bool>
-
-    <!-- Boolean indicating if current platform supports HFP inband ringing -->
-    <bool name="config_bluetooth_hfp_inband_ringing_support">false</bool>
-
-    <!-- Max number of scan filters supported by blutooth controller. 0 if the
-         device does not support hardware scan filters-->
-    <integer translatable="false" name="config_bluetooth_max_scan_filters">0</integer>
-
-    <!-- Max number of advertisers supported by bluetooth controller. 0 if the
-         device does not support multiple advertisement-->
-    <integer translatable="false" name="config_bluetooth_max_advertisers">0</integer>
-
-    <!-- Idle current for bluetooth controller. 0 by default-->
+    <!-- Note: This config is deprecated, use BluetoothProperties instead.
+         Idle current for bluetooth controller. 0 by default
+    -->
     <integer translatable="false" name="config_bluetooth_idle_cur_ma">0</integer>
 
-    <!-- Rx current for bluetooth controller. 0 by default-->
+    <!-- Note: This config is deprecated, use BluetoothProperties instead.
+         Rx current for bluetooth controller. 0 by default
+    -->
     <integer translatable="false" name="config_bluetooth_rx_cur_ma">0</integer>
 
-    <!-- Tx current for bluetooth controller. 0 by default-->
+    <!-- Note: This config is deprecated, use BluetoothProperties instead.
+         Tx current for bluetooth controller. 0 by default
+    -->
     <integer translatable="false" name="config_bluetooth_tx_cur_ma">0</integer>
 
-    <!-- Operating volatage for bluetooth controller. 0 by default-->
+    <!-- Note: This config is deprecated, use BluetoothProperties instead.
+         Operating volatage for bluetooth controller. 0 by default
+    -->
     <integer translatable="false" name="config_bluetooth_operating_voltage_mv">0</integer>
 
-    <!-- Max number of connected audio devices supported by Bluetooth stack -->
-    <integer name="config_bluetooth_max_connected_audio_devices">5</integer>
-
-    <!-- Whether supported profiles should be reloaded upon enabling bluetooth -->
-    <bool name="config_bluetooth_reload_supported_profiles_when_enabled">false</bool>
-
-    <!-- Enabling autoconnect over pan -->
-    <bool name="config_bluetooth_pan_enable_autoconnect">false</bool>
-
     <!-- The default data-use polling period. -->
     <integer name="config_datause_polling_period_sec">600</integer>
 
@@ -2007,10 +1985,6 @@
     <!-- The name of the package that will be allowed to change its components' label/icon. -->
     <string name="config_overrideComponentUiPackage" translatable="false">com.android.stk</string>
 
-    <!-- Enable/disable default bluetooth profiles:
-        HSP_AG, ObexObjectPush, Audio, NAP -->
-    <bool name="config_bluetooth_default_profiles">true</bool>
-
     <!-- IP address of the dns server to use if nobody else suggests one -->
     <string name="config_default_dns_server" translatable="false">8.8.8.8</string>
 
@@ -4141,8 +4115,6 @@
     <!-- Component name that should be granted Notification Assistant access -->
     <string name="config_defaultAssistantAccessComponent" translatable="false">android.ext.services/android.ext.services.notification.Assistant</string>
 
-    <bool name="config_supportBluetoothPersistedState">true</bool>
-
     <bool name="config_keepRestrictedProfilesInBackground">true</bool>
 
     <!-- Cellular network service package name to bind to by default. -->
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 2403a60..6ef5bd4 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -3200,11 +3200,87 @@
     <!-- @hide For use by platform and tools only. Developers should not specify this value. -->
     <public type="string" name="config_defaultRingtoneVibrationSound" id="0x0104003b" />
 
+    <!-- ===============================================================
+         Resources added in version T of the platform
+
+         NOTE: add <public> elements within a <staging-public-group> like so:
+
+         <staging-public-group type="attr" first-id="0x01ff0000">
+             <public name="exampleAttr1" />
+             <public name="exampleAttr2" />
+         </staging-public-group>
+
+         To add a new <staging-public-group> block, find the id value for the
+         last <staging-public-group> block defined for thie API level, and
+         subtract 0x00010000 from it to get to the id of the new block.
+
+         For example, if the block closest to the end of this file has an id
+         of 0x01ee0000, the id of the new block should be 0x01ed0000
+         (0x01ee0000 - 0x00010000 = 0x01ed0000).
+         =============================================================== -->
+    <eat-comment />
+
+    <staging-public-group type="attr" first-id="0x01df0000">
+    </staging-public-group>
+
+    <staging-public-group type="id" first-id="0x01de0000">
+    </staging-public-group>
+
+    <staging-public-group type="style" first-id="0x0dfd0000">
+    </staging-public-group>
+
+    <staging-public-group type="string" first-id="0x0dfc0000">
+    </staging-public-group>
+
+    <staging-public-group type="dimen" first-id="0x01db0000">
+    </staging-public-group>
+
+    <staging-public-group type="color" first-id="0x01da0000">
+    </staging-public-group>
+
+    <staging-public-group type="array" first-id="0x01d90000">
+      <!-- @hide @SystemApi -->
+      <public name="config_optionalIpSecAlgorithms" />
+    </staging-public-group>
+
+    <staging-public-group type="drawable" first-id="0x01d80000">
+    </staging-public-group>
+
+    <staging-public-group type="layout" first-id="0x01d70000">
+    </staging-public-group>
+
+    <staging-public-group type="anim" first-id="0x01d60000">
+    </staging-public-group>
+
+    <staging-public-group type="animator" first-id="0x01d50000">
+    </staging-public-group>
+
+    <staging-public-group type="interpolator" first-id="0x01d40000">
+    </staging-public-group>
+
+    <staging-public-group type="mipmap" first-id="0x01d30000">
+    </staging-public-group>
+
+    <staging-public-group type="integer" first-id="0x01d20000">
+    </staging-public-group>
+
+    <staging-public-group type="transition" first-id="0x01d10000">
+    </staging-public-group>
+
+    <staging-public-group type="raw" first-id="0x01d00000">
+    </staging-public-group>
+
+    <staging-public-group type="bool" first-id="0x01cf0000">
+    </staging-public-group>
+
+    <staging-public-group type="fraction" first-id="0x01ce0000">
+    </staging-public-group>
+
   <!-- ===============================================================
        DO NOT ADD UN-GROUPED ITEMS HERE
 
        Any new items (attrs, styles, ids, etc.) *must* be added in a
-       public-group block, as the preceding comment explains.
+       staging-public-group block, as the preceding comment explains.
        Items added outside of a group may have their value recalculated
        every time something new is added to this file.
        =============================================================== -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 4db6499..590fcf4 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -278,8 +278,6 @@
   <java-symbol type="bool" name="config_flipToScreenOffEnabled" />
   <java-symbol type="integer" name="config_flipToScreenOffMaxLatencyMicros" />
   <java-symbol type="bool" name="config_bluetooth_sco_off_call" />
-  <java-symbol type="bool" name="config_bluetooth_le_peripheral_mode_supported" />
-  <java-symbol type="bool" name="config_bluetooth_hfp_inband_ringing_support" />
   <java-symbol type="bool" name="config_cellBroadcastAppLinks" />
   <java-symbol type="bool" name="config_duplicate_port_omadm_wappush" />
   <java-symbol type="bool" name="config_disableTransitionAnimation" />
@@ -343,7 +341,6 @@
   <java-symbol type="integer" name="config_timeZoneRulesCheckRetryCount" />
   <java-symbol type="bool" name="config_sendAudioBecomingNoisy" />
   <java-symbol type="bool" name="config_enableScreenshotChord" />
-  <java-symbol type="bool" name="config_bluetooth_default_profiles" />
   <java-symbol type="bool" name="config_enableWifiDisplay" />
   <java-symbol type="bool" name="config_allowAnimationsInLowPowerMode" />
   <java-symbol type="bool" name="config_useDevInputEventForAudioJack" />
@@ -417,9 +414,6 @@
   <java-symbol type="dimen" name="config_pictureInPictureMaxAspectRatio" />
   <java-symbol type="integer" name="config_pictureInPictureMaxNumberOfActions" />
   <java-symbol type="dimen" name="config_closeToSquareDisplayMaxAspectRatio" />
-  <java-symbol type="integer" name="config_bluetooth_max_advertisers" />
-  <java-symbol type="integer" name="config_bluetooth_max_scan_filters" />
-  <java-symbol type="integer" name="config_bluetooth_max_connected_audio_devices" />
   <java-symbol type="integer" name="config_burnInProtectionMinHorizontalOffset" />
   <java-symbol type="integer" name="config_burnInProtectionMaxHorizontalOffset" />
   <java-symbol type="integer" name="config_burnInProtectionMinVerticalOffset" />
@@ -429,9 +423,6 @@
   <java-symbol type="integer" name="config_bluetooth_rx_cur_ma" />
   <java-symbol type="integer" name="config_bluetooth_tx_cur_ma" />
   <java-symbol type="integer" name="config_bluetooth_operating_voltage_mv" />
-  <java-symbol type="bool" name="config_bluetooth_pan_enable_autoconnect" />
-  <java-symbol type="bool" name="config_bluetooth_reload_supported_profiles_when_enabled" />
-  <java-symbol type="bool" name="config_hearing_aid_profile_supported" />
   <java-symbol type="integer" name="config_cursorWindowSize" />
   <java-symbol type="integer" name="config_drawLockTimeoutMillis" />
   <java-symbol type="integer" name="config_doublePressOnPowerBehavior" />
@@ -450,7 +441,6 @@
   <java-symbol type="integer" name="config_wakeUpToLastStateTimeoutMillis" />
   <java-symbol type="integer" name="config_lowMemoryKillerMinFreeKbytesAdjust" />
   <java-symbol type="integer" name="config_lowMemoryKillerMinFreeKbytesAbsolute" />
-  <java-symbol type="integer" name="config_max_pan_devices" />
   <java-symbol type="integer" name="config_ntpPollingInterval" />
   <java-symbol type="integer" name="config_ntpPollingIntervalShorter" />
   <java-symbol type="integer" name="config_ntpRetry" />
@@ -3782,8 +3772,6 @@
 
   <java-symbol type="string" name="config_defaultAssistantAccessComponent" />
 
-  <java-symbol type="bool" name="config_supportBluetoothPersistedState" />
-
   <java-symbol type="string" name="slices_permission_request" />
 
   <java-symbol type="string" name="screenshot_edit" />
diff --git a/core/tests/bluetoothtests/Android.bp b/core/tests/bluetoothtests/Android.bp
deleted file mode 100644
index 68416dd..0000000
--- a/core/tests/bluetoothtests/Android.bp
+++ /dev/null
@@ -1,24 +0,0 @@
-package {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "frameworks_base_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["frameworks_base_license"],
-}
-
-android_test {
-    name: "BluetoothTests",
-    // Include all test java files.
-    srcs: ["src/**/*.java"],
-    libs: [
-        "android.test.runner",
-        "android.test.base",
-    ],
-    static_libs: [
-        "junit",
-        "modules-utils-bytesmatcher",
-    ],
-    platform_apis: true,
-    certificate: "platform",
-}
diff --git a/core/tests/bluetoothtests/AndroidManifest.xml b/core/tests/bluetoothtests/AndroidManifest.xml
deleted file mode 100644
index 75583d5..0000000
--- a/core/tests/bluetoothtests/AndroidManifest.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 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.bluetooth.tests"
-          android:sharedUserId="android.uid.bluetooth" >
-
-    <uses-permission android:name="android.permission.BLUETOOTH" />
-    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
-    <uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE"/>
-    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
-    <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
-    <uses-permission android:name="android.permission.BLUETOOTH_PRIVILEGED" />
-    <uses-permission android:name="android.permission.BROADCAST_STICKY" />
-    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
-    <uses-permission android:name="android.permission.LOCAL_MAC_ADDRESS" />
-    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
-    <uses-permission android:name="android.permission.RECEIVE_SMS" />
-    <uses-permission android:name="android.permission.READ_SMS"/>
-    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
-    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
-    <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
-
-    <application >
-        <uses-library android:name="android.test.runner" />
-    </application>
-    <instrumentation android:name="android.bluetooth.BluetoothTestRunner"
-            android:targetPackage="com.android.bluetooth.tests"
-            android:label="Bluetooth Tests" />
-    <instrumentation android:name="android.bluetooth.BluetoothInstrumentation"
-            android:targetPackage="com.android.bluetooth.tests"
-            android:label="Bluetooth Test Utils" />
-
-</manifest>
diff --git a/core/tests/bluetoothtests/AndroidTest.xml b/core/tests/bluetoothtests/AndroidTest.xml
deleted file mode 100644
index f93c4eb..0000000
--- a/core/tests/bluetoothtests/AndroidTest.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?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 Bluetooth 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="BluetoothTests.apk" />
-    </target_preparer>
-
-    <option name="test-suite-tag" value="apct"/>
-    <option name="test-tag" value="BluetoothTests"/>
-
-    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
-        <option name="package" value="com.android.bluetooth.tests" />
-        <option name="hidden-api-checks" value="false"/>
-        <option name="runner" value="android.bluetooth.BluetoothTestRunner"/>
-    </test>
-</configuration>
diff --git a/core/tests/bluetoothtests/OWNERS b/core/tests/bluetoothtests/OWNERS
deleted file mode 100644
index 98bb877..0000000
--- a/core/tests/bluetoothtests/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-include /core/java/android/bluetooth/OWNERS
diff --git a/core/tests/bluetoothtests/src/android/bluetooth/BluetoothCodecConfigTest.java b/core/tests/bluetoothtests/src/android/bluetooth/BluetoothCodecConfigTest.java
deleted file mode 100644
index bd55426..0000000
--- a/core/tests/bluetoothtests/src/android/bluetooth/BluetoothCodecConfigTest.java
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-import android.test.suitebuilder.annotation.SmallTest;
-
-import junit.framework.TestCase;
-
-/**
- * Unit test cases for {@link BluetoothCodecConfig}.
- * <p>
- * To run this test, use:
- * runtest --path core/tests/bluetoothtests/src/android/bluetooth/BluetoothCodecConfigTest.java
- */
-public class BluetoothCodecConfigTest extends TestCase {
-    private static final int[] kCodecTypeArray = new int[] {
-        BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC,
-        BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC,
-        BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX,
-        BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD,
-        BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC,
-        BluetoothCodecConfig.SOURCE_CODEC_TYPE_INVALID,
-    };
-    private static final int[] kCodecPriorityArray = new int[] {
-        BluetoothCodecConfig.CODEC_PRIORITY_DISABLED,
-        BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT,
-        BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST,
-    };
-    private static final int[] kSampleRateArray = new int[] {
-        BluetoothCodecConfig.SAMPLE_RATE_NONE,
-        BluetoothCodecConfig.SAMPLE_RATE_44100,
-        BluetoothCodecConfig.SAMPLE_RATE_48000,
-        BluetoothCodecConfig.SAMPLE_RATE_88200,
-        BluetoothCodecConfig.SAMPLE_RATE_96000,
-        BluetoothCodecConfig.SAMPLE_RATE_176400,
-        BluetoothCodecConfig.SAMPLE_RATE_192000,
-    };
-    private static final int[] kBitsPerSampleArray = new int[] {
-        BluetoothCodecConfig.BITS_PER_SAMPLE_NONE,
-        BluetoothCodecConfig.BITS_PER_SAMPLE_16,
-        BluetoothCodecConfig.BITS_PER_SAMPLE_24,
-        BluetoothCodecConfig.BITS_PER_SAMPLE_32,
-    };
-    private static final int[] kChannelModeArray = new int[] {
-        BluetoothCodecConfig.CHANNEL_MODE_NONE,
-        BluetoothCodecConfig.CHANNEL_MODE_MONO,
-        BluetoothCodecConfig.CHANNEL_MODE_STEREO,
-    };
-    private static final long[] kCodecSpecific1Array = new long[] { 1000, 1001, 1002, 1003, };
-    private static final long[] kCodecSpecific2Array = new long[] { 2000, 2001, 2002, 2003, };
-    private static final long[] kCodecSpecific3Array = new long[] { 3000, 3001, 3002, 3003, };
-    private static final long[] kCodecSpecific4Array = new long[] { 4000, 4001, 4002, 4003, };
-
-    private static final int kTotalConfigs = kCodecTypeArray.length * kCodecPriorityArray.length *
-        kSampleRateArray.length * kBitsPerSampleArray.length * kChannelModeArray.length *
-        kCodecSpecific1Array.length * kCodecSpecific2Array.length * kCodecSpecific3Array.length *
-        kCodecSpecific4Array.length;
-
-    private int selectCodecType(int configId) {
-        int left = kCodecTypeArray.length;
-        int right = kTotalConfigs / left;
-        int index = configId / right;
-        index = index % kCodecTypeArray.length;
-        return kCodecTypeArray[index];
-    }
-
-    private int selectCodecPriority(int configId) {
-        int left = kCodecTypeArray.length * kCodecPriorityArray.length;
-        int right = kTotalConfigs / left;
-        int index = configId / right;
-        index = index % kCodecPriorityArray.length;
-        return kCodecPriorityArray[index];
-    }
-
-    private int selectSampleRate(int configId) {
-        int left = kCodecTypeArray.length * kCodecPriorityArray.length * kSampleRateArray.length;
-        int right = kTotalConfigs / left;
-        int index = configId / right;
-        index = index % kSampleRateArray.length;
-        return kSampleRateArray[index];
-    }
-
-    private int selectBitsPerSample(int configId) {
-        int left = kCodecTypeArray.length * kCodecPriorityArray.length * kSampleRateArray.length *
-            kBitsPerSampleArray.length;
-        int right = kTotalConfigs / left;
-        int index = configId / right;
-        index = index % kBitsPerSampleArray.length;
-        return kBitsPerSampleArray[index];
-    }
-
-    private int selectChannelMode(int configId) {
-        int left = kCodecTypeArray.length * kCodecPriorityArray.length * kSampleRateArray.length *
-            kBitsPerSampleArray.length * kChannelModeArray.length;
-        int right = kTotalConfigs / left;
-        int index = configId / right;
-        index = index % kChannelModeArray.length;
-        return kChannelModeArray[index];
-    }
-
-    private long selectCodecSpecific1(int configId) {
-        int left = kCodecTypeArray.length * kCodecPriorityArray.length * kSampleRateArray.length *
-            kBitsPerSampleArray.length * kChannelModeArray.length * kCodecSpecific1Array.length;
-        int right = kTotalConfigs / left;
-        int index = configId / right;
-        index = index % kCodecSpecific1Array.length;
-        return kCodecSpecific1Array[index];
-    }
-
-    private long selectCodecSpecific2(int configId) {
-        int left = kCodecTypeArray.length * kCodecPriorityArray.length * kSampleRateArray.length *
-            kBitsPerSampleArray.length * kChannelModeArray.length * kCodecSpecific1Array.length *
-            kCodecSpecific2Array.length;
-        int right = kTotalConfigs / left;
-        int index = configId / right;
-        index = index % kCodecSpecific2Array.length;
-        return kCodecSpecific2Array[index];
-    }
-
-    private long selectCodecSpecific3(int configId) {
-        int left = kCodecTypeArray.length * kCodecPriorityArray.length * kSampleRateArray.length *
-            kBitsPerSampleArray.length * kChannelModeArray.length * kCodecSpecific1Array.length *
-            kCodecSpecific2Array.length * kCodecSpecific3Array.length;
-        int right = kTotalConfigs / left;
-        int index = configId / right;
-        index = index % kCodecSpecific3Array.length;
-        return kCodecSpecific3Array[index];
-    }
-
-    private long selectCodecSpecific4(int configId) {
-        int left = kCodecTypeArray.length * kCodecPriorityArray.length * kSampleRateArray.length *
-            kBitsPerSampleArray.length * kChannelModeArray.length * kCodecSpecific1Array.length *
-            kCodecSpecific2Array.length * kCodecSpecific3Array.length *
-            kCodecSpecific4Array.length;
-        int right = kTotalConfigs / left;
-        int index = configId / right;
-        index = index % kCodecSpecific4Array.length;
-        return kCodecSpecific4Array[index];
-    }
-
-    @SmallTest
-    public void testBluetoothCodecConfig_valid_get_methods() {
-
-        for (int config_id = 0; config_id < kTotalConfigs; config_id++) {
-            int codec_type = selectCodecType(config_id);
-            int codec_priority = selectCodecPriority(config_id);
-            int sample_rate = selectSampleRate(config_id);
-            int bits_per_sample = selectBitsPerSample(config_id);
-            int channel_mode = selectChannelMode(config_id);
-            long codec_specific1 = selectCodecSpecific1(config_id);
-            long codec_specific2 = selectCodecSpecific2(config_id);
-            long codec_specific3 = selectCodecSpecific3(config_id);
-            long codec_specific4 = selectCodecSpecific4(config_id);
-
-            BluetoothCodecConfig bcc = buildBluetoothCodecConfig(codec_type, codec_priority,
-                                                                sample_rate, bits_per_sample,
-                                                                channel_mode, codec_specific1,
-                                                                codec_specific2, codec_specific3,
-                                                                codec_specific4);
-
-            if (codec_type == BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC) {
-                assertTrue(bcc.isMandatoryCodec());
-            } else {
-                assertFalse(bcc.isMandatoryCodec());
-            }
-
-            if (codec_type == BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC) {
-                assertEquals("SBC", bcc.getCodecName());
-            }
-            if (codec_type == BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC) {
-                assertEquals("AAC", bcc.getCodecName());
-            }
-            if (codec_type == BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX) {
-                assertEquals("aptX", bcc.getCodecName());
-            }
-            if (codec_type == BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD) {
-                assertEquals("aptX HD", bcc.getCodecName());
-            }
-            if (codec_type == BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC) {
-                assertEquals("LDAC", bcc.getCodecName());
-            }
-            if (codec_type == BluetoothCodecConfig.SOURCE_CODEC_TYPE_INVALID) {
-                assertEquals("INVALID CODEC", bcc.getCodecName());
-            }
-
-            assertEquals(codec_type, bcc.getCodecType());
-            assertEquals(codec_priority, bcc.getCodecPriority());
-            assertEquals(sample_rate, bcc.getSampleRate());
-            assertEquals(bits_per_sample, bcc.getBitsPerSample());
-            assertEquals(channel_mode, bcc.getChannelMode());
-            assertEquals(codec_specific1, bcc.getCodecSpecific1());
-            assertEquals(codec_specific2, bcc.getCodecSpecific2());
-            assertEquals(codec_specific3, bcc.getCodecSpecific3());
-            assertEquals(codec_specific4, bcc.getCodecSpecific4());
-        }
-    }
-
-    @SmallTest
-    public void testBluetoothCodecConfig_equals() {
-        BluetoothCodecConfig bcc1 =
-                buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC,
-                                     BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT,
-                                     BluetoothCodecConfig.SAMPLE_RATE_44100,
-                                     BluetoothCodecConfig.BITS_PER_SAMPLE_16,
-                                     BluetoothCodecConfig.CHANNEL_MODE_STEREO,
-                                     1000, 2000, 3000, 4000);
-
-        BluetoothCodecConfig bcc2_same =
-                buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC,
-                                     BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT,
-                                     BluetoothCodecConfig.SAMPLE_RATE_44100,
-                                     BluetoothCodecConfig.BITS_PER_SAMPLE_16,
-                                     BluetoothCodecConfig.CHANNEL_MODE_STEREO,
-                                     1000, 2000, 3000, 4000);
-        assertTrue(bcc1.equals(bcc2_same));
-
-        BluetoothCodecConfig bcc3_codec_type =
-                buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC,
-                                     BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT,
-                                     BluetoothCodecConfig.SAMPLE_RATE_44100,
-                                     BluetoothCodecConfig.BITS_PER_SAMPLE_16,
-                                     BluetoothCodecConfig.CHANNEL_MODE_STEREO,
-                                     1000, 2000, 3000, 4000);
-        assertFalse(bcc1.equals(bcc3_codec_type));
-
-        BluetoothCodecConfig bcc4_codec_priority =
-                buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC,
-                                     BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST,
-                                     BluetoothCodecConfig.SAMPLE_RATE_44100,
-                                     BluetoothCodecConfig.BITS_PER_SAMPLE_16,
-                                     BluetoothCodecConfig.CHANNEL_MODE_STEREO,
-                                     1000, 2000, 3000, 4000);
-        assertFalse(bcc1.equals(bcc4_codec_priority));
-
-        BluetoothCodecConfig bcc5_sample_rate =
-                buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC,
-                                     BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT,
-                                     BluetoothCodecConfig.SAMPLE_RATE_48000,
-                                     BluetoothCodecConfig.BITS_PER_SAMPLE_16,
-                                     BluetoothCodecConfig.CHANNEL_MODE_STEREO,
-                                     1000, 2000, 3000, 4000);
-        assertFalse(bcc1.equals(bcc5_sample_rate));
-
-        BluetoothCodecConfig bcc6_bits_per_sample =
-                buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC,
-                                     BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT,
-                                     BluetoothCodecConfig.SAMPLE_RATE_44100,
-                                     BluetoothCodecConfig.BITS_PER_SAMPLE_24,
-                                     BluetoothCodecConfig.CHANNEL_MODE_STEREO,
-                                     1000, 2000, 3000, 4000);
-        assertFalse(bcc1.equals(bcc6_bits_per_sample));
-
-        BluetoothCodecConfig bcc7_channel_mode =
-                buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC,
-                                     BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT,
-                                     BluetoothCodecConfig.SAMPLE_RATE_44100,
-                                     BluetoothCodecConfig.BITS_PER_SAMPLE_16,
-                                     BluetoothCodecConfig.CHANNEL_MODE_MONO,
-                                     1000, 2000, 3000, 4000);
-        assertFalse(bcc1.equals(bcc7_channel_mode));
-
-        BluetoothCodecConfig bcc8_codec_specific1 =
-                buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC,
-                                     BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT,
-                                     BluetoothCodecConfig.SAMPLE_RATE_44100,
-                                     BluetoothCodecConfig.BITS_PER_SAMPLE_16,
-                                     BluetoothCodecConfig.CHANNEL_MODE_STEREO,
-                                     1001, 2000, 3000, 4000);
-        assertFalse(bcc1.equals(bcc8_codec_specific1));
-
-        BluetoothCodecConfig bcc9_codec_specific2 =
-                buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC,
-                                     BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT,
-                                     BluetoothCodecConfig.SAMPLE_RATE_44100,
-                                     BluetoothCodecConfig.BITS_PER_SAMPLE_16,
-                                     BluetoothCodecConfig.CHANNEL_MODE_STEREO,
-                                     1000, 2002, 3000, 4000);
-        assertFalse(bcc1.equals(bcc9_codec_specific2));
-
-        BluetoothCodecConfig bcc10_codec_specific3 =
-                buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC,
-                                     BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT,
-                                     BluetoothCodecConfig.SAMPLE_RATE_44100,
-                                     BluetoothCodecConfig.BITS_PER_SAMPLE_16,
-                                     BluetoothCodecConfig.CHANNEL_MODE_STEREO,
-                                     1000, 2000, 3003, 4000);
-        assertFalse(bcc1.equals(bcc10_codec_specific3));
-
-        BluetoothCodecConfig bcc11_codec_specific4 =
-                buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC,
-                                     BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT,
-                                     BluetoothCodecConfig.SAMPLE_RATE_44100,
-                                     BluetoothCodecConfig.BITS_PER_SAMPLE_16,
-                                     BluetoothCodecConfig.CHANNEL_MODE_STEREO,
-                                     1000, 2000, 3000, 4004);
-        assertFalse(bcc1.equals(bcc11_codec_specific4));
-    }
-
-    private BluetoothCodecConfig buildBluetoothCodecConfig(int sourceCodecType,
-            int codecPriority, int sampleRate, int bitsPerSample, int channelMode,
-            long codecSpecific1, long codecSpecific2, long codecSpecific3, long codecSpecific4) {
-        return new BluetoothCodecConfig.Builder()
-                    .setCodecType(sourceCodecType)
-                    .setCodecPriority(codecPriority)
-                    .setSampleRate(sampleRate)
-                    .setBitsPerSample(bitsPerSample)
-                    .setChannelMode(channelMode)
-                    .setCodecSpecific1(codecSpecific1)
-                    .setCodecSpecific2(codecSpecific2)
-                    .setCodecSpecific3(codecSpecific3)
-                    .setCodecSpecific4(codecSpecific4)
-                    .build();
-
-    }
-}
diff --git a/core/tests/bluetoothtests/src/android/bluetooth/BluetoothCodecStatusTest.java b/core/tests/bluetoothtests/src/android/bluetooth/BluetoothCodecStatusTest.java
deleted file mode 100644
index 1cb2dca..0000000
--- a/core/tests/bluetoothtests/src/android/bluetooth/BluetoothCodecStatusTest.java
+++ /dev/null
@@ -1,493 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-import android.test.suitebuilder.annotation.SmallTest;
-
-import junit.framework.TestCase;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-
-/**
- * Unit test cases for {@link BluetoothCodecStatus}.
- * <p>
- * To run this test, use:
- * runtest --path core/tests/bluetoothtests/src/android/bluetooth/BluetoothCodecStatusTest.java
- */
-public class BluetoothCodecStatusTest extends TestCase {
-
-    // Codec configs: A and B are same; C is different
-    private static final BluetoothCodecConfig config_A =
-            buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC,
-                                 BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT,
-                                 BluetoothCodecConfig.SAMPLE_RATE_44100,
-                                 BluetoothCodecConfig.BITS_PER_SAMPLE_16,
-                                 BluetoothCodecConfig.CHANNEL_MODE_STEREO,
-                                 1000, 2000, 3000, 4000);
-
-    private static final BluetoothCodecConfig config_B =
-            buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC,
-                                 BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT,
-                                 BluetoothCodecConfig.SAMPLE_RATE_44100,
-                                 BluetoothCodecConfig.BITS_PER_SAMPLE_16,
-                                 BluetoothCodecConfig.CHANNEL_MODE_STEREO,
-                                 1000, 2000, 3000, 4000);
-
-    private static final BluetoothCodecConfig config_C =
-            buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC,
-                                 BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT,
-                                 BluetoothCodecConfig.SAMPLE_RATE_44100,
-                                 BluetoothCodecConfig.BITS_PER_SAMPLE_16,
-                                 BluetoothCodecConfig.CHANNEL_MODE_STEREO,
-                                 1000, 2000, 3000, 4000);
-
-    // Local capabilities: A and B are same; C is different
-    private static final BluetoothCodecConfig local_capability1_A =
-            buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC,
-                                 BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT,
-                                 BluetoothCodecConfig.SAMPLE_RATE_44100 |
-                                 BluetoothCodecConfig.SAMPLE_RATE_48000,
-                                 BluetoothCodecConfig.BITS_PER_SAMPLE_16,
-                                 BluetoothCodecConfig.CHANNEL_MODE_STEREO |
-                                 BluetoothCodecConfig.CHANNEL_MODE_MONO,
-                                 1000, 2000, 3000, 4000);
-
-    private static final BluetoothCodecConfig local_capability1_B =
-            buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC,
-                                 BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT,
-                                 BluetoothCodecConfig.SAMPLE_RATE_44100 |
-                                 BluetoothCodecConfig.SAMPLE_RATE_48000,
-                                 BluetoothCodecConfig.BITS_PER_SAMPLE_16,
-                                 BluetoothCodecConfig.CHANNEL_MODE_STEREO |
-                                 BluetoothCodecConfig.CHANNEL_MODE_MONO,
-                                 1000, 2000, 3000, 4000);
-
-    private static final BluetoothCodecConfig local_capability1_C =
-            buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC,
-                                 BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT,
-                                 BluetoothCodecConfig.SAMPLE_RATE_44100 |
-                                 BluetoothCodecConfig.SAMPLE_RATE_48000,
-                                 BluetoothCodecConfig.BITS_PER_SAMPLE_16,
-                                 BluetoothCodecConfig.CHANNEL_MODE_STEREO,
-                                 1000, 2000, 3000, 4000);
-
-
-    private static final BluetoothCodecConfig local_capability2_A =
-            buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC,
-                                 BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT,
-                                 BluetoothCodecConfig.SAMPLE_RATE_44100 |
-                                 BluetoothCodecConfig.SAMPLE_RATE_48000,
-                                 BluetoothCodecConfig.BITS_PER_SAMPLE_16,
-                                 BluetoothCodecConfig.CHANNEL_MODE_STEREO |
-                                 BluetoothCodecConfig.CHANNEL_MODE_MONO,
-                                 1000, 2000, 3000, 4000);
-
-    private static final BluetoothCodecConfig local_capability2_B =
-            buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC,
-                                 BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT,
-                                 BluetoothCodecConfig.SAMPLE_RATE_44100 |
-                                 BluetoothCodecConfig.SAMPLE_RATE_48000,
-                                 BluetoothCodecConfig.BITS_PER_SAMPLE_16,
-                                 BluetoothCodecConfig.CHANNEL_MODE_STEREO |
-                                 BluetoothCodecConfig.CHANNEL_MODE_MONO,
-                                 1000, 2000, 3000, 4000);
-
-    private static final BluetoothCodecConfig local_capability2_C =
-            buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC,
-                                 BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT,
-                                 BluetoothCodecConfig.SAMPLE_RATE_44100 |
-                                 BluetoothCodecConfig.SAMPLE_RATE_48000,
-                                 BluetoothCodecConfig.BITS_PER_SAMPLE_16,
-                                 BluetoothCodecConfig.CHANNEL_MODE_STEREO,
-                                 1000, 2000, 3000, 4000);
-
-    private static final BluetoothCodecConfig local_capability3_A =
-            buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX,
-                                 BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT,
-                                 BluetoothCodecConfig.SAMPLE_RATE_44100 |
-                                 BluetoothCodecConfig.SAMPLE_RATE_48000,
-                                 BluetoothCodecConfig.BITS_PER_SAMPLE_16,
-                                 BluetoothCodecConfig.CHANNEL_MODE_STEREO |
-                                 BluetoothCodecConfig.CHANNEL_MODE_MONO,
-                                 1000, 2000, 3000, 4000);
-
-    private static final BluetoothCodecConfig local_capability3_B =
-            buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX,
-                                 BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT,
-                                 BluetoothCodecConfig.SAMPLE_RATE_44100 |
-                                 BluetoothCodecConfig.SAMPLE_RATE_48000,
-                                 BluetoothCodecConfig.BITS_PER_SAMPLE_16,
-                                 BluetoothCodecConfig.CHANNEL_MODE_STEREO |
-                                 BluetoothCodecConfig.CHANNEL_MODE_MONO,
-                                 1000, 2000, 3000, 4000);
-
-    private static final BluetoothCodecConfig local_capability3_C =
-            buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX,
-                                 BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT,
-                                 BluetoothCodecConfig.SAMPLE_RATE_44100 |
-                                 BluetoothCodecConfig.SAMPLE_RATE_48000,
-                                 BluetoothCodecConfig.BITS_PER_SAMPLE_16,
-                                 BluetoothCodecConfig.CHANNEL_MODE_STEREO,
-                                 1000, 2000, 3000, 4000);
-
-    private static final BluetoothCodecConfig local_capability4_A =
-            buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD,
-                                 BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT,
-                                 BluetoothCodecConfig.SAMPLE_RATE_44100 |
-                                 BluetoothCodecConfig.SAMPLE_RATE_48000,
-                                 BluetoothCodecConfig.BITS_PER_SAMPLE_24,
-                                 BluetoothCodecConfig.CHANNEL_MODE_STEREO |
-                                 BluetoothCodecConfig.CHANNEL_MODE_MONO,
-                                 1000, 2000, 3000, 4000);
-
-    private static final BluetoothCodecConfig local_capability4_B =
-            buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD,
-                                 BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT,
-                                 BluetoothCodecConfig.SAMPLE_RATE_44100 |
-                                 BluetoothCodecConfig.SAMPLE_RATE_48000,
-                                 BluetoothCodecConfig.BITS_PER_SAMPLE_24,
-                                 BluetoothCodecConfig.CHANNEL_MODE_STEREO |
-                                 BluetoothCodecConfig.CHANNEL_MODE_MONO,
-                                 1000, 2000, 3000, 4000);
-
-    private static final BluetoothCodecConfig local_capability4_C =
-            buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD,
-                                 BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT,
-                                 BluetoothCodecConfig.SAMPLE_RATE_44100 |
-                                 BluetoothCodecConfig.SAMPLE_RATE_48000,
-                                 BluetoothCodecConfig.BITS_PER_SAMPLE_24,
-                                 BluetoothCodecConfig.CHANNEL_MODE_STEREO,
-                                 1000, 2000, 3000, 4000);
-
-    private static final BluetoothCodecConfig local_capability5_A =
-            buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC,
-                                 BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT,
-                                 BluetoothCodecConfig.SAMPLE_RATE_44100 |
-                                 BluetoothCodecConfig.SAMPLE_RATE_48000 |
-                                 BluetoothCodecConfig.SAMPLE_RATE_88200 |
-                                 BluetoothCodecConfig.SAMPLE_RATE_96000,
-                                 BluetoothCodecConfig.BITS_PER_SAMPLE_16 |
-                                 BluetoothCodecConfig.BITS_PER_SAMPLE_24 |
-                                 BluetoothCodecConfig.BITS_PER_SAMPLE_32,
-                                 BluetoothCodecConfig.CHANNEL_MODE_STEREO |
-                                 BluetoothCodecConfig.CHANNEL_MODE_MONO,
-                                 1000, 2000, 3000, 4000);
-
-    private static final BluetoothCodecConfig local_capability5_B =
-            buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC,
-                                 BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT,
-                                 BluetoothCodecConfig.SAMPLE_RATE_44100 |
-                                 BluetoothCodecConfig.SAMPLE_RATE_48000 |
-                                 BluetoothCodecConfig.SAMPLE_RATE_88200 |
-                                 BluetoothCodecConfig.SAMPLE_RATE_96000,
-                                 BluetoothCodecConfig.BITS_PER_SAMPLE_16 |
-                                 BluetoothCodecConfig.BITS_PER_SAMPLE_24 |
-                                 BluetoothCodecConfig.BITS_PER_SAMPLE_32,
-                                 BluetoothCodecConfig.CHANNEL_MODE_STEREO |
-                                 BluetoothCodecConfig.CHANNEL_MODE_MONO,
-                                 1000, 2000, 3000, 4000);
-
-    private static final BluetoothCodecConfig local_capability5_C =
-            buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC,
-                                 BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT,
-                                 BluetoothCodecConfig.SAMPLE_RATE_44100 |
-                                 BluetoothCodecConfig.SAMPLE_RATE_48000 |
-                                 BluetoothCodecConfig.SAMPLE_RATE_88200 |
-                                 BluetoothCodecConfig.SAMPLE_RATE_96000,
-                                 BluetoothCodecConfig.BITS_PER_SAMPLE_16 |
-                                 BluetoothCodecConfig.BITS_PER_SAMPLE_24 |
-                                 BluetoothCodecConfig.BITS_PER_SAMPLE_32,
-                                 BluetoothCodecConfig.CHANNEL_MODE_STEREO,
-                                 1000, 2000, 3000, 4000);
-
-
-    // Selectable capabilities: A and B are same; C is different
-    private static final BluetoothCodecConfig selectable_capability1_A =
-            buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC,
-                                 BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT,
-                                 BluetoothCodecConfig.SAMPLE_RATE_44100,
-                                 BluetoothCodecConfig.BITS_PER_SAMPLE_16,
-                                 BluetoothCodecConfig.CHANNEL_MODE_STEREO |
-                                 BluetoothCodecConfig.CHANNEL_MODE_MONO,
-                                 1000, 2000, 3000, 4000);
-
-    private static final BluetoothCodecConfig selectable_capability1_B =
-            buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC,
-                                 BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT,
-                                 BluetoothCodecConfig.SAMPLE_RATE_44100,
-                                 BluetoothCodecConfig.BITS_PER_SAMPLE_16,
-                                 BluetoothCodecConfig.CHANNEL_MODE_STEREO |
-                                 BluetoothCodecConfig.CHANNEL_MODE_MONO,
-                                 1000, 2000, 3000, 4000);
-
-    private static final BluetoothCodecConfig selectable_capability1_C =
-            buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC,
-                                 BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT,
-                                 BluetoothCodecConfig.SAMPLE_RATE_44100,
-                                 BluetoothCodecConfig.BITS_PER_SAMPLE_16,
-                                 BluetoothCodecConfig.CHANNEL_MODE_STEREO,
-                                 1000, 2000, 3000, 4000);
-
-    private static final BluetoothCodecConfig selectable_capability2_A =
-            buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC,
-                                 BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT,
-                                 BluetoothCodecConfig.SAMPLE_RATE_44100,
-                                 BluetoothCodecConfig.BITS_PER_SAMPLE_16,
-                                 BluetoothCodecConfig.CHANNEL_MODE_STEREO |
-                                 BluetoothCodecConfig.CHANNEL_MODE_MONO,
-                                 1000, 2000, 3000, 4000);
-
-    private static final BluetoothCodecConfig selectable_capability2_B =
-            buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC,
-                                 BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT,
-                                 BluetoothCodecConfig.SAMPLE_RATE_44100,
-                                 BluetoothCodecConfig.BITS_PER_SAMPLE_16,
-                                 BluetoothCodecConfig.CHANNEL_MODE_STEREO |
-                                 BluetoothCodecConfig.CHANNEL_MODE_MONO,
-                                 1000, 2000, 3000, 4000);
-
-    private static final BluetoothCodecConfig selectable_capability2_C =
-            buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC,
-                                 BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT,
-                                 BluetoothCodecConfig.SAMPLE_RATE_44100,
-                                 BluetoothCodecConfig.BITS_PER_SAMPLE_16,
-                                 BluetoothCodecConfig.CHANNEL_MODE_STEREO,
-                                 1000, 2000, 3000, 4000);
-
-    private static final BluetoothCodecConfig selectable_capability3_A =
-            buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX,
-                                 BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT,
-                                 BluetoothCodecConfig.SAMPLE_RATE_44100,
-                                 BluetoothCodecConfig.BITS_PER_SAMPLE_16,
-                                 BluetoothCodecConfig.CHANNEL_MODE_STEREO |
-                                 BluetoothCodecConfig.CHANNEL_MODE_MONO,
-                                 1000, 2000, 3000, 4000);
-
-    private static final BluetoothCodecConfig selectable_capability3_B =
-            buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX,
-                                 BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT,
-                                 BluetoothCodecConfig.SAMPLE_RATE_44100,
-                                 BluetoothCodecConfig.BITS_PER_SAMPLE_16,
-                                 BluetoothCodecConfig.CHANNEL_MODE_STEREO |
-                                 BluetoothCodecConfig.CHANNEL_MODE_MONO,
-                                 1000, 2000, 3000, 4000);
-
-    private static final BluetoothCodecConfig selectable_capability3_C =
-            buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX,
-                                 BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT,
-                                 BluetoothCodecConfig.SAMPLE_RATE_44100,
-                                 BluetoothCodecConfig.BITS_PER_SAMPLE_16,
-                                 BluetoothCodecConfig.CHANNEL_MODE_STEREO,
-                                 1000, 2000, 3000, 4000);
-
-    private static final BluetoothCodecConfig selectable_capability4_A =
-            buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD,
-                                 BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT,
-                                 BluetoothCodecConfig.SAMPLE_RATE_44100,
-                                 BluetoothCodecConfig.BITS_PER_SAMPLE_24,
-                                 BluetoothCodecConfig.CHANNEL_MODE_STEREO |
-                                 BluetoothCodecConfig.CHANNEL_MODE_MONO,
-                                 1000, 2000, 3000, 4000);
-
-    private static final BluetoothCodecConfig selectable_capability4_B =
-            buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD,
-                                 BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT,
-                                 BluetoothCodecConfig.SAMPLE_RATE_44100,
-                                 BluetoothCodecConfig.BITS_PER_SAMPLE_24,
-                                 BluetoothCodecConfig.CHANNEL_MODE_STEREO |
-                                 BluetoothCodecConfig.CHANNEL_MODE_MONO,
-                                 1000, 2000, 3000, 4000);
-
-    private static final BluetoothCodecConfig selectable_capability4_C =
-            buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD,
-                                 BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT,
-                                 BluetoothCodecConfig.SAMPLE_RATE_44100,
-                                 BluetoothCodecConfig.BITS_PER_SAMPLE_24,
-                                 BluetoothCodecConfig.CHANNEL_MODE_STEREO,
-                                 1000, 2000, 3000, 4000);
-
-    private static final BluetoothCodecConfig selectable_capability5_A =
-            buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC,
-                                 BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT,
-                                 BluetoothCodecConfig.SAMPLE_RATE_44100 |
-                                 BluetoothCodecConfig.SAMPLE_RATE_48000 |
-                                 BluetoothCodecConfig.SAMPLE_RATE_88200 |
-                                 BluetoothCodecConfig.SAMPLE_RATE_96000,
-                                 BluetoothCodecConfig.BITS_PER_SAMPLE_16 |
-                                 BluetoothCodecConfig.BITS_PER_SAMPLE_24 |
-                                 BluetoothCodecConfig.BITS_PER_SAMPLE_32,
-                                 BluetoothCodecConfig.CHANNEL_MODE_STEREO |
-                                 BluetoothCodecConfig.CHANNEL_MODE_MONO,
-                                 1000, 2000, 3000, 4000);
-
-    private static final BluetoothCodecConfig selectable_capability5_B =
-            buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC,
-                                 BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT,
-                                 BluetoothCodecConfig.SAMPLE_RATE_44100 |
-                                 BluetoothCodecConfig.SAMPLE_RATE_48000 |
-                                 BluetoothCodecConfig.SAMPLE_RATE_88200 |
-                                 BluetoothCodecConfig.SAMPLE_RATE_96000,
-                                 BluetoothCodecConfig.BITS_PER_SAMPLE_16 |
-                                 BluetoothCodecConfig.BITS_PER_SAMPLE_24 |
-                                 BluetoothCodecConfig.BITS_PER_SAMPLE_32,
-                                 BluetoothCodecConfig.CHANNEL_MODE_STEREO |
-                                 BluetoothCodecConfig.CHANNEL_MODE_MONO,
-                                 1000, 2000, 3000, 4000);
-
-    private static final BluetoothCodecConfig selectable_capability5_C =
-            buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC,
-                                 BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT,
-                                 BluetoothCodecConfig.SAMPLE_RATE_44100 |
-                                 BluetoothCodecConfig.SAMPLE_RATE_48000 |
-                                 BluetoothCodecConfig.SAMPLE_RATE_88200 |
-                                 BluetoothCodecConfig.SAMPLE_RATE_96000,
-                                 BluetoothCodecConfig.BITS_PER_SAMPLE_16 |
-                                 BluetoothCodecConfig.BITS_PER_SAMPLE_24 |
-                                 BluetoothCodecConfig.BITS_PER_SAMPLE_32,
-                                 BluetoothCodecConfig.CHANNEL_MODE_STEREO,
-                                 1000, 2000, 3000, 4000);
-
-    private static final List<BluetoothCodecConfig> LOCAL_CAPABILITY_A =
-            new ArrayList() {{
-                    add(local_capability1_A);
-                    add(local_capability2_A);
-                    add(local_capability3_A);
-                    add(local_capability4_A);
-                    add(local_capability5_A);
-            }};
-
-    private static final List<BluetoothCodecConfig> LOCAL_CAPABILITY_B =
-            new ArrayList() {{
-                    add(local_capability1_B);
-                    add(local_capability2_B);
-                    add(local_capability3_B);
-                    add(local_capability4_B);
-                    add(local_capability5_B);
-            }};
-
-    private static final List<BluetoothCodecConfig> LOCAL_CAPABILITY_B_REORDERED =
-            new ArrayList() {{
-                    add(local_capability5_B);
-                    add(local_capability4_B);
-                    add(local_capability2_B);
-                    add(local_capability3_B);
-                    add(local_capability1_B);
-            }};
-
-    private static final List<BluetoothCodecConfig> LOCAL_CAPABILITY_C =
-            new ArrayList() {{
-                    add(local_capability1_C);
-                    add(local_capability2_C);
-                    add(local_capability3_C);
-                    add(local_capability4_C);
-                    add(local_capability5_C);
-            }};
-
-    private static final List<BluetoothCodecConfig> SELECTABLE_CAPABILITY_A =
-            new ArrayList() {{
-                    add(selectable_capability1_A);
-                    add(selectable_capability2_A);
-                    add(selectable_capability3_A);
-                    add(selectable_capability4_A);
-                    add(selectable_capability5_A);
-            }};
-
-    private static final List<BluetoothCodecConfig> SELECTABLE_CAPABILITY_B =
-            new ArrayList() {{
-                    add(selectable_capability1_B);
-                    add(selectable_capability2_B);
-                    add(selectable_capability3_B);
-                    add(selectable_capability4_B);
-                    add(selectable_capability5_B);
-            }};
-
-    private static final List<BluetoothCodecConfig> SELECTABLE_CAPABILITY_B_REORDERED =
-            new ArrayList() {{
-                    add(selectable_capability5_B);
-                    add(selectable_capability4_B);
-                    add(selectable_capability2_B);
-                    add(selectable_capability3_B);
-                    add(selectable_capability1_B);
-            }};
-
-    private static final List<BluetoothCodecConfig> SELECTABLE_CAPABILITY_C =
-            new ArrayList() {{
-                    add(selectable_capability1_C);
-                    add(selectable_capability2_C);
-                    add(selectable_capability3_C);
-                    add(selectable_capability4_C);
-                    add(selectable_capability5_C);
-            }};
-
-    private static final BluetoothCodecStatus bcs_A =
-            new BluetoothCodecStatus(config_A, LOCAL_CAPABILITY_A, SELECTABLE_CAPABILITY_A);
-    private static final BluetoothCodecStatus bcs_B =
-            new BluetoothCodecStatus(config_B, LOCAL_CAPABILITY_B, SELECTABLE_CAPABILITY_B);
-    private static final BluetoothCodecStatus bcs_B_reordered =
-            new BluetoothCodecStatus(config_B, LOCAL_CAPABILITY_B_REORDERED,
-                                 SELECTABLE_CAPABILITY_B_REORDERED);
-    private static final BluetoothCodecStatus bcs_C =
-            new BluetoothCodecStatus(config_C, LOCAL_CAPABILITY_C, SELECTABLE_CAPABILITY_C);
-
-    @SmallTest
-    public void testBluetoothCodecStatus_get_methods() {
-
-        assertTrue(Objects.equals(bcs_A.getCodecConfig(), config_A));
-        assertTrue(Objects.equals(bcs_A.getCodecConfig(), config_B));
-        assertFalse(Objects.equals(bcs_A.getCodecConfig(), config_C));
-
-        assertTrue(bcs_A.getCodecsLocalCapabilities().equals(LOCAL_CAPABILITY_A));
-        assertTrue(bcs_A.getCodecsLocalCapabilities().equals(LOCAL_CAPABILITY_B));
-        assertFalse(bcs_A.getCodecsLocalCapabilities().equals(LOCAL_CAPABILITY_C));
-
-        assertTrue(bcs_A.getCodecsSelectableCapabilities()
-                                 .equals(SELECTABLE_CAPABILITY_A));
-        assertTrue(bcs_A.getCodecsSelectableCapabilities()
-                                  .equals(SELECTABLE_CAPABILITY_B));
-        assertFalse(bcs_A.getCodecsSelectableCapabilities()
-                                  .equals(SELECTABLE_CAPABILITY_C));
-    }
-
-    @SmallTest
-    public void testBluetoothCodecStatus_equals() {
-        assertTrue(bcs_A.equals(bcs_B));
-        assertTrue(bcs_B.equals(bcs_A));
-        assertTrue(bcs_A.equals(bcs_B_reordered));
-        assertTrue(bcs_B_reordered.equals(bcs_A));
-        assertFalse(bcs_A.equals(bcs_C));
-        assertFalse(bcs_C.equals(bcs_A));
-    }
-
-    private static BluetoothCodecConfig buildBluetoothCodecConfig(int sourceCodecType,
-            int codecPriority, int sampleRate, int bitsPerSample, int channelMode,
-            long codecSpecific1, long codecSpecific2, long codecSpecific3, long codecSpecific4) {
-        return new BluetoothCodecConfig.Builder()
-                    .setCodecType(sourceCodecType)
-                    .setCodecPriority(codecPriority)
-                    .setSampleRate(sampleRate)
-                    .setBitsPerSample(bitsPerSample)
-                    .setChannelMode(channelMode)
-                    .setCodecSpecific1(codecSpecific1)
-                    .setCodecSpecific2(codecSpecific2)
-                    .setCodecSpecific3(codecSpecific3)
-                    .setCodecSpecific4(codecSpecific4)
-                    .build();
-
-    }
-}
diff --git a/core/tests/bluetoothtests/src/android/bluetooth/BluetoothInstrumentation.java b/core/tests/bluetoothtests/src/android/bluetooth/BluetoothInstrumentation.java
deleted file mode 100644
index 37b2a50..0000000
--- a/core/tests/bluetoothtests/src/android/bluetooth/BluetoothInstrumentation.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.bluetooth;
-
-import android.app.Activity;
-import android.app.Instrumentation;
-import android.content.Context;
-import android.os.Bundle;
-
-import junit.framework.Assert;
-
-import java.util.Set;
-
-public class BluetoothInstrumentation extends Instrumentation {
-
-    private BluetoothTestUtils mUtils = null;
-    private BluetoothAdapter mAdapter = null;
-    private Bundle mArgs = null;
-    private Bundle mSuccessResult = null;
-
-    private BluetoothTestUtils getBluetoothTestUtils() {
-        if (mUtils == null) {
-            mUtils = new BluetoothTestUtils(getContext(),
-                    BluetoothInstrumentation.class.getSimpleName());
-        }
-        return mUtils;
-    }
-
-    private BluetoothAdapter getBluetoothAdapter() {
-        if (mAdapter == null) {
-            mAdapter = ((BluetoothManager)getContext().getSystemService(
-                    Context.BLUETOOTH_SERVICE)).getAdapter();
-        }
-        return mAdapter;
-    }
-
-    @Override
-    public void onCreate(Bundle arguments) {
-        super.onCreate(arguments);
-        mArgs = arguments;
-        // create the default result response, but only use it in success code path
-        mSuccessResult = new Bundle();
-        mSuccessResult.putString("result", "SUCCESS");
-        start();
-    }
-
-    @Override
-    public void onStart() {
-        String command = mArgs.getString("command");
-        if ("enable".equals(command)) {
-            enable();
-        } else if ("disable".equals(command)) {
-            disable();
-        } else if ("unpairAll".equals(command)) {
-            unpairAll();
-        } else if ("getName".equals(command)) {
-            getName();
-        } else if ("getAddress".equals(command)) {
-            getAddress();
-        } else if ("getBondedDevices".equals(command)) {
-            getBondedDevices();
-        } else {
-            finish(null);
-        }
-    }
-
-    public void enable() {
-        getBluetoothTestUtils().enable(getBluetoothAdapter());
-        finish(mSuccessResult);
-    }
-
-    public void disable() {
-        getBluetoothTestUtils().disable(getBluetoothAdapter());
-        finish(mSuccessResult);
-    }
-
-    public void unpairAll() {
-        getBluetoothTestUtils().unpairAll(getBluetoothAdapter());
-        finish(mSuccessResult);
-    }
-
-    public void getName() {
-        String name = getBluetoothAdapter().getName();
-        mSuccessResult.putString("name", name);
-        finish(mSuccessResult);
-    }
-
-    public void getAddress() {
-        String name = getBluetoothAdapter().getAddress();
-        mSuccessResult.putString("address", name);
-        finish(mSuccessResult);
-    }
-
-    public void getBondedDevices() {
-        Set<BluetoothDevice> devices = getBluetoothAdapter().getBondedDevices();
-        int i = 0;
-        for (BluetoothDevice device : devices) {
-            mSuccessResult.putString(String.format("device-%02d", i), device.getAddress());
-            i++;
-        }
-        finish(mSuccessResult);
-    }
-
-    public void finish(Bundle result) {
-        if (result == null) {
-            result = new Bundle();
-        }
-        finish(Activity.RESULT_OK, result);
-    }
-}
diff --git a/core/tests/bluetoothtests/src/android/bluetooth/BluetoothLeAudioCodecConfigTest.java b/core/tests/bluetoothtests/src/android/bluetooth/BluetoothLeAudioCodecConfigTest.java
deleted file mode 100644
index c3d707c..0000000
--- a/core/tests/bluetoothtests/src/android/bluetooth/BluetoothLeAudioCodecConfigTest.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-import android.test.suitebuilder.annotation.SmallTest;
-
-import junit.framework.TestCase;
-
-/**
- * Unit test cases for {@link BluetoothLeAudioCodecConfig}.
- */
-public class BluetoothLeAudioCodecConfigTest extends TestCase {
-    private int[] mCodecTypeArray = new int[] {
-        BluetoothLeAudioCodecConfig.SOURCE_CODEC_TYPE_LC3,
-        BluetoothLeAudioCodecConfig.SOURCE_CODEC_TYPE_INVALID,
-    };
-
-    @SmallTest
-    public void testBluetoothLeAudioCodecConfig_valid_get_methods() {
-
-        for (int codecIdx = 0; codecIdx < mCodecTypeArray.length; codecIdx++) {
-            int codecType = mCodecTypeArray[codecIdx];
-
-            BluetoothLeAudioCodecConfig leAudioCodecConfig =
-                    buildBluetoothLeAudioCodecConfig(codecType);
-
-            if (codecType == BluetoothLeAudioCodecConfig.SOURCE_CODEC_TYPE_LC3) {
-                assertEquals("LC3", leAudioCodecConfig.getCodecName());
-            }
-            if (codecType == BluetoothLeAudioCodecConfig.SOURCE_CODEC_TYPE_INVALID) {
-                assertEquals("INVALID CODEC", leAudioCodecConfig.getCodecName());
-            }
-
-            assertEquals(codecType, leAudioCodecConfig.getCodecType());
-        }
-    }
-
-    private BluetoothLeAudioCodecConfig buildBluetoothLeAudioCodecConfig(int sourceCodecType) {
-        return new BluetoothLeAudioCodecConfig.Builder()
-                    .setCodecType(sourceCodecType)
-                    .build();
-
-    }
-}
diff --git a/core/tests/bluetoothtests/src/android/bluetooth/BluetoothRebootStressTest.java b/core/tests/bluetoothtests/src/android/bluetooth/BluetoothRebootStressTest.java
deleted file mode 100644
index 33e9dd7..0000000
--- a/core/tests/bluetoothtests/src/android/bluetooth/BluetoothRebootStressTest.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-import android.content.Context;
-import android.test.InstrumentationTestCase;
-
-/**
- * Instrumentation test case for stress test involving rebooting the device.
- * <p>
- * This test case tests that bluetooth is enabled after a device reboot. Because
- * the device will reboot, the instrumentation must be driven by a script on the
- * host side.
- */
-public class BluetoothRebootStressTest extends InstrumentationTestCase {
-    private static final String TAG = "BluetoothRebootStressTest";
-    private static final String OUTPUT_FILE = "BluetoothRebootStressTestOutput.txt";
-
-    private BluetoothTestUtils mTestUtils;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-
-        Context context = getInstrumentation().getTargetContext();
-        mTestUtils = new BluetoothTestUtils(context, TAG, OUTPUT_FILE);
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-
-        mTestUtils.close();
-    }
-
-    /**
-     * Test method used to start the test by turning bluetooth on.
-     */
-    public void testStart() {
-        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
-        mTestUtils.enable(adapter);
-    }
-
-    /**
-     * Test method used in the middle iterations of the test to check if
-     * bluetooth is on. Does not toggle bluetooth after the check. Assumes that
-     * bluetooth has been turned on by {@code #testStart()}
-     */
-    public void testMiddleNoToggle() {
-        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
-
-        assertTrue(adapter.isEnabled());
-    }
-
-    /**
-     * Test method used in the middle iterations of the test to check if
-     * bluetooth is on. Toggles bluetooth after the check. Assumes that
-     * bluetooth has been turned on by {@code #testStart()}
-     */
-    public void testMiddleToggle() {
-        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
-
-        assertTrue(adapter.isEnabled());
-
-        mTestUtils.disable(adapter);
-        mTestUtils.enable(adapter);
-    }
-
-    /**
-     * Test method used in the stop the test by turning bluetooth off. Assumes
-     * that bluetooth has been turned on by {@code #testStart()}
-     */
-    public void testStop() {
-        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
-
-        assertTrue(adapter.isEnabled());
-
-        mTestUtils.disable(adapter);
-    }
-}
diff --git a/core/tests/bluetoothtests/src/android/bluetooth/BluetoothStressTest.java b/core/tests/bluetoothtests/src/android/bluetooth/BluetoothStressTest.java
deleted file mode 100644
index 89dbe3f..0000000
--- a/core/tests/bluetoothtests/src/android/bluetooth/BluetoothStressTest.java
+++ /dev/null
@@ -1,393 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-import android.content.Context;
-import android.test.InstrumentationTestCase;
-
-/**
- * Stress test suite for Bluetooth related functions.
- *
- * Includes tests for enabling/disabling bluetooth, enabling/disabling discoverable mode,
- * starting/stopping scans, connecting/disconnecting to HFP, A2DP, HID, PAN profiles, and verifying
- * that remote connections/disconnections occur for the PAN profile.
- * <p>
- * This test suite uses {@link android.bluetooth.BluetoothTestRunner} to for parameters such as the
- * number of iterations and the addresses of remote Bluetooth devices.
- */
-public class BluetoothStressTest extends InstrumentationTestCase {
-    private static final String TAG = "BluetoothStressTest";
-    private static final String OUTPUT_FILE = "BluetoothStressTestOutput.txt";
-    /** The amount of time to sleep between issuing start/stop SCO in ms. */
-    private static final long SCO_SLEEP_TIME = 2 * 1000;
-
-    private BluetoothAdapter mAdapter;
-    private BluetoothTestUtils mTestUtils;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-
-        Context context = getInstrumentation().getTargetContext();
-        mAdapter = BluetoothAdapter.getDefaultAdapter();
-        mTestUtils = new BluetoothTestUtils(context, TAG, OUTPUT_FILE);
-
-        // Start all tests in a disabled state.
-        if (mAdapter.isEnabled()) {
-            mTestUtils.disable(mAdapter);
-        }
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-        mTestUtils.close();
-    }
-
-    /**
-     * Stress test for enabling and disabling Bluetooth.
-     */
-    public void testEnable() {
-        int iterations = BluetoothTestRunner.sEnableIterations;
-        if (iterations == 0) {
-            return;
-        }
-
-        for (int i = 0; i < iterations; i++) {
-            mTestUtils.writeOutput("enable iteration " + (i + 1) + " of " + iterations);
-            mTestUtils.enable(mAdapter);
-            mTestUtils.disable(mAdapter);
-        }
-    }
-
-    /**
-     * Stress test for putting the device in and taking the device out of discoverable mode.
-     */
-    public void testDiscoverable() {
-        int iterations = BluetoothTestRunner.sDiscoverableIterations;
-        if (iterations == 0) {
-            return;
-        }
-
-        mTestUtils.enable(mAdapter);
-        mTestUtils.undiscoverable(mAdapter);
-
-        for (int i = 0; i < iterations; i++) {
-            mTestUtils.writeOutput("discoverable iteration " + (i + 1) + " of " + iterations);
-            mTestUtils.discoverable(mAdapter);
-            mTestUtils.undiscoverable(mAdapter);
-        }
-    }
-
-    /**
-     * Stress test for starting and stopping Bluetooth scans.
-     */
-    public void testScan() {
-        int iterations = BluetoothTestRunner.sScanIterations;
-        if (iterations == 0) {
-            return;
-        }
-
-        mTestUtils.enable(mAdapter);
-        mTestUtils.stopScan(mAdapter);
-
-        for (int i = 0; i < iterations; i++) {
-            mTestUtils.writeOutput("scan iteration " + (i + 1) + " of " + iterations);
-            mTestUtils.startScan(mAdapter);
-            mTestUtils.stopScan(mAdapter);
-        }
-    }
-
-    /**
-     * Stress test for enabling and disabling the PAN NAP profile.
-     */
-    public void testEnablePan() {
-        int iterations = BluetoothTestRunner.sEnablePanIterations;
-        if (iterations == 0) {
-            return;
-        }
-
-        mTestUtils.enable(mAdapter);
-        mTestUtils.disablePan(mAdapter);
-
-        for (int i = 0; i < iterations; i++) {
-            mTestUtils.writeOutput("testEnablePan iteration " + (i + 1) + " of "
-                    + iterations);
-            mTestUtils.enablePan(mAdapter);
-            mTestUtils.disablePan(mAdapter);
-        }
-    }
-
-    /**
-     * Stress test for pairing and unpairing with a remote device.
-     * <p>
-     * In this test, the local device initiates pairing with a remote device, and then unpairs with
-     * the device after the pairing has successfully completed.
-     */
-    public void testPair() {
-        int iterations = BluetoothTestRunner.sPairIterations;
-        if (iterations == 0) {
-            return;
-        }
-
-        BluetoothDevice device = mAdapter.getRemoteDevice(BluetoothTestRunner.sDeviceAddress);
-        mTestUtils.enable(mAdapter);
-        mTestUtils.unpair(mAdapter, device);
-
-        for (int i = 0; i < iterations; i++) {
-            mTestUtils.writeOutput("pair iteration " + (i + 1) + " of " + iterations);
-            mTestUtils.pair(mAdapter, device, BluetoothTestRunner.sDevicePairPasskey,
-                    BluetoothTestRunner.sDevicePairPin);
-            mTestUtils.unpair(mAdapter, device);
-        }
-    }
-
-    /**
-     * Stress test for accepting a pairing request and unpairing with a remote device.
-     * <p>
-     * In this test, the local device waits for a pairing request from a remote device.  It accepts
-     * the request and then unpairs after the paring has successfully completed.
-     */
-    public void testAcceptPair() {
-        int iterations = BluetoothTestRunner.sPairIterations;
-        if (iterations == 0) {
-            return;
-        }
-        BluetoothDevice device = mAdapter.getRemoteDevice(BluetoothTestRunner.sDeviceAddress);
-        mTestUtils.enable(mAdapter);
-        mTestUtils.unpair(mAdapter, device);
-
-        for (int i = 0; i < iterations; i++) {
-            mTestUtils.writeOutput("acceptPair iteration " + (i + 1) + " of " + iterations);
-            mTestUtils.acceptPair(mAdapter, device, BluetoothTestRunner.sDevicePairPasskey,
-                    BluetoothTestRunner.sDevicePairPin);
-            mTestUtils.unpair(mAdapter, device);
-        }
-    }
-
-    /**
-     * Stress test for connecting and disconnecting with an A2DP source.
-     * <p>
-     * In this test, the local device plays the role of an A2DP sink, and initiates connections and
-     * disconnections with an A2DP source.
-     */
-    public void testConnectA2dp() {
-        int iterations = BluetoothTestRunner.sConnectA2dpIterations;
-        if (iterations == 0) {
-            return;
-        }
-
-        BluetoothDevice device = mAdapter.getRemoteDevice(BluetoothTestRunner.sDeviceAddress);
-        mTestUtils.enable(mAdapter);
-        mTestUtils.unpair(mAdapter, device);
-        mTestUtils.pair(mAdapter, device, BluetoothTestRunner.sDevicePairPasskey,
-                BluetoothTestRunner.sDevicePairPin);
-        mTestUtils.disconnectProfile(mAdapter, device, BluetoothProfile.A2DP, null);
-
-        for (int i = 0; i < iterations; i++) {
-            mTestUtils.writeOutput("connectA2dp iteration " + (i + 1) + " of " + iterations);
-            mTestUtils.connectProfile(mAdapter, device, BluetoothProfile.A2DP,
-                    String.format("connectA2dp(device=%s)", device));
-            mTestUtils.disconnectProfile(mAdapter, device, BluetoothProfile.A2DP,
-                    String.format("disconnectA2dp(device=%s)", device));
-        }
-
-        mTestUtils.unpair(mAdapter, device);
-    }
-
-    /**
-     * Stress test for connecting and disconnecting the HFP with a hands free device.
-     * <p>
-     * In this test, the local device plays the role of an HFP audio gateway, and initiates
-     * connections and disconnections with a hands free device.
-     */
-    public void testConnectHeadset() {
-        int iterations = BluetoothTestRunner.sConnectHeadsetIterations;
-        if (iterations == 0) {
-            return;
-        }
-
-        BluetoothDevice device = mAdapter.getRemoteDevice(BluetoothTestRunner.sDeviceAddress);
-        mTestUtils.enable(mAdapter);
-        mTestUtils.unpair(mAdapter, device);
-        mTestUtils.pair(mAdapter, device, BluetoothTestRunner.sDevicePairPasskey,
-                BluetoothTestRunner.sDevicePairPin);
-        mTestUtils.disconnectProfile(mAdapter, device, BluetoothProfile.HEADSET, null);
-
-        for (int i = 0; i < iterations; i++) {
-            mTestUtils.writeOutput("connectHeadset iteration " + (i + 1) + " of " + iterations);
-            mTestUtils.connectProfile(mAdapter, device, BluetoothProfile.HEADSET,
-                    String.format("connectHeadset(device=%s)", device));
-            mTestUtils.disconnectProfile(mAdapter, device, BluetoothProfile.HEADSET,
-                    String.format("disconnectHeadset(device=%s)", device));
-        }
-
-        mTestUtils.unpair(mAdapter, device);
-    }
-
-    /**
-     * Stress test for connecting and disconnecting with a HID device.
-     * <p>
-     * In this test, the local device plays the role of a HID host, and initiates connections and
-     * disconnections with a HID device.
-     */
-    public void testConnectInput() {
-        int iterations = BluetoothTestRunner.sConnectInputIterations;
-        if (iterations == 0) {
-            return;
-        }
-
-        BluetoothDevice device = mAdapter.getRemoteDevice(BluetoothTestRunner.sDeviceAddress);
-        mTestUtils.enable(mAdapter);
-        mTestUtils.unpair(mAdapter, device);
-        mTestUtils.pair(mAdapter, device, BluetoothTestRunner.sDevicePairPasskey,
-                BluetoothTestRunner.sDevicePairPin);
-        mTestUtils.disconnectProfile(mAdapter, device, BluetoothProfile.HID_HOST, null);
-
-        for (int i = 0; i < iterations; i++) {
-            mTestUtils.writeOutput("connectInput iteration " + (i + 1) + " of " + iterations);
-            mTestUtils.connectProfile(mAdapter, device, BluetoothProfile.HID_HOST,
-                    String.format("connectInput(device=%s)", device));
-            mTestUtils.disconnectProfile(mAdapter, device, BluetoothProfile.HID_HOST,
-                    String.format("disconnectInput(device=%s)", device));
-        }
-
-        mTestUtils.unpair(mAdapter, device);
-    }
-
-    /**
-     * Stress test for connecting and disconnecting with a PAN NAP.
-     * <p>
-     * In this test, the local device plays the role of a PANU, and initiates connections and
-     * disconnections with a NAP.
-     */
-    public void testConnectPan() {
-        int iterations = BluetoothTestRunner.sConnectPanIterations;
-        if (iterations == 0) {
-            return;
-        }
-
-        BluetoothDevice device = mAdapter.getRemoteDevice(BluetoothTestRunner.sDeviceAddress);
-        mTestUtils.enable(mAdapter);
-        mTestUtils.unpair(mAdapter, device);
-        mTestUtils.pair(mAdapter, device, BluetoothTestRunner.sDevicePairPasskey,
-                BluetoothTestRunner.sDevicePairPin);
-
-        for (int i = 0; i < iterations; i++) {
-            mTestUtils.writeOutput("connectPan iteration " + (i + 1) + " of " + iterations);
-            mTestUtils.connectPan(mAdapter, device);
-            mTestUtils.disconnectPan(mAdapter, device);
-        }
-
-        mTestUtils.unpair(mAdapter, device);
-    }
-
-    /**
-     * Stress test for verifying a PANU connecting and disconnecting with the device.
-     * <p>
-     * In this test, the local device plays the role of a NAP which a remote PANU connects and
-     * disconnects from.
-     */
-    public void testIncomingPanConnection() {
-        int iterations = BluetoothTestRunner.sConnectPanIterations;
-        if (iterations == 0) {
-            return;
-        }
-
-        BluetoothDevice device = mAdapter.getRemoteDevice(BluetoothTestRunner.sDeviceAddress);
-        mTestUtils.enable(mAdapter);
-        mTestUtils.disablePan(mAdapter);
-        mTestUtils.enablePan(mAdapter);
-        mTestUtils.unpair(mAdapter, device);
-        mTestUtils.acceptPair(mAdapter, device, BluetoothTestRunner.sDevicePairPasskey,
-                BluetoothTestRunner.sDevicePairPin);
-
-        for (int i = 0; i < iterations; i++) {
-            mTestUtils.writeOutput("incomingPanConnection iteration " + (i + 1) + " of "
-                    + iterations);
-            mTestUtils.incomingPanConnection(mAdapter, device);
-            mTestUtils.incomingPanDisconnection(mAdapter, device);
-        }
-
-        mTestUtils.unpair(mAdapter, device);
-        mTestUtils.disablePan(mAdapter);
-    }
-
-    /**
-     * Stress test for verifying that AudioManager can open and close SCO connections.
-     * <p>
-     * In this test, a HSP connection is opened with an external headset and the SCO connection is
-     * repeatibly opened and closed.
-     */
-    public void testStartStopSco() {
-        int iterations = BluetoothTestRunner.sStartStopScoIterations;
-        if (iterations == 0) {
-            return;
-        }
-
-        BluetoothDevice device = mAdapter.getRemoteDevice(BluetoothTestRunner.sDeviceAddress);
-        mTestUtils.enable(mAdapter);
-        mTestUtils.unpair(mAdapter, device);
-        mTestUtils.pair(mAdapter, device, BluetoothTestRunner.sDevicePairPasskey,
-                BluetoothTestRunner.sDevicePairPin);
-        mTestUtils.disconnectProfile(mAdapter, device, BluetoothProfile.HEADSET, null);
-        mTestUtils.connectProfile(mAdapter, device, BluetoothProfile.HEADSET, null);
-        mTestUtils.stopSco(mAdapter, device);
-
-        for (int i = 0; i < iterations; i++) {
-            mTestUtils.writeOutput("startStopSco iteration " + (i + 1) + " of " + iterations);
-            mTestUtils.startSco(mAdapter, device);
-            sleep(SCO_SLEEP_TIME);
-            mTestUtils.stopSco(mAdapter, device);
-            sleep(SCO_SLEEP_TIME);
-        }
-
-        mTestUtils.disconnectProfile(mAdapter, device, BluetoothProfile.HEADSET, null);
-        mTestUtils.unpair(mAdapter, device);
-    }
-
-    /* Make sure there is at least 1 unread message in the last week on remote device */
-    public void testMceSetMessageStatus() {
-        int iterations = BluetoothTestRunner.sMceSetMessageStatusIterations;
-        if (iterations == 0) {
-            return;
-        }
-
-        BluetoothDevice device = mAdapter.getRemoteDevice(BluetoothTestRunner.sDeviceAddress);
-        mTestUtils.enable(mAdapter);
-        mTestUtils.connectProfile(mAdapter, device, BluetoothProfile.MAP_CLIENT, null);
-        mTestUtils.mceGetUnreadMessage(mAdapter, device);
-
-        for (int i = 0; i < iterations; i++) {
-            mTestUtils.mceSetMessageStatus(mAdapter, device, BluetoothMapClient.READ);
-            mTestUtils.mceSetMessageStatus(mAdapter, device, BluetoothMapClient.UNREAD);
-        }
-
-        /**
-         * It is hard to find device to support set undeleted status, so just
-         * set deleted in 1 iteration
-         **/
-        mTestUtils.mceSetMessageStatus(mAdapter, device, BluetoothMapClient.DELETED);
-    }
-
-    private void sleep(long time) {
-        try {
-            Thread.sleep(time);
-        } catch (InterruptedException e) {
-        }
-    }
-}
diff --git a/core/tests/bluetoothtests/src/android/bluetooth/BluetoothTestRunner.java b/core/tests/bluetoothtests/src/android/bluetooth/BluetoothTestRunner.java
deleted file mode 100644
index d19c2c3..0000000
--- a/core/tests/bluetoothtests/src/android/bluetooth/BluetoothTestRunner.java
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-import junit.framework.TestSuite;
-
-import android.os.Bundle;
-import android.test.InstrumentationTestRunner;
-import android.test.InstrumentationTestSuite;
-import android.util.Log;
-
-/**
- * Instrumentation test runner for Bluetooth tests.
- * <p>
- * To run:
- * <pre>
- * {@code
- * adb shell am instrument \
- *     [-e enable_iterations <iterations>] \
- *     [-e discoverable_iterations <iterations>] \
- *     [-e scan_iterations <iterations>] \
- *     [-e enable_pan_iterations <iterations>] \
- *     [-e pair_iterations <iterations>] \
- *     [-e connect_a2dp_iterations <iterations>] \
- *     [-e connect_headset_iterations <iterations>] \
- *     [-e connect_input_iterations <iterations>] \
- *     [-e connect_pan_iterations <iterations>] \
- *     [-e start_stop_sco_iterations <iterations>] \
- *     [-e mce_set_message_status_iterations <iterations>] \
- *     [-e pair_address <address>] \
- *     [-e headset_address <address>] \
- *     [-e a2dp_address <address>] \
- *     [-e input_address <address>] \
- *     [-e pan_address <address>] \
- *     [-e pair_pin <pin>] \
- *     [-e pair_passkey <passkey>] \
- *     -w com.android.bluetooth.tests/android.bluetooth.BluetoothTestRunner
- * }
- * </pre>
- */
-public class BluetoothTestRunner extends InstrumentationTestRunner {
-    private static final String TAG = "BluetoothTestRunner";
-
-    public static int sEnableIterations = 100;
-    public static int sDiscoverableIterations = 1000;
-    public static int sScanIterations = 1000;
-    public static int sEnablePanIterations = 1000;
-    public static int sPairIterations = 100;
-    public static int sConnectHeadsetIterations = 100;
-    public static int sConnectA2dpIterations = 100;
-    public static int sConnectInputIterations = 100;
-    public static int sConnectPanIterations = 100;
-    public static int sStartStopScoIterations = 100;
-    public static int sMceSetMessageStatusIterations = 100;
-
-    public static String sDeviceAddress = "";
-    public static byte[] sDevicePairPin = {'1', '2', '3', '4'};
-    public static int sDevicePairPasskey = 123456;
-
-    @Override
-    public TestSuite getAllTests() {
-        TestSuite suite = new InstrumentationTestSuite(this);
-        suite.addTestSuite(BluetoothStressTest.class);
-        return suite;
-    }
-
-    @Override
-    public ClassLoader getLoader() {
-        return BluetoothTestRunner.class.getClassLoader();
-    }
-
-    @Override
-    public void onCreate(Bundle arguments) {
-        String val = arguments.getString("enable_iterations");
-        if (val != null) {
-            try {
-                sEnableIterations = Integer.parseInt(val);
-            } catch (NumberFormatException e) {
-                // Invalid argument, fall back to default value
-            }
-        }
-
-        val = arguments.getString("discoverable_iterations");
-        if (val != null) {
-            try {
-                sDiscoverableIterations = Integer.parseInt(val);
-            } catch (NumberFormatException e) {
-                // Invalid argument, fall back to default value
-            }
-        }
-
-        val = arguments.getString("scan_iterations");
-        if (val != null) {
-            try {
-                sScanIterations = Integer.parseInt(val);
-            } catch (NumberFormatException e) {
-                // Invalid argument, fall back to default value
-            }
-        }
-
-        val = arguments.getString("enable_pan_iterations");
-        if (val != null) {
-            try {
-                sEnablePanIterations = Integer.parseInt(val);
-            } catch (NumberFormatException e) {
-                // Invalid argument, fall back to default value
-            }
-        }
-
-        val = arguments.getString("pair_iterations");
-        if (val != null) {
-            try {
-                sPairIterations = Integer.parseInt(val);
-            } catch (NumberFormatException e) {
-                // Invalid argument, fall back to default value
-            }
-        }
-
-        val = arguments.getString("connect_a2dp_iterations");
-        if (val != null) {
-            try {
-                sConnectA2dpIterations = Integer.parseInt(val);
-            } catch (NumberFormatException e) {
-                // Invalid argument, fall back to default value
-            }
-        }
-
-        val = arguments.getString("connect_headset_iterations");
-        if (val != null) {
-            try {
-                sConnectHeadsetIterations = Integer.parseInt(val);
-            } catch (NumberFormatException e) {
-                // Invalid argument, fall back to default value
-            }
-        }
-
-        val = arguments.getString("connect_input_iterations");
-        if (val != null) {
-            try {
-                sConnectInputIterations = Integer.parseInt(val);
-            } catch (NumberFormatException e) {
-                // Invalid argument, fall back to default value
-            }
-        }
-
-        val = arguments.getString("connect_pan_iterations");
-        if (val != null) {
-            try {
-                sConnectPanIterations = Integer.parseInt(val);
-            } catch (NumberFormatException e) {
-                // Invalid argument, fall back to default value
-            }
-        }
-
-        val = arguments.getString("start_stop_sco_iterations");
-        if (val != null) {
-            try {
-                sStartStopScoIterations = Integer.parseInt(val);
-            } catch (NumberFormatException e) {
-                // Invalid argument, fall back to default value
-            }
-        }
-
-        val = arguments.getString("mce_set_message_status_iterations");
-        if (val != null) {
-            try {
-                sMceSetMessageStatusIterations = Integer.parseInt(val);
-            } catch (NumberFormatException e) {
-                // Invalid argument, fall back to default value
-            }
-        }
-
-        val = arguments.getString("device_address");
-        if (val != null) {
-            sDeviceAddress = val;
-        }
-
-        val = arguments.getString("device_pair_pin");
-        if (val != null) {
-            byte[] pin = BluetoothDevice.convertPinToBytes(val);
-            if (pin != null) {
-                sDevicePairPin = pin;
-            }
-        }
-
-        val = arguments.getString("device_pair_passkey");
-        if (val != null) {
-            try {
-                sDevicePairPasskey = Integer.parseInt(val);
-            } catch (NumberFormatException e) {
-                // Invalid argument, fall back to default value
-            }
-        }
-
-        Log.i(TAG, String.format("enable_iterations=%d", sEnableIterations));
-        Log.i(TAG, String.format("discoverable_iterations=%d", sDiscoverableIterations));
-        Log.i(TAG, String.format("scan_iterations=%d", sScanIterations));
-        Log.i(TAG, String.format("pair_iterations=%d", sPairIterations));
-        Log.i(TAG, String.format("connect_a2dp_iterations=%d", sConnectA2dpIterations));
-        Log.i(TAG, String.format("connect_headset_iterations=%d", sConnectHeadsetIterations));
-        Log.i(TAG, String.format("connect_input_iterations=%d", sConnectInputIterations));
-        Log.i(TAG, String.format("connect_pan_iterations=%d", sConnectPanIterations));
-        Log.i(TAG, String.format("start_stop_sco_iterations=%d", sStartStopScoIterations));
-        Log.i(TAG, String.format("device_address=%s", sDeviceAddress));
-        Log.i(TAG, String.format("device_pair_pin=%s", new String(sDevicePairPin)));
-        Log.i(TAG, String.format("device_pair_passkey=%d", sDevicePairPasskey));
-
-        // Call onCreate last since we want to set the static variables first.
-        super.onCreate(arguments);
-    }
-}
diff --git a/core/tests/bluetoothtests/src/android/bluetooth/BluetoothTestUtils.java b/core/tests/bluetoothtests/src/android/bluetooth/BluetoothTestUtils.java
deleted file mode 100644
index 409025b..0000000
--- a/core/tests/bluetoothtests/src/android/bluetooth/BluetoothTestUtils.java
+++ /dev/null
@@ -1,1649 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-import android.bluetooth.BluetoothPan;
-import android.bluetooth.BluetoothProfile;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.media.AudioManager;
-import android.os.Environment;
-import android.util.Log;
-
-import junit.framework.Assert;
-
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.TimeUnit;
-
-public class BluetoothTestUtils extends Assert {
-
-    /** Timeout for enable/disable in ms. */
-    private static final int ENABLE_DISABLE_TIMEOUT = 20000;
-    /** Timeout for discoverable/undiscoverable in ms. */
-    private static final int DISCOVERABLE_UNDISCOVERABLE_TIMEOUT = 5000;
-    /** Timeout for starting/stopping a scan in ms. */
-    private static final int START_STOP_SCAN_TIMEOUT = 5000;
-    /** Timeout for pair/unpair in ms. */
-    private static final int PAIR_UNPAIR_TIMEOUT = 20000;
-    /** Timeout for connecting/disconnecting a profile in ms. */
-    private static final int CONNECT_DISCONNECT_PROFILE_TIMEOUT = 20000;
-    /** Timeout to start or stop a SCO channel in ms. */
-    private static final int START_STOP_SCO_TIMEOUT = 10000;
-    /** Timeout to connect a profile proxy in ms. */
-    private static final int CONNECT_PROXY_TIMEOUT = 5000;
-    /** Time between polls in ms. */
-    private static final int POLL_TIME = 100;
-    /** Timeout to get map message in ms. */
-    private static final int GET_UNREAD_MESSAGE_TIMEOUT = 10000;
-    /** Timeout to set map message status in ms. */
-    private static final int SET_MESSAGE_STATUS_TIMEOUT = 2000;
-
-    private abstract class FlagReceiver extends BroadcastReceiver {
-        private int mExpectedFlags = 0;
-        private int mFiredFlags = 0;
-        private long mCompletedTime = -1;
-
-        public FlagReceiver(int expectedFlags) {
-            mExpectedFlags = expectedFlags;
-        }
-
-        public int getFiredFlags() {
-            synchronized (this) {
-                return mFiredFlags;
-            }
-        }
-
-        public long getCompletedTime() {
-            synchronized (this) {
-                return mCompletedTime;
-            }
-        }
-
-        protected void setFiredFlag(int flag) {
-            synchronized (this) {
-                mFiredFlags |= flag;
-                if ((mFiredFlags & mExpectedFlags) == mExpectedFlags) {
-                    mCompletedTime = System.currentTimeMillis();
-                }
-            }
-        }
-    }
-
-    private class BluetoothReceiver extends FlagReceiver {
-        private static final int DISCOVERY_STARTED_FLAG = 1;
-        private static final int DISCOVERY_FINISHED_FLAG = 1 << 1;
-        private static final int SCAN_MODE_NONE_FLAG = 1 << 2;
-        private static final int SCAN_MODE_CONNECTABLE_FLAG = 1 << 3;
-        private static final int SCAN_MODE_CONNECTABLE_DISCOVERABLE_FLAG = 1 << 4;
-        private static final int STATE_OFF_FLAG = 1 << 5;
-        private static final int STATE_TURNING_ON_FLAG = 1 << 6;
-        private static final int STATE_ON_FLAG = 1 << 7;
-        private static final int STATE_TURNING_OFF_FLAG = 1 << 8;
-        private static final int STATE_GET_MESSAGE_FINISHED_FLAG = 1 << 9;
-        private static final int STATE_SET_MESSAGE_STATUS_FINISHED_FLAG = 1 << 10;
-
-        public BluetoothReceiver(int expectedFlags) {
-            super(expectedFlags);
-        }
-
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(intent.getAction())) {
-                setFiredFlag(DISCOVERY_STARTED_FLAG);
-            } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(intent.getAction())) {
-                setFiredFlag(DISCOVERY_FINISHED_FLAG);
-            } else if (BluetoothAdapter.ACTION_SCAN_MODE_CHANGED.equals(intent.getAction())) {
-                int mode = intent.getIntExtra(BluetoothAdapter.EXTRA_SCAN_MODE, -1);
-                assertNotSame(-1, mode);
-                switch (mode) {
-                    case BluetoothAdapter.SCAN_MODE_NONE:
-                        setFiredFlag(SCAN_MODE_NONE_FLAG);
-                        break;
-                    case BluetoothAdapter.SCAN_MODE_CONNECTABLE:
-                        setFiredFlag(SCAN_MODE_CONNECTABLE_FLAG);
-                        break;
-                    case BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE:
-                        setFiredFlag(SCAN_MODE_CONNECTABLE_DISCOVERABLE_FLAG);
-                        break;
-                }
-            } else if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(intent.getAction())) {
-                int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);
-                assertNotSame(-1, state);
-                switch (state) {
-                    case BluetoothAdapter.STATE_OFF:
-                        setFiredFlag(STATE_OFF_FLAG);
-                        break;
-                    case BluetoothAdapter.STATE_TURNING_ON:
-                        setFiredFlag(STATE_TURNING_ON_FLAG);
-                        break;
-                    case BluetoothAdapter.STATE_ON:
-                        setFiredFlag(STATE_ON_FLAG);
-                        break;
-                    case BluetoothAdapter.STATE_TURNING_OFF:
-                        setFiredFlag(STATE_TURNING_OFF_FLAG);
-                        break;
-                }
-            }
-        }
-    }
-
-    private class PairReceiver extends FlagReceiver {
-        private static final int STATE_BONDED_FLAG = 1;
-        private static final int STATE_BONDING_FLAG = 1 << 1;
-        private static final int STATE_NONE_FLAG = 1 << 2;
-
-        private BluetoothDevice mDevice;
-        private int mPasskey;
-        private byte[] mPin;
-
-        public PairReceiver(BluetoothDevice device, int passkey, byte[] pin, int expectedFlags) {
-            super(expectedFlags);
-
-            mDevice = device;
-            mPasskey = passkey;
-            mPin = pin;
-        }
-
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (!mDevice.equals(intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE))) {
-                return;
-            }
-
-            if (BluetoothDevice.ACTION_PAIRING_REQUEST.equals(intent.getAction())) {
-                int varient = intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT, -1);
-                assertNotSame(-1, varient);
-                switch (varient) {
-                    case BluetoothDevice.PAIRING_VARIANT_PIN:
-                    case BluetoothDevice.PAIRING_VARIANT_PIN_16_DIGITS:
-                        mDevice.setPin(mPin);
-                        break;
-                    case BluetoothDevice.PAIRING_VARIANT_PASSKEY:
-                        break;
-                    case BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION:
-                    case BluetoothDevice.PAIRING_VARIANT_CONSENT:
-                        mDevice.setPairingConfirmation(true);
-                        break;
-                    case BluetoothDevice.PAIRING_VARIANT_OOB_CONSENT:
-                        break;
-                }
-            } else if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(intent.getAction())) {
-                int state = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, -1);
-                assertNotSame(-1, state);
-                switch (state) {
-                    case BluetoothDevice.BOND_NONE:
-                        setFiredFlag(STATE_NONE_FLAG);
-                        break;
-                    case BluetoothDevice.BOND_BONDING:
-                        setFiredFlag(STATE_BONDING_FLAG);
-                        break;
-                    case BluetoothDevice.BOND_BONDED:
-                        setFiredFlag(STATE_BONDED_FLAG);
-                        break;
-                }
-            }
-        }
-    }
-
-    private class ConnectProfileReceiver extends FlagReceiver {
-        private static final int STATE_DISCONNECTED_FLAG = 1;
-        private static final int STATE_CONNECTING_FLAG = 1 << 1;
-        private static final int STATE_CONNECTED_FLAG = 1 << 2;
-        private static final int STATE_DISCONNECTING_FLAG = 1 << 3;
-
-        private BluetoothDevice mDevice;
-        private int mProfile;
-        private String mConnectionAction;
-
-        public ConnectProfileReceiver(BluetoothDevice device, int profile, int expectedFlags) {
-            super(expectedFlags);
-
-            mDevice = device;
-            mProfile = profile;
-
-            switch (mProfile) {
-                case BluetoothProfile.A2DP:
-                    mConnectionAction = BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED;
-                    break;
-                case BluetoothProfile.HEADSET:
-                    mConnectionAction = BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED;
-                    break;
-                case BluetoothProfile.HID_HOST:
-                    mConnectionAction = BluetoothHidHost.ACTION_CONNECTION_STATE_CHANGED;
-                    break;
-                case BluetoothProfile.PAN:
-                    mConnectionAction = BluetoothPan.ACTION_CONNECTION_STATE_CHANGED;
-                    break;
-                case BluetoothProfile.MAP_CLIENT:
-                    mConnectionAction = BluetoothMapClient.ACTION_CONNECTION_STATE_CHANGED;
-                    break;
-                default:
-                    mConnectionAction = null;
-            }
-        }
-
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (mConnectionAction != null && mConnectionAction.equals(intent.getAction())) {
-                if (!mDevice.equals(intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE))) {
-                    return;
-                }
-
-                int state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1);
-                assertNotSame(-1, state);
-                switch (state) {
-                    case BluetoothProfile.STATE_DISCONNECTED:
-                        setFiredFlag(STATE_DISCONNECTED_FLAG);
-                        break;
-                    case BluetoothProfile.STATE_CONNECTING:
-                        setFiredFlag(STATE_CONNECTING_FLAG);
-                        break;
-                    case BluetoothProfile.STATE_CONNECTED:
-                        setFiredFlag(STATE_CONNECTED_FLAG);
-                        break;
-                    case BluetoothProfile.STATE_DISCONNECTING:
-                        setFiredFlag(STATE_DISCONNECTING_FLAG);
-                        break;
-                }
-            }
-        }
-    }
-
-    private class ConnectPanReceiver extends ConnectProfileReceiver {
-        private int mRole;
-
-        public ConnectPanReceiver(BluetoothDevice device, int role, int expectedFlags) {
-            super(device, BluetoothProfile.PAN, expectedFlags);
-
-            mRole = role;
-        }
-
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (mRole != intent.getIntExtra(BluetoothPan.EXTRA_LOCAL_ROLE, -1)) {
-                return;
-            }
-
-            super.onReceive(context, intent);
-        }
-    }
-
-    private class StartStopScoReceiver extends FlagReceiver {
-        private static final int STATE_CONNECTED_FLAG = 1;
-        private static final int STATE_DISCONNECTED_FLAG = 1 << 1;
-
-        public StartStopScoReceiver(int expectedFlags) {
-            super(expectedFlags);
-        }
-
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED.equals(intent.getAction())) {
-                int state = intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE,
-                        AudioManager.SCO_AUDIO_STATE_ERROR);
-                assertNotSame(AudioManager.SCO_AUDIO_STATE_ERROR, state);
-                switch(state) {
-                    case AudioManager.SCO_AUDIO_STATE_CONNECTED:
-                        setFiredFlag(STATE_CONNECTED_FLAG);
-                        break;
-                    case AudioManager.SCO_AUDIO_STATE_DISCONNECTED:
-                        setFiredFlag(STATE_DISCONNECTED_FLAG);
-                        break;
-                }
-            }
-        }
-    }
-
-
-    private class MceSetMessageStatusReceiver extends FlagReceiver {
-        private static final int MESSAGE_RECEIVED_FLAG = 1;
-        private static final int STATUS_CHANGED_FLAG = 1 << 1;
-
-        public MceSetMessageStatusReceiver(int expectedFlags) {
-            super(expectedFlags);
-        }
-
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (BluetoothMapClient.ACTION_MESSAGE_RECEIVED.equals(intent.getAction())) {
-                String handle = intent.getStringExtra(BluetoothMapClient.EXTRA_MESSAGE_HANDLE);
-                assertNotNull(handle);
-                setFiredFlag(MESSAGE_RECEIVED_FLAG);
-                mMsgHandle = handle;
-            } else if (BluetoothMapClient.ACTION_MESSAGE_DELETED_STATUS_CHANGED.equals(intent.getAction())) {
-                int result = intent.getIntExtra(BluetoothMapClient.EXTRA_RESULT_CODE, BluetoothMapClient.RESULT_FAILURE);
-                assertEquals(result, BluetoothMapClient.RESULT_SUCCESS);
-                setFiredFlag(STATUS_CHANGED_FLAG);
-            } else if (BluetoothMapClient.ACTION_MESSAGE_READ_STATUS_CHANGED.equals(intent.getAction())) {
-                int result = intent.getIntExtra(BluetoothMapClient.EXTRA_RESULT_CODE, BluetoothMapClient.RESULT_FAILURE);
-                assertEquals(result, BluetoothMapClient.RESULT_SUCCESS);
-                setFiredFlag(STATUS_CHANGED_FLAG);
-            }
-        }
-    }
-
-    private BluetoothProfile.ServiceListener mServiceListener =
-            new BluetoothProfile.ServiceListener() {
-        @Override
-        public void onServiceConnected(int profile, BluetoothProfile proxy) {
-            synchronized (this) {
-                switch (profile) {
-                    case BluetoothProfile.A2DP:
-                        mA2dp = (BluetoothA2dp) proxy;
-                        break;
-                    case BluetoothProfile.HEADSET:
-                        mHeadset = (BluetoothHeadset) proxy;
-                        break;
-                    case BluetoothProfile.HID_HOST:
-                        mInput = (BluetoothHidHost) proxy;
-                        break;
-                    case BluetoothProfile.PAN:
-                        mPan = (BluetoothPan) proxy;
-                        break;
-                    case BluetoothProfile.MAP_CLIENT:
-                        mMce = (BluetoothMapClient) proxy;
-                        break;
-                }
-            }
-        }
-
-        @Override
-        public void onServiceDisconnected(int profile) {
-            synchronized (this) {
-                switch (profile) {
-                    case BluetoothProfile.A2DP:
-                        mA2dp = null;
-                        break;
-                    case BluetoothProfile.HEADSET:
-                        mHeadset = null;
-                        break;
-                    case BluetoothProfile.HID_HOST:
-                        mInput = null;
-                        break;
-                    case BluetoothProfile.PAN:
-                        mPan = null;
-                        break;
-                    case BluetoothProfile.MAP_CLIENT:
-                        mMce = null;
-                        break;
-                }
-            }
-        }
-    };
-
-    private List<BroadcastReceiver> mReceivers = new ArrayList<BroadcastReceiver>();
-
-    private BufferedWriter mOutputWriter;
-    private String mTag;
-    private String mOutputFile;
-
-    private Context mContext;
-    private BluetoothA2dp mA2dp = null;
-    private BluetoothHeadset mHeadset = null;
-    private BluetoothHidHost mInput = null;
-    private BluetoothPan mPan = null;
-    private BluetoothMapClient mMce = null;
-    private String mMsgHandle = null;
-
-    /**
-     * Creates a utility instance for testing Bluetooth.
-     *
-     * @param context The context of the application using the utility.
-     * @param tag The log tag of the application using the utility.
-     */
-    public BluetoothTestUtils(Context context, String tag) {
-        this(context, tag, null);
-    }
-
-    /**
-     * Creates a utility instance for testing Bluetooth.
-     *
-     * @param context The context of the application using the utility.
-     * @param tag The log tag of the application using the utility.
-     * @param outputFile The path to an output file if the utility is to write results to a
-     *        separate file.
-     */
-    public BluetoothTestUtils(Context context, String tag, String outputFile) {
-        mContext = context;
-        mTag = tag;
-        mOutputFile = outputFile;
-
-        if (mOutputFile == null) {
-            mOutputWriter = null;
-        } else {
-            try {
-                mOutputWriter = new BufferedWriter(new FileWriter(new File(
-                        Environment.getExternalStorageDirectory(), mOutputFile), true));
-            } catch (IOException e) {
-                Log.w(mTag, "Test output file could not be opened", e);
-                mOutputWriter = null;
-            }
-        }
-    }
-
-    /**
-     * Closes the utility instance and unregisters any BroadcastReceivers.
-     */
-    public void close() {
-        while (!mReceivers.isEmpty()) {
-            mContext.unregisterReceiver(mReceivers.remove(0));
-        }
-
-        if (mOutputWriter != null) {
-            try {
-                mOutputWriter.close();
-            } catch (IOException e) {
-                Log.w(mTag, "Test output file could not be closed", e);
-            }
-        }
-    }
-
-    /**
-     * Enables Bluetooth and checks to make sure that Bluetooth was turned on and that the correct
-     * actions were broadcast.
-     *
-     * @param adapter The BT adapter.
-     */
-    public void enable(BluetoothAdapter adapter) {
-        writeOutput("Enabling Bluetooth adapter.");
-        assertFalse(adapter.isEnabled());
-        int btState = adapter.getState();
-        final Semaphore completionSemaphore = new Semaphore(0);
-        final BroadcastReceiver receiver = new BroadcastReceiver() {
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                final String action = intent.getAction();
-                if (!BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) {
-                    return;
-                }
-                final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
-                        BluetoothAdapter.ERROR);
-                if (state == BluetoothAdapter.STATE_ON) {
-                    completionSemaphore.release();
-                }
-            }
-        };
-
-        final IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
-        mContext.registerReceiver(receiver, filter);
-        // Note: for Wear Local Edition builds, which have Permission Review Mode enabled to
-        // obey China CMIIT, BluetoothAdapter may not startup immediately on methods enable/disable.
-        // So no assertion applied here.
-        adapter.enable();
-        boolean success = false;
-        try {
-            success = completionSemaphore.tryAcquire(ENABLE_DISABLE_TIMEOUT, TimeUnit.MILLISECONDS);
-            writeOutput(String.format("enable() completed in 0 ms"));
-        } catch (final InterruptedException e) {
-            // This should never happen but just in case it does, the test will fail anyway.
-        }
-        mContext.unregisterReceiver(receiver);
-        if (!success) {
-            fail(String.format("enable() timeout: state=%d (expected %d)", btState,
-                    BluetoothAdapter.STATE_ON));
-        }
-    }
-
-    /**
-     * Disables Bluetooth and checks to make sure that Bluetooth was turned off and that the correct
-     * actions were broadcast.
-     *
-     * @param adapter The BT adapter.
-     */
-    public void disable(BluetoothAdapter adapter) {
-        writeOutput("Disabling Bluetooth adapter.");
-        assertTrue(adapter.isEnabled());
-        int btState = adapter.getState();
-        final Semaphore completionSemaphore = new Semaphore(0);
-        final BroadcastReceiver receiver = new BroadcastReceiver() {
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                final String action = intent.getAction();
-                if (!BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) {
-                    return;
-                }
-                final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
-                        BluetoothAdapter.ERROR);
-                if (state == BluetoothAdapter.STATE_OFF) {
-                    completionSemaphore.release();
-                }
-            }
-        };
-
-        final IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
-        mContext.registerReceiver(receiver, filter);
-        // Note: for Wear Local Edition builds, which have Permission Review Mode enabled to
-        // obey China CMIIT, BluetoothAdapter may not startup immediately on methods enable/disable.
-        // So no assertion applied here.
-        adapter.disable();
-        boolean success = false;
-        try {
-            success = completionSemaphore.tryAcquire(ENABLE_DISABLE_TIMEOUT, TimeUnit.MILLISECONDS);
-            writeOutput(String.format("disable() completed in 0 ms"));
-        } catch (final InterruptedException e) {
-            // This should never happen but just in case it does, the test will fail anyway.
-        }
-        mContext.unregisterReceiver(receiver);
-        if (!success) {
-            fail(String.format("disable() timeout: state=%d (expected %d)", btState,
-                    BluetoothAdapter.STATE_OFF));
-        }
-    }
-
-    /**
-     * Puts the local device into discoverable mode and checks to make sure that the local device
-     * is in discoverable mode and that the correct actions were broadcast.
-     *
-     * @param adapter The BT adapter.
-     */
-    public void discoverable(BluetoothAdapter adapter) {
-        if (!adapter.isEnabled()) {
-            fail("discoverable() bluetooth not enabled");
-        }
-
-        int scanMode = adapter.getScanMode();
-        if (scanMode != BluetoothAdapter.SCAN_MODE_CONNECTABLE) {
-            return;
-        }
-
-        final Semaphore completionSemaphore = new Semaphore(0);
-        final BroadcastReceiver receiver = new BroadcastReceiver() {
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                final String action = intent.getAction();
-                if (!BluetoothAdapter.ACTION_SCAN_MODE_CHANGED.equals(action)) {
-                    return;
-                }
-                final int mode = intent.getIntExtra(BluetoothAdapter.EXTRA_SCAN_MODE,
-                        BluetoothAdapter.SCAN_MODE_NONE);
-                if (mode == BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
-                    completionSemaphore.release();
-                }
-            }
-        };
-
-        final IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
-        mContext.registerReceiver(receiver, filter);
-        assertTrue(adapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE));
-        boolean success = false;
-        try {
-            success = completionSemaphore.tryAcquire(DISCOVERABLE_UNDISCOVERABLE_TIMEOUT,
-                    TimeUnit.MILLISECONDS);
-            writeOutput(String.format("discoverable() completed in 0 ms"));
-        } catch (final InterruptedException e) {
-            // This should never happen but just in case it does, the test will fail anyway.
-        }
-        mContext.unregisterReceiver(receiver);
-        if (!success) {
-            fail(String.format("discoverable() timeout: scanMode=%d (expected %d)", scanMode,
-                    BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE));
-        }
-    }
-
-    /**
-     * Puts the local device into connectable only mode and checks to make sure that the local
-     * device is in in connectable mode and that the correct actions were broadcast.
-     *
-     * @param adapter The BT adapter.
-     */
-    public void undiscoverable(BluetoothAdapter adapter) {
-        if (!adapter.isEnabled()) {
-            fail("undiscoverable() bluetooth not enabled");
-        }
-
-        int scanMode = adapter.getScanMode();
-        if (scanMode != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
-            return;
-        }
-
-        final Semaphore completionSemaphore = new Semaphore(0);
-        final BroadcastReceiver receiver = new BroadcastReceiver() {
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                final String action = intent.getAction();
-                if (!BluetoothAdapter.ACTION_SCAN_MODE_CHANGED.equals(action)) {
-                    return;
-                }
-                final int mode = intent.getIntExtra(BluetoothAdapter.EXTRA_SCAN_MODE,
-                        BluetoothAdapter.SCAN_MODE_NONE);
-                if (mode == BluetoothAdapter.SCAN_MODE_CONNECTABLE) {
-                    completionSemaphore.release();
-                }
-            }
-        };
-
-        final IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
-        mContext.registerReceiver(receiver, filter);
-        assertTrue(adapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE));
-        boolean success = false;
-        try {
-            success = completionSemaphore.tryAcquire(DISCOVERABLE_UNDISCOVERABLE_TIMEOUT,
-                    TimeUnit.MILLISECONDS);
-            writeOutput(String.format("undiscoverable() completed in 0 ms"));
-        } catch (InterruptedException e) {
-            // This should never happen but just in case it does, the test will fail anyway.
-        }
-        mContext.unregisterReceiver(receiver);
-        if (!success) {
-            fail(String.format("undiscoverable() timeout: scanMode=%d (expected %d)", scanMode,
-                    BluetoothAdapter.SCAN_MODE_CONNECTABLE));
-        }
-    }
-
-    /**
-     * Starts a scan for remote devices and checks to make sure that the local device is scanning
-     * and that the correct actions were broadcast.
-     *
-     * @param adapter The BT adapter.
-     */
-    public void startScan(BluetoothAdapter adapter) {
-        int mask = BluetoothReceiver.DISCOVERY_STARTED_FLAG;
-
-        if (!adapter.isEnabled()) {
-            fail("startScan() bluetooth not enabled");
-        }
-
-        if (adapter.isDiscovering()) {
-            return;
-        }
-
-        BluetoothReceiver receiver = getBluetoothReceiver(mask);
-
-        long start = System.currentTimeMillis();
-        assertTrue(adapter.startDiscovery());
-
-        while (System.currentTimeMillis() - start < START_STOP_SCAN_TIMEOUT) {
-            if (adapter.isDiscovering() && ((receiver.getFiredFlags() & mask) == mask)) {
-                writeOutput(String.format("startScan() completed in %d ms",
-                        (receiver.getCompletedTime() - start)));
-                removeReceiver(receiver);
-                return;
-            }
-            sleep(POLL_TIME);
-        }
-
-        int firedFlags = receiver.getFiredFlags();
-        removeReceiver(receiver);
-        fail(String.format("startScan() timeout: isDiscovering=%b, flags=0x%x (expected 0x%x)",
-                adapter.isDiscovering(), firedFlags, mask));
-    }
-
-    /**
-     * Stops a scan for remote devices and checks to make sure that the local device is not scanning
-     * and that the correct actions were broadcast.
-     *
-     * @param adapter The BT adapter.
-     */
-    public void stopScan(BluetoothAdapter adapter) {
-        int mask = BluetoothReceiver.DISCOVERY_FINISHED_FLAG;
-
-        if (!adapter.isEnabled()) {
-            fail("stopScan() bluetooth not enabled");
-        }
-
-        if (!adapter.isDiscovering()) {
-            return;
-        }
-
-        BluetoothReceiver receiver = getBluetoothReceiver(mask);
-
-        long start = System.currentTimeMillis();
-        assertTrue(adapter.cancelDiscovery());
-
-        while (System.currentTimeMillis() - start < START_STOP_SCAN_TIMEOUT) {
-            if (!adapter.isDiscovering() && ((receiver.getFiredFlags() & mask) == mask)) {
-                writeOutput(String.format("stopScan() completed in %d ms",
-                        (receiver.getCompletedTime() - start)));
-                removeReceiver(receiver);
-                return;
-            }
-            sleep(POLL_TIME);
-        }
-
-        int firedFlags = receiver.getFiredFlags();
-        removeReceiver(receiver);
-        fail(String.format("stopScan() timeout: isDiscovering=%b, flags=0x%x (expected 0x%x)",
-                adapter.isDiscovering(), firedFlags, mask));
-
-    }
-
-    /**
-     * Enables PAN tethering on the local device and checks to make sure that tethering is enabled.
-     *
-     * @param adapter The BT adapter.
-     */
-    public void enablePan(BluetoothAdapter adapter) {
-        if (mPan == null) mPan = (BluetoothPan) connectProxy(adapter, BluetoothProfile.PAN);
-        assertNotNull(mPan);
-
-        long start = System.currentTimeMillis();
-        mPan.setBluetoothTethering(true);
-        long stop = System.currentTimeMillis();
-        assertTrue(mPan.isTetheringOn());
-
-        writeOutput(String.format("enablePan() completed in %d ms", (stop - start)));
-    }
-
-    /**
-     * Disables PAN tethering on the local device and checks to make sure that tethering is
-     * disabled.
-     *
-     * @param adapter The BT adapter.
-     */
-    public void disablePan(BluetoothAdapter adapter) {
-        if (mPan == null) mPan = (BluetoothPan) connectProxy(adapter, BluetoothProfile.PAN);
-        assertNotNull(mPan);
-
-        long start = System.currentTimeMillis();
-        mPan.setBluetoothTethering(false);
-        long stop = System.currentTimeMillis();
-        assertFalse(mPan.isTetheringOn());
-
-        writeOutput(String.format("disablePan() completed in %d ms", (stop - start)));
-    }
-
-    /**
-     * Initiates a pairing with a remote device and checks to make sure that the devices are paired
-     * and that the correct actions were broadcast.
-     *
-     * @param adapter The BT adapter.
-     * @param device The remote device.
-     * @param passkey The pairing passkey if pairing requires a passkey. Any value if not.
-     * @param pin The pairing pin if pairing requires a pin. Any value if not.
-     */
-    public void pair(BluetoothAdapter adapter, BluetoothDevice device, int passkey, byte[] pin) {
-        pairOrAcceptPair(adapter, device, passkey, pin, true);
-    }
-
-    /**
-     * Accepts a pairing with a remote device and checks to make sure that the devices are paired
-     * and that the correct actions were broadcast.
-     *
-     * @param adapter The BT adapter.
-     * @param device The remote device.
-     * @param passkey The pairing passkey if pairing requires a passkey. Any value if not.
-     * @param pin The pairing pin if pairing requires a pin. Any value if not.
-     */
-    public void acceptPair(BluetoothAdapter adapter, BluetoothDevice device, int passkey,
-            byte[] pin) {
-        pairOrAcceptPair(adapter, device, passkey, pin, false);
-    }
-
-    /**
-     * Helper method used by {@link #pair(BluetoothAdapter, BluetoothDevice, int, byte[])} and
-     * {@link #acceptPair(BluetoothAdapter, BluetoothDevice, int, byte[])} to either pair or accept
-     * a pairing request.
-     *
-     * @param adapter The BT adapter.
-     * @param device The remote device.
-     * @param passkey The pairing passkey if pairing requires a passkey. Any value if not.
-     * @param pin The pairing pin if pairing requires a pin. Any value if not.
-     * @param shouldPair Whether to pair or accept the pair.
-     */
-    private void pairOrAcceptPair(BluetoothAdapter adapter, BluetoothDevice device, int passkey,
-            byte[] pin, boolean shouldPair) {
-        int mask = PairReceiver.STATE_BONDING_FLAG | PairReceiver.STATE_BONDED_FLAG;
-        long start = -1;
-        String methodName;
-        if (shouldPair) {
-            methodName = String.format("pair(device=%s)", device);
-        } else {
-            methodName = String.format("acceptPair(device=%s)", device);
-        }
-
-        if (!adapter.isEnabled()) {
-            fail(String.format("%s bluetooth not enabled", methodName));
-        }
-
-        PairReceiver receiver = getPairReceiver(device, passkey, pin, mask);
-
-        int state = device.getBondState();
-        switch (state) {
-            case BluetoothDevice.BOND_NONE:
-                assertFalse(adapter.getBondedDevices().contains(device));
-                start = System.currentTimeMillis();
-                if (shouldPair) {
-                    assertTrue(device.createBond());
-                }
-                break;
-            case BluetoothDevice.BOND_BONDING:
-                mask = 0; // Don't check for received intents since we might have missed them.
-                break;
-            case BluetoothDevice.BOND_BONDED:
-                assertTrue(adapter.getBondedDevices().contains(device));
-                return;
-            default:
-                removeReceiver(receiver);
-                fail(String.format("%s invalid state: state=%d", methodName, state));
-        }
-
-        long s = System.currentTimeMillis();
-        while (System.currentTimeMillis() - s < PAIR_UNPAIR_TIMEOUT) {
-            state = device.getBondState();
-            if (state == BluetoothDevice.BOND_BONDED && (receiver.getFiredFlags() & mask) == mask) {
-                assertTrue(adapter.getBondedDevices().contains(device));
-                long finish = receiver.getCompletedTime();
-                if (start != -1 && finish != -1) {
-                    writeOutput(String.format("%s completed in %d ms", methodName,
-                            (finish - start)));
-                } else {
-                    writeOutput(String.format("%s completed", methodName));
-                }
-                removeReceiver(receiver);
-                return;
-            }
-            sleep(POLL_TIME);
-        }
-
-        int firedFlags = receiver.getFiredFlags();
-        removeReceiver(receiver);
-        fail(String.format("%s timeout: state=%d (expected %d), flags=0x%x (expected 0x%x)",
-                methodName, state, BluetoothDevice.BOND_BONDED, firedFlags, mask));
-    }
-
-    /**
-     * Deletes a pairing with a remote device and checks to make sure that the devices are unpaired
-     * and that the correct actions were broadcast.
-     *
-     * @param adapter The BT adapter.
-     * @param device The remote device.
-     */
-    public void unpair(BluetoothAdapter adapter, BluetoothDevice device) {
-        int mask = PairReceiver.STATE_NONE_FLAG;
-        long start = -1;
-        String methodName = String.format("unpair(device=%s)", device);
-
-        if (!adapter.isEnabled()) {
-            fail(String.format("%s bluetooth not enabled", methodName));
-        }
-
-        PairReceiver receiver = getPairReceiver(device, 0, null, mask);
-
-        int state = device.getBondState();
-        switch (state) {
-            case BluetoothDevice.BOND_NONE:
-                assertFalse(adapter.getBondedDevices().contains(device));
-                removeReceiver(receiver);
-                return;
-            case BluetoothDevice.BOND_BONDING:
-                start = System.currentTimeMillis();
-                assertTrue(device.removeBond());
-                break;
-            case BluetoothDevice.BOND_BONDED:
-                assertTrue(adapter.getBondedDevices().contains(device));
-                start = System.currentTimeMillis();
-                assertTrue(device.removeBond());
-                break;
-            default:
-                removeReceiver(receiver);
-                fail(String.format("%s invalid state: state=%d", methodName, state));
-        }
-
-        long s = System.currentTimeMillis();
-        while (System.currentTimeMillis() - s < PAIR_UNPAIR_TIMEOUT) {
-            if (device.getBondState() == BluetoothDevice.BOND_NONE
-                    && (receiver.getFiredFlags() & mask) == mask) {
-                assertFalse(adapter.getBondedDevices().contains(device));
-                long finish = receiver.getCompletedTime();
-                if (start != -1 && finish != -1) {
-                    writeOutput(String.format("%s completed in %d ms", methodName,
-                            (finish - start)));
-                } else {
-                    writeOutput(String.format("%s completed", methodName));
-                }
-                removeReceiver(receiver);
-                return;
-            }
-        }
-
-        int firedFlags = receiver.getFiredFlags();
-        removeReceiver(receiver);
-        fail(String.format("%s timeout: state=%d (expected %d), flags=0x%x (expected 0x%x)",
-                methodName, state, BluetoothDevice.BOND_BONDED, firedFlags, mask));
-    }
-
-    /**
-     * Deletes all pairings of remote devices
-     * @param adapter the BT adapter
-     */
-    public void unpairAll(BluetoothAdapter adapter) {
-        Set<BluetoothDevice> devices = adapter.getBondedDevices();
-        for (BluetoothDevice device : devices) {
-            unpair(adapter, device);
-        }
-    }
-
-    /**
-     * Connects a profile from the local device to a remote device and checks to make sure that the
-     * profile is connected and that the correct actions were broadcast.
-     *
-     * @param adapter The BT adapter.
-     * @param device The remote device.
-     * @param profile The profile to connect. One of {@link BluetoothProfile#A2DP},
-     * {@link BluetoothProfile#HEADSET}, {@link BluetoothProfile#HID_HOST} or {@link BluetoothProfile#MAP_CLIENT}..
-     * @param methodName The method name to printed in the logs.  If null, will be
-     * "connectProfile(profile=&lt;profile&gt;, device=&lt;device&gt;)"
-     */
-    public void connectProfile(BluetoothAdapter adapter, BluetoothDevice device, int profile,
-            String methodName) {
-        if (methodName == null) {
-            methodName = String.format("connectProfile(profile=%d, device=%s)", profile, device);
-        }
-        int mask = (ConnectProfileReceiver.STATE_CONNECTING_FLAG
-                | ConnectProfileReceiver.STATE_CONNECTED_FLAG);
-        long start = -1;
-
-        if (!adapter.isEnabled()) {
-            fail(String.format("%s bluetooth not enabled", methodName));
-        }
-
-        if (!adapter.getBondedDevices().contains(device)) {
-            fail(String.format("%s device not paired", methodName));
-        }
-
-        BluetoothProfile proxy = connectProxy(adapter, profile);
-        assertNotNull(proxy);
-
-        ConnectProfileReceiver receiver = getConnectProfileReceiver(device, profile, mask);
-
-        int state = proxy.getConnectionState(device);
-        switch (state) {
-            case BluetoothProfile.STATE_CONNECTED:
-                removeReceiver(receiver);
-                return;
-            case BluetoothProfile.STATE_CONNECTING:
-                mask = 0; // Don't check for received intents since we might have missed them.
-                break;
-            case BluetoothProfile.STATE_DISCONNECTED:
-            case BluetoothProfile.STATE_DISCONNECTING:
-                start = System.currentTimeMillis();
-                if (profile == BluetoothProfile.A2DP) {
-                    assertTrue(((BluetoothA2dp)proxy).connect(device));
-                } else if (profile == BluetoothProfile.HEADSET) {
-                    assertTrue(((BluetoothHeadset)proxy).connect(device));
-                } else if (profile == BluetoothProfile.HID_HOST) {
-                    assertTrue(((BluetoothHidHost)proxy).connect(device));
-                } else if (profile == BluetoothProfile.MAP_CLIENT) {
-                    assertTrue(((BluetoothMapClient)proxy).connect(device));
-                }
-                break;
-            default:
-                removeReceiver(receiver);
-                fail(String.format("%s invalid state: state=%d", methodName, state));
-        }
-
-        long s = System.currentTimeMillis();
-        while (System.currentTimeMillis() - s < CONNECT_DISCONNECT_PROFILE_TIMEOUT) {
-            state = proxy.getConnectionState(device);
-            if (state == BluetoothProfile.STATE_CONNECTED
-                    && (receiver.getFiredFlags() & mask) == mask) {
-                long finish = receiver.getCompletedTime();
-                if (start != -1 && finish != -1) {
-                    writeOutput(String.format("%s completed in %d ms", methodName,
-                            (finish - start)));
-                } else {
-                    writeOutput(String.format("%s completed", methodName));
-                }
-                removeReceiver(receiver);
-                return;
-            }
-            sleep(POLL_TIME);
-        }
-
-        int firedFlags = receiver.getFiredFlags();
-        removeReceiver(receiver);
-        fail(String.format("%s timeout: state=%d (expected %d), flags=0x%x (expected 0x%x)",
-                methodName, state, BluetoothProfile.STATE_CONNECTED, firedFlags, mask));
-    }
-
-    /**
-     * Disconnects a profile between the local device and a remote device and checks to make sure
-     * that the profile is disconnected and that the correct actions were broadcast.
-     *
-     * @param adapter The BT adapter.
-     * @param device The remote device.
-     * @param profile The profile to disconnect. One of {@link BluetoothProfile#A2DP},
-     * {@link BluetoothProfile#HEADSET}, or {@link BluetoothProfile#HID_HOST}.
-     * @param methodName The method name to printed in the logs.  If null, will be
-     * "connectProfile(profile=&lt;profile&gt;, device=&lt;device&gt;)"
-     */
-    public void disconnectProfile(BluetoothAdapter adapter, BluetoothDevice device, int profile,
-            String methodName) {
-        if (methodName == null) {
-            methodName = String.format("disconnectProfile(profile=%d, device=%s)", profile, device);
-        }
-        int mask = (ConnectProfileReceiver.STATE_DISCONNECTING_FLAG
-                | ConnectProfileReceiver.STATE_DISCONNECTED_FLAG);
-        long start = -1;
-
-        if (!adapter.isEnabled()) {
-            fail(String.format("%s bluetooth not enabled", methodName));
-        }
-
-        if (!adapter.getBondedDevices().contains(device)) {
-            fail(String.format("%s device not paired", methodName));
-        }
-
-        BluetoothProfile proxy = connectProxy(adapter, profile);
-        assertNotNull(proxy);
-
-        ConnectProfileReceiver receiver = getConnectProfileReceiver(device, profile, mask);
-
-        int state = proxy.getConnectionState(device);
-        switch (state) {
-            case BluetoothProfile.STATE_CONNECTED:
-            case BluetoothProfile.STATE_CONNECTING:
-                start = System.currentTimeMillis();
-                if (profile == BluetoothProfile.A2DP) {
-                    assertTrue(((BluetoothA2dp)proxy).disconnect(device));
-                } else if (profile == BluetoothProfile.HEADSET) {
-                    assertTrue(((BluetoothHeadset)proxy).disconnect(device));
-                } else if (profile == BluetoothProfile.HID_HOST) {
-                    assertTrue(((BluetoothHidHost)proxy).disconnect(device));
-                } else if (profile == BluetoothProfile.MAP_CLIENT) {
-                    assertTrue(((BluetoothMapClient)proxy).disconnect(device));
-                }
-                break;
-            case BluetoothProfile.STATE_DISCONNECTED:
-                removeReceiver(receiver);
-                return;
-            case BluetoothProfile.STATE_DISCONNECTING:
-                mask = 0; // Don't check for received intents since we might have missed them.
-                break;
-            default:
-                removeReceiver(receiver);
-                fail(String.format("%s invalid state: state=%d", methodName, state));
-        }
-
-        long s = System.currentTimeMillis();
-        while (System.currentTimeMillis() - s < CONNECT_DISCONNECT_PROFILE_TIMEOUT) {
-            state = proxy.getConnectionState(device);
-            if (state == BluetoothProfile.STATE_DISCONNECTED
-                    && (receiver.getFiredFlags() & mask) == mask) {
-                long finish = receiver.getCompletedTime();
-                if (start != -1 && finish != -1) {
-                    writeOutput(String.format("%s completed in %d ms", methodName,
-                            (finish - start)));
-                } else {
-                    writeOutput(String.format("%s completed", methodName));
-                }
-                removeReceiver(receiver);
-                return;
-            }
-            sleep(POLL_TIME);
-        }
-
-        int firedFlags = receiver.getFiredFlags();
-        removeReceiver(receiver);
-        fail(String.format("%s timeout: state=%d (expected %d), flags=0x%x (expected 0x%x)",
-                methodName, state, BluetoothProfile.STATE_DISCONNECTED, firedFlags, mask));
-    }
-
-    /**
-     * Connects the PANU to a remote NAP and checks to make sure that the PANU is connected and that
-     * the correct actions were broadcast.
-     *
-     * @param adapter The BT adapter.
-     * @param device The remote device.
-     */
-    public void connectPan(BluetoothAdapter adapter, BluetoothDevice device) {
-        connectPanOrIncomingPanConnection(adapter, device, true);
-    }
-
-    /**
-     * Checks that a remote PANU connects to the local NAP correctly and that the correct actions
-     * were broadcast.
-     *
-     * @param adapter The BT adapter.
-     * @param device The remote device.
-     */
-    public void incomingPanConnection(BluetoothAdapter adapter, BluetoothDevice device) {
-        connectPanOrIncomingPanConnection(adapter, device, false);
-    }
-
-    /**
-     * Helper method used by {@link #connectPan(BluetoothAdapter, BluetoothDevice)} and
-     * {@link #incomingPanConnection(BluetoothAdapter, BluetoothDevice)} to either connect to a
-     * remote NAP or verify that a remote device connected to the local NAP.
-     *
-     * @param adapter The BT adapter.
-     * @param device The remote device.
-     * @param connect If the method should initiate the connection (is PANU)
-     */
-    private void connectPanOrIncomingPanConnection(BluetoothAdapter adapter, BluetoothDevice device,
-            boolean connect) {
-        long start = -1;
-        int mask, role;
-        String methodName;
-
-        if (connect) {
-            methodName = String.format("connectPan(device=%s)", device);
-            mask = (ConnectProfileReceiver.STATE_CONNECTED_FLAG |
-                    ConnectProfileReceiver.STATE_CONNECTING_FLAG);
-            role = BluetoothPan.LOCAL_PANU_ROLE;
-        } else {
-            methodName = String.format("incomingPanConnection(device=%s)", device);
-            mask = ConnectProfileReceiver.STATE_CONNECTED_FLAG;
-            role = BluetoothPan.LOCAL_NAP_ROLE;
-        }
-
-        if (!adapter.isEnabled()) {
-            fail(String.format("%s bluetooth not enabled", methodName));
-        }
-
-        if (!adapter.getBondedDevices().contains(device)) {
-            fail(String.format("%s device not paired", methodName));
-        }
-
-        mPan = (BluetoothPan) connectProxy(adapter, BluetoothProfile.PAN);
-        assertNotNull(mPan);
-        ConnectPanReceiver receiver = getConnectPanReceiver(device, role, mask);
-
-        int state = mPan.getConnectionState(device);
-        switch (state) {
-            case BluetoothPan.STATE_CONNECTED:
-                removeReceiver(receiver);
-                return;
-            case BluetoothPan.STATE_CONNECTING:
-                mask = 0; // Don't check for received intents since we might have missed them.
-                break;
-            case BluetoothPan.STATE_DISCONNECTED:
-            case BluetoothPan.STATE_DISCONNECTING:
-                start = System.currentTimeMillis();
-                if (role == BluetoothPan.LOCAL_PANU_ROLE) {
-                    Log.i("BT", "connect to pan");
-                    assertTrue(mPan.connect(device));
-                }
-                break;
-            default:
-                removeReceiver(receiver);
-                fail(String.format("%s invalid state: state=%d", methodName, state));
-        }
-
-        long s = System.currentTimeMillis();
-        while (System.currentTimeMillis() - s < CONNECT_DISCONNECT_PROFILE_TIMEOUT) {
-            state = mPan.getConnectionState(device);
-            if (state == BluetoothPan.STATE_CONNECTED
-                    && (receiver.getFiredFlags() & mask) == mask) {
-                long finish = receiver.getCompletedTime();
-                if (start != -1 && finish != -1) {
-                    writeOutput(String.format("%s completed in %d ms", methodName,
-                            (finish - start)));
-                } else {
-                    writeOutput(String.format("%s completed", methodName));
-                }
-                removeReceiver(receiver);
-                return;
-            }
-            sleep(POLL_TIME);
-        }
-
-        int firedFlags = receiver.getFiredFlags();
-        removeReceiver(receiver);
-        fail(String.format("%s timeout: state=%d (expected %d), flags=0x%x (expected 0x%s)",
-                methodName, state, BluetoothPan.STATE_CONNECTED, firedFlags, mask));
-    }
-
-    /**
-     * Disconnects the PANU from a remote NAP and checks to make sure that the PANU is disconnected
-     * and that the correct actions were broadcast.
-     *
-     * @param adapter The BT adapter.
-     * @param device The remote device.
-     */
-    public void disconnectPan(BluetoothAdapter adapter, BluetoothDevice device) {
-        disconnectFromRemoteOrVerifyConnectNap(adapter, device, true);
-    }
-
-    /**
-     * Checks that a remote PANU disconnects from the local NAP correctly and that the correct
-     * actions were broadcast.
-     *
-     * @param adapter The BT adapter.
-     * @param device The remote device.
-     */
-    public void incomingPanDisconnection(BluetoothAdapter adapter, BluetoothDevice device) {
-        disconnectFromRemoteOrVerifyConnectNap(adapter, device, false);
-    }
-
-    /**
-     * Helper method used by {@link #disconnectPan(BluetoothAdapter, BluetoothDevice)} and
-     * {@link #incomingPanDisconnection(BluetoothAdapter, BluetoothDevice)} to either disconnect
-     * from a remote NAP or verify that a remote device disconnected from the local NAP.
-     *
-     * @param adapter The BT adapter.
-     * @param device The remote device.
-     * @param disconnect Whether the method should connect or verify.
-     */
-    private void disconnectFromRemoteOrVerifyConnectNap(BluetoothAdapter adapter,
-            BluetoothDevice device, boolean disconnect) {
-        long start = -1;
-        int mask, role;
-        String methodName;
-
-        if (disconnect) {
-            methodName = String.format("disconnectPan(device=%s)", device);
-            mask = (ConnectProfileReceiver.STATE_DISCONNECTED_FLAG |
-                    ConnectProfileReceiver.STATE_DISCONNECTING_FLAG);
-            role = BluetoothPan.LOCAL_PANU_ROLE;
-        } else {
-            methodName = String.format("incomingPanDisconnection(device=%s)", device);
-            mask = ConnectProfileReceiver.STATE_DISCONNECTED_FLAG;
-            role = BluetoothPan.LOCAL_NAP_ROLE;
-        }
-
-        if (!adapter.isEnabled()) {
-            fail(String.format("%s bluetooth not enabled", methodName));
-        }
-
-        if (!adapter.getBondedDevices().contains(device)) {
-            fail(String.format("%s device not paired", methodName));
-        }
-
-        mPan = (BluetoothPan) connectProxy(adapter, BluetoothProfile.PAN);
-        assertNotNull(mPan);
-        ConnectPanReceiver receiver = getConnectPanReceiver(device, role, mask);
-
-        int state = mPan.getConnectionState(device);
-        switch (state) {
-            case BluetoothPan.STATE_CONNECTED:
-            case BluetoothPan.STATE_CONNECTING:
-                start = System.currentTimeMillis();
-                if (role == BluetoothPan.LOCAL_PANU_ROLE) {
-                    assertTrue(mPan.disconnect(device));
-                }
-                break;
-            case BluetoothPan.STATE_DISCONNECTED:
-                removeReceiver(receiver);
-                return;
-            case BluetoothPan.STATE_DISCONNECTING:
-                mask = 0; // Don't check for received intents since we might have missed them.
-                break;
-            default:
-                removeReceiver(receiver);
-                fail(String.format("%s invalid state: state=%d", methodName, state));
-        }
-
-        long s = System.currentTimeMillis();
-        while (System.currentTimeMillis() - s < CONNECT_DISCONNECT_PROFILE_TIMEOUT) {
-            state = mPan.getConnectionState(device);
-            if (state == BluetoothHidHost.STATE_DISCONNECTED
-                    && (receiver.getFiredFlags() & mask) == mask) {
-                long finish = receiver.getCompletedTime();
-                if (start != -1 && finish != -1) {
-                    writeOutput(String.format("%s completed in %d ms", methodName,
-                            (finish - start)));
-                } else {
-                    writeOutput(String.format("%s completed", methodName));
-                }
-                removeReceiver(receiver);
-                return;
-            }
-            sleep(POLL_TIME);
-        }
-
-        int firedFlags = receiver.getFiredFlags();
-        removeReceiver(receiver);
-        fail(String.format("%s timeout: state=%d (expected %d), flags=0x%x (expected 0x%s)",
-                methodName, state, BluetoothHidHost.STATE_DISCONNECTED, firedFlags, mask));
-    }
-
-    /**
-     * Opens a SCO channel using {@link android.media.AudioManager#startBluetoothSco()} and checks
-     * to make sure that the channel is opened and that the correct actions were broadcast.
-     *
-     * @param adapter The BT adapter.
-     * @param device The remote device.
-     */
-    public void startSco(BluetoothAdapter adapter, BluetoothDevice device) {
-        startStopSco(adapter, device, true);
-    }
-
-    /**
-     * Closes a SCO channel using {@link android.media.AudioManager#stopBluetoothSco()} and checks
-     *  to make sure that the channel is closed and that the correct actions were broadcast.
-     *
-     * @param adapter The BT adapter.
-     * @param device The remote device.
-     */
-    public void stopSco(BluetoothAdapter adapter, BluetoothDevice device) {
-        startStopSco(adapter, device, false);
-    }
-    /**
-     * Helper method for {@link #startSco(BluetoothAdapter, BluetoothDevice)} and
-     * {@link #stopSco(BluetoothAdapter, BluetoothDevice)}.
-     *
-     * @param adapter The BT adapter.
-     * @param device The remote device.
-     * @param isStart Whether the SCO channel should be opened.
-     */
-    private void startStopSco(BluetoothAdapter adapter, BluetoothDevice device, boolean isStart) {
-        long start = -1;
-        int mask;
-        String methodName;
-
-        if (isStart) {
-            methodName = String.format("startSco(device=%s)", device);
-            mask = StartStopScoReceiver.STATE_CONNECTED_FLAG;
-        } else {
-            methodName = String.format("stopSco(device=%s)", device);
-            mask = StartStopScoReceiver.STATE_DISCONNECTED_FLAG;
-        }
-
-        if (!adapter.isEnabled()) {
-            fail(String.format("%s bluetooth not enabled", methodName));
-        }
-
-        if (!adapter.getBondedDevices().contains(device)) {
-            fail(String.format("%s device not paired", methodName));
-        }
-
-        AudioManager manager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
-        assertNotNull(manager);
-
-        if (!manager.isBluetoothScoAvailableOffCall()) {
-            fail(String.format("%s device does not support SCO", methodName));
-        }
-
-        boolean isScoOn = manager.isBluetoothScoOn();
-        if (isStart == isScoOn) {
-            return;
-        }
-
-        StartStopScoReceiver receiver = getStartStopScoReceiver(mask);
-        start = System.currentTimeMillis();
-        if (isStart) {
-            manager.startBluetoothSco();
-        } else {
-            manager.stopBluetoothSco();
-        }
-
-        long s = System.currentTimeMillis();
-        while (System.currentTimeMillis() - s < START_STOP_SCO_TIMEOUT) {
-            isScoOn = manager.isBluetoothScoOn();
-            if (isStart == isScoOn && (receiver.getFiredFlags() & mask) == mask) {
-                long finish = receiver.getCompletedTime();
-                if (start != -1 && finish != -1) {
-                    writeOutput(String.format("%s completed in %d ms", methodName,
-                            (finish - start)));
-                } else {
-                    writeOutput(String.format("%s completed", methodName));
-                }
-                removeReceiver(receiver);
-                return;
-            }
-            sleep(POLL_TIME);
-        }
-
-        int firedFlags = receiver.getFiredFlags();
-        removeReceiver(receiver);
-        fail(String.format("%s timeout: on=%b (expected %b), flags=0x%x (expected 0x%x)",
-                methodName, isScoOn, isStart, firedFlags, mask));
-    }
-
-    /**
-     * Writes a string to the logcat and a file if a file has been specified in the constructor.
-     *
-     * @param s The string to be written.
-     */
-    public void writeOutput(String s) {
-        Log.i(mTag, s);
-        if (mOutputWriter == null) {
-            return;
-        }
-        try {
-            mOutputWriter.write(s + "\n");
-            mOutputWriter.flush();
-        } catch (IOException e) {
-            Log.w(mTag, "Could not write to output file", e);
-        }
-    }
-
-    public void mceGetUnreadMessage(BluetoothAdapter adapter, BluetoothDevice device) {
-        int mask;
-        String methodName = "getUnreadMessage";
-
-        if (!adapter.isEnabled()) {
-            fail(String.format("%s bluetooth not enabled", methodName));
-        }
-
-        if (!adapter.getBondedDevices().contains(device)) {
-            fail(String.format("%s device not paired", methodName));
-        }
-
-        mMce = (BluetoothMapClient) connectProxy(adapter, BluetoothProfile.MAP_CLIENT);
-        assertNotNull(mMce);
-
-        if (mMce.getConnectionState(device) != BluetoothProfile.STATE_CONNECTED) {
-            fail(String.format("%s device is not connected", methodName));
-        }
-
-        mMsgHandle = null;
-        mask = MceSetMessageStatusReceiver.MESSAGE_RECEIVED_FLAG;
-        MceSetMessageStatusReceiver receiver = getMceSetMessageStatusReceiver(device, mask);
-        assertTrue(mMce.getUnreadMessages(device));
-
-        long s = System.currentTimeMillis();
-        while (System.currentTimeMillis() - s < GET_UNREAD_MESSAGE_TIMEOUT) {
-            if ((receiver.getFiredFlags() & mask) == mask) {
-                writeOutput(String.format("%s completed", methodName));
-                removeReceiver(receiver);
-                return;
-            }
-            sleep(POLL_TIME);
-        }
-        int firedFlags = receiver.getFiredFlags();
-        removeReceiver(receiver);
-        fail(String.format("%s timeout: state=%d (expected %d), flags=0x%x (expected 0x%s)",
-                methodName, mMce.getConnectionState(device), BluetoothMapClient.STATE_CONNECTED, firedFlags, mask));
-    }
-
-    /**
-     * Set a message to read/unread/deleted/undeleted
-     */
-    public void mceSetMessageStatus(BluetoothAdapter adapter, BluetoothDevice device, int status) {
-        int mask;
-        String methodName = "setMessageStatus";
-
-        if (!adapter.isEnabled()) {
-            fail(String.format("%s bluetooth not enabled", methodName));
-        }
-
-        if (!adapter.getBondedDevices().contains(device)) {
-            fail(String.format("%s device not paired", methodName));
-        }
-
-        mMce = (BluetoothMapClient) connectProxy(adapter, BluetoothProfile.MAP_CLIENT);
-        assertNotNull(mMce);
-
-        if (mMce.getConnectionState(device) != BluetoothProfile.STATE_CONNECTED) {
-            fail(String.format("%s device is not connected", methodName));
-        }
-
-        assertNotNull(mMsgHandle);
-        mask = MceSetMessageStatusReceiver.STATUS_CHANGED_FLAG;
-        MceSetMessageStatusReceiver receiver = getMceSetMessageStatusReceiver(device, mask);
-
-        assertTrue(mMce.setMessageStatus(device, mMsgHandle, status));
-
-        long s = System.currentTimeMillis();
-        while (System.currentTimeMillis() - s < SET_MESSAGE_STATUS_TIMEOUT) {
-            if ((receiver.getFiredFlags() & mask) == mask) {
-                writeOutput(String.format("%s completed", methodName));
-                removeReceiver(receiver);
-                return;
-            }
-            sleep(POLL_TIME);
-        }
-
-        int firedFlags = receiver.getFiredFlags();
-        removeReceiver(receiver);
-        fail(String.format("%s timeout: state=%d (expected %d), flags=0x%x (expected 0x%s)",
-                methodName, mMce.getConnectionState(device), BluetoothPan.STATE_CONNECTED, firedFlags, mask));
-    }
-
-    private void addReceiver(BroadcastReceiver receiver, String[] actions) {
-        IntentFilter filter = new IntentFilter();
-        for (String action: actions) {
-            filter.addAction(action);
-        }
-        mContext.registerReceiver(receiver, filter);
-        mReceivers.add(receiver);
-    }
-
-    private BluetoothReceiver getBluetoothReceiver(int expectedFlags) {
-        String[] actions = {
-                BluetoothAdapter.ACTION_DISCOVERY_FINISHED,
-                BluetoothAdapter.ACTION_DISCOVERY_STARTED,
-                BluetoothAdapter.ACTION_SCAN_MODE_CHANGED,
-                BluetoothAdapter.ACTION_STATE_CHANGED};
-        BluetoothReceiver receiver = new BluetoothReceiver(expectedFlags);
-        addReceiver(receiver, actions);
-        return receiver;
-    }
-
-    private PairReceiver getPairReceiver(BluetoothDevice device, int passkey, byte[] pin,
-            int expectedFlags) {
-        String[] actions = {
-                BluetoothDevice.ACTION_PAIRING_REQUEST,
-                BluetoothDevice.ACTION_BOND_STATE_CHANGED};
-        PairReceiver receiver = new PairReceiver(device, passkey, pin, expectedFlags);
-        addReceiver(receiver, actions);
-        return receiver;
-    }
-
-    private ConnectProfileReceiver getConnectProfileReceiver(BluetoothDevice device, int profile,
-            int expectedFlags) {
-        String[] actions = {
-                BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED,
-                BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED,
-                BluetoothHidHost.ACTION_CONNECTION_STATE_CHANGED,
-                BluetoothMapClient.ACTION_CONNECTION_STATE_CHANGED};
-        ConnectProfileReceiver receiver = new ConnectProfileReceiver(device, profile,
-                expectedFlags);
-        addReceiver(receiver, actions);
-        return receiver;
-    }
-
-    private ConnectPanReceiver getConnectPanReceiver(BluetoothDevice device, int role,
-            int expectedFlags) {
-        String[] actions = {BluetoothPan.ACTION_CONNECTION_STATE_CHANGED};
-        ConnectPanReceiver receiver = new ConnectPanReceiver(device, role, expectedFlags);
-        addReceiver(receiver, actions);
-        return receiver;
-    }
-
-    private StartStopScoReceiver getStartStopScoReceiver(int expectedFlags) {
-        String[] actions = {AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED};
-        StartStopScoReceiver receiver = new StartStopScoReceiver(expectedFlags);
-        addReceiver(receiver, actions);
-        return receiver;
-    }
-
-    private MceSetMessageStatusReceiver getMceSetMessageStatusReceiver(BluetoothDevice device,
-            int expectedFlags) {
-        String[] actions = {BluetoothMapClient.ACTION_MESSAGE_RECEIVED,
-            BluetoothMapClient.ACTION_MESSAGE_READ_STATUS_CHANGED,
-            BluetoothMapClient.ACTION_MESSAGE_DELETED_STATUS_CHANGED};
-        MceSetMessageStatusReceiver receiver = new MceSetMessageStatusReceiver(expectedFlags);
-        addReceiver(receiver, actions);
-        return receiver;
-    }
-
-    private void removeReceiver(BroadcastReceiver receiver) {
-        mContext.unregisterReceiver(receiver);
-        mReceivers.remove(receiver);
-    }
-
-    private BluetoothProfile connectProxy(BluetoothAdapter adapter, int profile) {
-        switch (profile) {
-            case BluetoothProfile.A2DP:
-                if (mA2dp != null) {
-                    return mA2dp;
-                }
-                break;
-            case BluetoothProfile.HEADSET:
-                if (mHeadset != null) {
-                    return mHeadset;
-                }
-                break;
-            case BluetoothProfile.HID_HOST:
-                if (mInput != null) {
-                    return mInput;
-                }
-                break;
-            case BluetoothProfile.PAN:
-                if (mPan != null) {
-                    return mPan;
-                }
-            case BluetoothProfile.MAP_CLIENT:
-                if (mMce != null) {
-                    return mMce;
-                }
-                break;
-            default:
-                return null;
-        }
-        adapter.getProfileProxy(mContext, mServiceListener, profile);
-        long s = System.currentTimeMillis();
-        switch (profile) {
-            case BluetoothProfile.A2DP:
-                while (mA2dp == null && System.currentTimeMillis() - s < CONNECT_PROXY_TIMEOUT) {
-                    sleep(POLL_TIME);
-                }
-                return mA2dp;
-            case BluetoothProfile.HEADSET:
-                while (mHeadset == null && System.currentTimeMillis() - s < CONNECT_PROXY_TIMEOUT) {
-                    sleep(POLL_TIME);
-                }
-                return mHeadset;
-            case BluetoothProfile.HID_HOST:
-                while (mInput == null && System.currentTimeMillis() - s < CONNECT_PROXY_TIMEOUT) {
-                    sleep(POLL_TIME);
-                }
-                return mInput;
-            case BluetoothProfile.PAN:
-                while (mPan == null && System.currentTimeMillis() - s < CONNECT_PROXY_TIMEOUT) {
-                    sleep(POLL_TIME);
-                }
-                return mPan;
-            case BluetoothProfile.MAP_CLIENT:
-                while (mMce == null && System.currentTimeMillis() - s < CONNECT_PROXY_TIMEOUT) {
-                    sleep(POLL_TIME);
-                }
-                return mMce;
-            default:
-                return null;
-        }
-    }
-
-    private void sleep(long time) {
-        try {
-            Thread.sleep(time);
-        } catch (InterruptedException e) {
-        }
-    }
-}
diff --git a/core/tests/bluetoothtests/src/android/bluetooth/BluetoothUuidTest.java b/core/tests/bluetoothtests/src/android/bluetooth/BluetoothUuidTest.java
deleted file mode 100644
index 536d722..0000000
--- a/core/tests/bluetoothtests/src/android/bluetooth/BluetoothUuidTest.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-import android.os.ParcelUuid;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import junit.framework.TestCase;
-
-/**
- * Unit test cases for {@link BluetoothUuid}.
- * <p>
- * To run this test, use adb shell am instrument -e class 'android.bluetooth.BluetoothUuidTest' -w
- * 'com.android.bluetooth.tests/android.bluetooth.BluetoothTestRunner'
- */
-public class BluetoothUuidTest extends TestCase {
-
-    @SmallTest
-    public void testUuidParser() {
-        byte[] uuid16 = new byte[] {
-                0x0B, 0x11 };
-        assertEquals(ParcelUuid.fromString("0000110B-0000-1000-8000-00805F9B34FB"),
-                BluetoothUuid.parseUuidFrom(uuid16));
-
-        byte[] uuid32 = new byte[] {
-                0x0B, 0x11, 0x33, (byte) 0xFE };
-        assertEquals(ParcelUuid.fromString("FE33110B-0000-1000-8000-00805F9B34FB"),
-                BluetoothUuid.parseUuidFrom(uuid32));
-
-        byte[] uuid128 = new byte[] {
-                0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
-                0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, (byte) 0xFF };
-        assertEquals(ParcelUuid.fromString("FF0F0E0D-0C0B-0A09-0807-0060504030201"),
-                BluetoothUuid.parseUuidFrom(uuid128));
-    }
-
-    @SmallTest
-    public void testUuidType() {
-        assertTrue(BluetoothUuid.is16BitUuid(
-                ParcelUuid.fromString("0000110B-0000-1000-8000-00805F9B34FB")));
-        assertFalse(BluetoothUuid.is32BitUuid(
-                ParcelUuid.fromString("0000110B-0000-1000-8000-00805F9B34FB")));
-
-        assertFalse(BluetoothUuid.is16BitUuid(
-                ParcelUuid.fromString("FE33110B-0000-1000-8000-00805F9B34FB")));
-        assertTrue(BluetoothUuid.is32BitUuid(
-                ParcelUuid.fromString("FE33110B-0000-1000-8000-00805F9B34FB")));
-        assertFalse(BluetoothUuid.is32BitUuid(
-                ParcelUuid.fromString("FE33110B-1000-1000-8000-00805F9B34FB")));
-
-    }
-}
diff --git a/core/tests/bluetoothtests/src/android/bluetooth/le/AdvertiseDataTest.java b/core/tests/bluetoothtests/src/android/bluetooth/le/AdvertiseDataTest.java
deleted file mode 100644
index e58d905..0000000
--- a/core/tests/bluetoothtests/src/android/bluetooth/le/AdvertiseDataTest.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.le;
-
-import android.os.Parcel;
-import android.os.ParcelUuid;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import junit.framework.TestCase;
-
-/**
- * Unit test cases for {@link AdvertiseData}.
- * <p>
- * To run the test, use adb shell am instrument -e class 'android.bluetooth.le.AdvertiseDataTest' -w
- * 'com.android.bluetooth.tests/android.bluetooth.BluetoothTestRunner'
- */
-public class AdvertiseDataTest extends TestCase {
-
-    private AdvertiseData.Builder mAdvertiseDataBuilder;
-
-    @Override
-    protected void setUp() throws Exception {
-        mAdvertiseDataBuilder = new AdvertiseData.Builder();
-    }
-
-    @SmallTest
-    public void testEmptyData() {
-        Parcel parcel = Parcel.obtain();
-        AdvertiseData data = mAdvertiseDataBuilder.build();
-        data.writeToParcel(parcel, 0);
-        parcel.setDataPosition(0);
-        AdvertiseData dataFromParcel =
-                AdvertiseData.CREATOR.createFromParcel(parcel);
-        assertEquals(data, dataFromParcel);
-    }
-
-    @SmallTest
-    public void testEmptyServiceUuid() {
-        Parcel parcel = Parcel.obtain();
-        AdvertiseData data = mAdvertiseDataBuilder.setIncludeDeviceName(true).build();
-        data.writeToParcel(parcel, 0);
-        parcel.setDataPosition(0);
-        AdvertiseData dataFromParcel =
-                AdvertiseData.CREATOR.createFromParcel(parcel);
-        assertEquals(data, dataFromParcel);
-    }
-
-    @SmallTest
-    public void testEmptyManufacturerData() {
-        Parcel parcel = Parcel.obtain();
-        int manufacturerId = 50;
-        byte[] manufacturerData = new byte[0];
-        AdvertiseData data =
-                mAdvertiseDataBuilder.setIncludeDeviceName(true)
-                        .addManufacturerData(manufacturerId, manufacturerData).build();
-        data.writeToParcel(parcel, 0);
-        parcel.setDataPosition(0);
-        AdvertiseData dataFromParcel =
-                AdvertiseData.CREATOR.createFromParcel(parcel);
-        assertEquals(data, dataFromParcel);
-    }
-
-    @SmallTest
-    public void testEmptyServiceData() {
-        Parcel parcel = Parcel.obtain();
-        ParcelUuid uuid = ParcelUuid.fromString("0000110A-0000-1000-8000-00805F9B34FB");
-        byte[] serviceData = new byte[0];
-        AdvertiseData data =
-                mAdvertiseDataBuilder.setIncludeDeviceName(true)
-                        .addServiceData(uuid, serviceData).build();
-        data.writeToParcel(parcel, 0);
-        parcel.setDataPosition(0);
-        AdvertiseData dataFromParcel =
-                AdvertiseData.CREATOR.createFromParcel(parcel);
-        assertEquals(data, dataFromParcel);
-    }
-
-    @SmallTest
-    public void testServiceUuid() {
-        Parcel parcel = Parcel.obtain();
-        ParcelUuid uuid = ParcelUuid.fromString("0000110A-0000-1000-8000-00805F9B34FB");
-        ParcelUuid uuid2 = ParcelUuid.fromString("0000110B-0000-1000-8000-00805F9B34FB");
-
-        AdvertiseData data =
-                mAdvertiseDataBuilder.setIncludeDeviceName(true)
-                        .addServiceUuid(uuid).addServiceUuid(uuid2).build();
-        data.writeToParcel(parcel, 0);
-        parcel.setDataPosition(0);
-        AdvertiseData dataFromParcel =
-                AdvertiseData.CREATOR.createFromParcel(parcel);
-        assertEquals(data, dataFromParcel);
-    }
-
-    @SmallTest
-    public void testManufacturerData() {
-        Parcel parcel = Parcel.obtain();
-        ParcelUuid uuid = ParcelUuid.fromString("0000110A-0000-1000-8000-00805F9B34FB");
-        ParcelUuid uuid2 = ParcelUuid.fromString("0000110B-0000-1000-8000-00805F9B34FB");
-
-        int manufacturerId = 50;
-        byte[] manufacturerData = new byte[] {
-                (byte) 0xF0, 0x00, 0x02, 0x15 };
-        AdvertiseData data =
-                mAdvertiseDataBuilder.setIncludeDeviceName(true)
-                        .addServiceUuid(uuid).addServiceUuid(uuid2)
-                        .addManufacturerData(manufacturerId, manufacturerData).build();
-
-        data.writeToParcel(parcel, 0);
-        parcel.setDataPosition(0);
-        AdvertiseData dataFromParcel =
-                AdvertiseData.CREATOR.createFromParcel(parcel);
-        assertEquals(data, dataFromParcel);
-    }
-
-    @SmallTest
-    public void testServiceData() {
-        Parcel parcel = Parcel.obtain();
-        ParcelUuid uuid = ParcelUuid.fromString("0000110A-0000-1000-8000-00805F9B34FB");
-        byte[] serviceData = new byte[] {
-                (byte) 0xF0, 0x00, 0x02, 0x15 };
-        AdvertiseData data =
-                mAdvertiseDataBuilder.setIncludeDeviceName(true)
-                        .addServiceData(uuid, serviceData).build();
-        data.writeToParcel(parcel, 0);
-        parcel.setDataPosition(0);
-        AdvertiseData dataFromParcel =
-                AdvertiseData.CREATOR.createFromParcel(parcel);
-        assertEquals(data, dataFromParcel);
-    }
-}
diff --git a/core/tests/bluetoothtests/src/android/bluetooth/le/ScanFilterTest.java b/core/tests/bluetoothtests/src/android/bluetooth/le/ScanFilterTest.java
deleted file mode 100644
index 35da4bc..0000000
--- a/core/tests/bluetoothtests/src/android/bluetooth/le/ScanFilterTest.java
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.le;
-
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.le.ScanFilter;
-import android.bluetooth.le.ScanRecord;
-import android.os.Parcel;
-import android.os.ParcelUuid;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import junit.framework.TestCase;
-
-/**
- * Unit test cases for Bluetooth LE scan filters.
- * <p>
- * To run this test, use adb shell am instrument -e class 'android.bluetooth.ScanFilterTest' -w
- * 'com.android.bluetooth.tests/android.bluetooth.BluetoothTestRunner'
- */
-public class ScanFilterTest extends TestCase {
-
-    private static final String DEVICE_MAC = "01:02:03:04:05:AB";
-    private ScanResult mScanResult;
-    private ScanFilter.Builder mFilterBuilder;
-
-    @Override
-    protected void setUp() throws Exception {
-        byte[] scanRecord = new byte[] {
-                0x02, 0x01, 0x1a, // advertising flags
-                0x05, 0x02, 0x0b, 0x11, 0x0a, 0x11, // 16 bit service uuids
-                0x04, 0x09, 0x50, 0x65, 0x64, // setName
-                0x02, 0x0A, (byte) 0xec, // tx power level
-                0x05, 0x16, 0x0b, 0x11, 0x50, 0x64, // service data
-                0x05, (byte) 0xff, (byte) 0xe0, 0x00, 0x02, 0x15, // manufacturer specific data
-                0x03, 0x50, 0x01, 0x02, // an unknown data type won't cause trouble
-        };
-
-        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
-        BluetoothDevice device = adapter.getRemoteDevice(DEVICE_MAC);
-        mScanResult = new ScanResult(device, ScanRecord.parseFromBytes(scanRecord),
-                -10, 1397545200000000L);
-        mFilterBuilder = new ScanFilter.Builder();
-    }
-
-    @SmallTest
-    public void testsetNameFilter() {
-        ScanFilter filter = mFilterBuilder.setDeviceName("Ped").build();
-        assertTrue("setName filter fails", filter.matches(mScanResult));
-
-        filter = mFilterBuilder.setDeviceName("Pem").build();
-        assertFalse("setName filter fails", filter.matches(mScanResult));
-
-    }
-
-    @SmallTest
-    public void testDeviceFilter() {
-        ScanFilter filter = mFilterBuilder.setDeviceAddress(DEVICE_MAC).build();
-        assertTrue("device filter fails", filter.matches(mScanResult));
-
-        filter = mFilterBuilder.setDeviceAddress("11:22:33:44:55:66").build();
-        assertFalse("device filter fails", filter.matches(mScanResult));
-    }
-
-    @SmallTest
-    public void testsetServiceUuidFilter() {
-        ScanFilter filter = mFilterBuilder.setServiceUuid(
-                ParcelUuid.fromString("0000110A-0000-1000-8000-00805F9B34FB")).build();
-        assertTrue("uuid filter fails", filter.matches(mScanResult));
-
-        filter = mFilterBuilder.setServiceUuid(
-                ParcelUuid.fromString("0000110C-0000-1000-8000-00805F9B34FB")).build();
-        assertFalse("uuid filter fails", filter.matches(mScanResult));
-
-        filter = mFilterBuilder
-                .setServiceUuid(ParcelUuid.fromString("0000110C-0000-1000-8000-00805F9B34FB"),
-                        ParcelUuid.fromString("FFFFFFF0-FFFF-FFFF-FFFF-FFFFFFFFFFFF"))
-                .build();
-        assertTrue("uuid filter fails", filter.matches(mScanResult));
-    }
-
-    @SmallTest
-    public void testsetServiceDataFilter() {
-        byte[] setServiceData = new byte[] {
-                0x50, 0x64 };
-        ParcelUuid serviceDataUuid = ParcelUuid.fromString("0000110B-0000-1000-8000-00805F9B34FB");
-        ScanFilter filter = mFilterBuilder.setServiceData(serviceDataUuid, setServiceData).build();
-        assertTrue("service data filter fails", filter.matches(mScanResult));
-
-        byte[] emptyData = new byte[0];
-        filter = mFilterBuilder.setServiceData(serviceDataUuid, emptyData).build();
-        assertTrue("service data filter fails", filter.matches(mScanResult));
-
-        byte[] prefixData = new byte[] {
-                0x50 };
-        filter = mFilterBuilder.setServiceData(serviceDataUuid, prefixData).build();
-        assertTrue("service data filter fails", filter.matches(mScanResult));
-
-        byte[] nonMatchData = new byte[] {
-                0x51, 0x64 };
-        byte[] mask = new byte[] {
-                (byte) 0x00, (byte) 0xFF };
-        filter = mFilterBuilder.setServiceData(serviceDataUuid, nonMatchData, mask).build();
-        assertTrue("partial service data filter fails", filter.matches(mScanResult));
-
-        filter = mFilterBuilder.setServiceData(serviceDataUuid, nonMatchData).build();
-        assertFalse("service data filter fails", filter.matches(mScanResult));
-    }
-
-    @SmallTest
-    public void testManufacturerSpecificData() {
-        byte[] setManufacturerData = new byte[] {
-                0x02, 0x15 };
-        int manufacturerId = 0xE0;
-        ScanFilter filter =
-                mFilterBuilder.setManufacturerData(manufacturerId, setManufacturerData).build();
-        assertTrue("manufacturer data filter fails", filter.matches(mScanResult));
-
-        byte[] emptyData = new byte[0];
-        filter = mFilterBuilder.setManufacturerData(manufacturerId, emptyData).build();
-        assertTrue("manufacturer data filter fails", filter.matches(mScanResult));
-
-        byte[] prefixData = new byte[] {
-                0x02 };
-        filter = mFilterBuilder.setManufacturerData(manufacturerId, prefixData).build();
-        assertTrue("manufacturer data filter fails", filter.matches(mScanResult));
-
-        // Test data mask
-        byte[] nonMatchData = new byte[] {
-                0x02, 0x14 };
-        filter = mFilterBuilder.setManufacturerData(manufacturerId, nonMatchData).build();
-        assertFalse("manufacturer data filter fails", filter.matches(mScanResult));
-        byte[] mask = new byte[] {
-                (byte) 0xFF, (byte) 0x00
-        };
-        filter = mFilterBuilder.setManufacturerData(manufacturerId, nonMatchData, mask).build();
-        assertTrue("partial setManufacturerData filter fails", filter.matches(mScanResult));
-    }
-
-    @SmallTest
-    public void testReadWriteParcel() {
-        ScanFilter filter = mFilterBuilder.build();
-        testReadWriteParcelForFilter(filter);
-
-        filter = mFilterBuilder.setDeviceName("Ped").build();
-        testReadWriteParcelForFilter(filter);
-
-        filter = mFilterBuilder.setDeviceAddress("11:22:33:44:55:66").build();
-        testReadWriteParcelForFilter(filter);
-
-        filter = mFilterBuilder.setServiceUuid(
-                ParcelUuid.fromString("0000110C-0000-1000-8000-00805F9B34FB")).build();
-        testReadWriteParcelForFilter(filter);
-
-        filter = mFilterBuilder.setServiceUuid(
-                ParcelUuid.fromString("0000110C-0000-1000-8000-00805F9B34FB"),
-                ParcelUuid.fromString("FFFFFFF0-FFFF-FFFF-FFFF-FFFFFFFFFFFF")).build();
-        testReadWriteParcelForFilter(filter);
-
-        byte[] serviceData = new byte[] {
-                0x50, 0x64 };
-
-        ParcelUuid serviceDataUuid = ParcelUuid.fromString("0000110B-0000-1000-8000-00805F9B34FB");
-        filter = mFilterBuilder.setServiceData(serviceDataUuid, serviceData).build();
-        testReadWriteParcelForFilter(filter);
-
-        filter = mFilterBuilder.setServiceData(serviceDataUuid, new byte[0]).build();
-        testReadWriteParcelForFilter(filter);
-
-        byte[] serviceDataMask = new byte[] {
-                (byte) 0xFF, (byte) 0xFF };
-        filter = mFilterBuilder.setServiceData(serviceDataUuid, serviceData, serviceDataMask)
-                .build();
-        testReadWriteParcelForFilter(filter);
-
-        byte[] manufacturerData = new byte[] {
-                0x02, 0x15 };
-        int manufacturerId = 0xE0;
-        filter = mFilterBuilder.setManufacturerData(manufacturerId, manufacturerData).build();
-        testReadWriteParcelForFilter(filter);
-
-        filter = mFilterBuilder.setServiceData(serviceDataUuid, new byte[0]).build();
-        testReadWriteParcelForFilter(filter);
-
-        byte[] manufacturerDataMask = new byte[] {
-                (byte) 0xFF, (byte) 0xFF
-        };
-        filter = mFilterBuilder.setManufacturerData(manufacturerId, manufacturerData,
-                manufacturerDataMask).build();
-        testReadWriteParcelForFilter(filter);
-    }
-
-    private void testReadWriteParcelForFilter(ScanFilter filter) {
-        Parcel parcel = Parcel.obtain();
-        filter.writeToParcel(parcel, 0);
-        parcel.setDataPosition(0);
-        ScanFilter filterFromParcel =
-                ScanFilter.CREATOR.createFromParcel(parcel);
-        assertEquals(filter, filterFromParcel);
-    }
-}
diff --git a/core/tests/bluetoothtests/src/android/bluetooth/le/ScanRecordTest.java b/core/tests/bluetoothtests/src/android/bluetooth/le/ScanRecordTest.java
deleted file mode 100644
index 4e817d4..0000000
--- a/core/tests/bluetoothtests/src/android/bluetooth/le/ScanRecordTest.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.le;
-
-import android.os.ParcelUuid;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import com.android.internal.util.HexDump;
-import com.android.modules.utils.BytesMatcher;
-
-import junit.framework.TestCase;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.function.Predicate;
-
-/**
- * Unit test cases for {@link ScanRecord}.
- * <p>
- * To run this test, use adb shell am instrument -e class 'android.bluetooth.ScanRecordTest' -w
- * 'com.android.bluetooth.tests/android.bluetooth.BluetoothTestRunner'
- */
-public class ScanRecordTest extends TestCase {
-    /**
-     * Example raw beacons captured from a Blue Charm BC011
-     */
-    private static final String RECORD_URL = "0201060303AAFE1716AAFE10EE01626C7565636861726D626561636F6E730009168020691E0EFE13551109426C7565436861726D5F313639363835000000";
-    private static final String RECORD_UUID = "0201060303AAFE1716AAFE00EE626C7565636861726D31000000000001000009168020691E0EFE13551109426C7565436861726D5F313639363835000000";
-    private static final String RECORD_TLM = "0201060303AAFE1116AAFE20000BF017000008874803FB93540916802069080EFE13551109426C7565436861726D5F313639363835000000000000000000";
-    private static final String RECORD_IBEACON = "0201061AFF4C000215426C7565436861726D426561636F6E730EFE1355C509168020691E0EFE13551109426C7565436861726D5F31363936383500000000";
-
-    @SmallTest
-    public void testMatchesAnyField_Eddystone_Parser() {
-        final List<String> found = new ArrayList<>();
-        final Predicate<byte[]> matcher = (v) -> {
-            found.add(HexDump.toHexString(v));
-            return false;
-        };
-        ScanRecord.parseFromBytes(HexDump.hexStringToByteArray(RECORD_URL))
-                .matchesAnyField(matcher);
-
-        assertEquals(Arrays.asList(
-                "020106",
-                "0303AAFE",
-                "1716AAFE10EE01626C7565636861726D626561636F6E7300",
-                "09168020691E0EFE1355",
-                "1109426C7565436861726D5F313639363835"), found);
-    }
-
-    @SmallTest
-    public void testMatchesAnyField_Eddystone() {
-        final BytesMatcher matcher = BytesMatcher.decode("⊆0016AAFE/00FFFFFF");
-        assertMatchesAnyField(RECORD_URL, matcher);
-        assertMatchesAnyField(RECORD_UUID, matcher);
-        assertMatchesAnyField(RECORD_TLM, matcher);
-        assertNotMatchesAnyField(RECORD_IBEACON, matcher);
-    }
-
-    @SmallTest
-    public void testMatchesAnyField_iBeacon_Parser() {
-        final List<String> found = new ArrayList<>();
-        final Predicate<byte[]> matcher = (v) -> {
-            found.add(HexDump.toHexString(v));
-            return false;
-        };
-        ScanRecord.parseFromBytes(HexDump.hexStringToByteArray(RECORD_IBEACON))
-                .matchesAnyField(matcher);
-
-        assertEquals(Arrays.asList(
-                "020106",
-                "1AFF4C000215426C7565436861726D426561636F6E730EFE1355C5",
-                "09168020691E0EFE1355",
-                "1109426C7565436861726D5F313639363835"), found);
-    }
-
-    @SmallTest
-    public void testMatchesAnyField_iBeacon() {
-        final BytesMatcher matcher = BytesMatcher.decode("⊆00FF4C0002/00FFFFFFFF");
-        assertNotMatchesAnyField(RECORD_URL, matcher);
-        assertNotMatchesAnyField(RECORD_UUID, matcher);
-        assertNotMatchesAnyField(RECORD_TLM, matcher);
-        assertMatchesAnyField(RECORD_IBEACON, matcher);
-    }
-
-    @SmallTest
-    public void testParser() {
-        byte[] scanRecord = new byte[] {
-                0x02, 0x01, 0x1a, // advertising flags
-                0x05, 0x02, 0x0b, 0x11, 0x0a, 0x11, // 16 bit service uuids
-                0x04, 0x09, 0x50, 0x65, 0x64, // name
-                0x02, 0x0A, (byte) 0xec, // tx power level
-                0x05, 0x16, 0x0b, 0x11, 0x50, 0x64, // service data
-                0x05, (byte) 0xff, (byte) 0xe0, 0x00, 0x02, 0x15, // manufacturer specific data
-                0x03, 0x50, 0x01, 0x02, // an unknown data type won't cause trouble
-        };
-        ScanRecord data = ScanRecord.parseFromBytes(scanRecord);
-        assertEquals(0x1a, data.getAdvertiseFlags());
-        ParcelUuid uuid1 = ParcelUuid.fromString("0000110A-0000-1000-8000-00805F9B34FB");
-        ParcelUuid uuid2 = ParcelUuid.fromString("0000110B-0000-1000-8000-00805F9B34FB");
-        assertTrue(data.getServiceUuids().contains(uuid1));
-        assertTrue(data.getServiceUuids().contains(uuid2));
-
-        assertEquals("Ped", data.getDeviceName());
-        assertEquals(-20, data.getTxPowerLevel());
-
-        assertTrue(data.getManufacturerSpecificData().get(0x00E0) != null);
-        assertArrayEquals(new byte[] {
-                0x02, 0x15 }, data.getManufacturerSpecificData().get(0x00E0));
-
-        assertTrue(data.getServiceData().containsKey(uuid2));
-        assertArrayEquals(new byte[] {
-                0x50, 0x64 }, data.getServiceData().get(uuid2));
-    }
-
-    // Assert two byte arrays are equal.
-    private static void assertArrayEquals(byte[] expected, byte[] actual) {
-        if (!Arrays.equals(expected, actual)) {
-            fail("expected:<" + Arrays.toString(expected) +
-                    "> but was:<" + Arrays.toString(actual) + ">");
-        }
-
-    }
-
-    private static void assertMatchesAnyField(String record, BytesMatcher matcher) {
-        assertTrue(ScanRecord.parseFromBytes(HexDump.hexStringToByteArray(record))
-                .matchesAnyField(matcher));
-    }
-
-    private static void assertNotMatchesAnyField(String record, BytesMatcher matcher) {
-        assertFalse(ScanRecord.parseFromBytes(HexDump.hexStringToByteArray(record))
-                .matchesAnyField(matcher));
-    }
-}
diff --git a/core/tests/bluetoothtests/src/android/bluetooth/le/ScanResultTest.java b/core/tests/bluetoothtests/src/android/bluetooth/le/ScanResultTest.java
deleted file mode 100644
index 01d5c59..0000000
--- a/core/tests/bluetoothtests/src/android/bluetooth/le/ScanResultTest.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.le;
-
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothDevice;
-import android.os.Parcel;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import junit.framework.TestCase;
-
-/**
- * Unit test cases for Bluetooth LE scans.
- * <p>
- * To run this test, use adb shell am instrument -e class 'android.bluetooth.ScanResultTest' -w
- * 'com.android.bluetooth.tests/android.bluetooth.BluetoothTestRunner'
- */
-public class ScanResultTest extends TestCase {
-
-    /**
-     * Test read and write parcel of ScanResult
-     */
-    @SmallTest
-    public void testScanResultParceling() {
-        BluetoothDevice device = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(
-                "01:02:03:04:05:06");
-        byte[] scanRecord = new byte[] {
-                1, 2, 3 };
-        int rssi = -10;
-        long timestampMicros = 10000L;
-
-        ScanResult result = new ScanResult(device, ScanRecord.parseFromBytes(scanRecord), rssi,
-                timestampMicros);
-        Parcel parcel = Parcel.obtain();
-        result.writeToParcel(parcel, 0);
-        // Need to reset parcel data position to the beginning.
-        parcel.setDataPosition(0);
-        ScanResult resultFromParcel = ScanResult.CREATOR.createFromParcel(parcel);
-        assertEquals(result, resultFromParcel);
-    }
-
-}
diff --git a/core/tests/bluetoothtests/src/android/bluetooth/le/ScanSettingsTest.java b/core/tests/bluetoothtests/src/android/bluetooth/le/ScanSettingsTest.java
deleted file mode 100644
index 7c42c3b..0000000
--- a/core/tests/bluetoothtests/src/android/bluetooth/le/ScanSettingsTest.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.le;
-
-import android.test.suitebuilder.annotation.SmallTest;
-
-import junit.framework.TestCase;
-
-/**
- * Test for Bluetooth LE {@link ScanSettings}.
- */
-public class ScanSettingsTest extends TestCase {
-
-    @SmallTest
-    public void testCallbackType() {
-        ScanSettings.Builder builder = new ScanSettings.Builder();
-        builder.setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES);
-        builder.setCallbackType(ScanSettings.CALLBACK_TYPE_FIRST_MATCH);
-        builder.setCallbackType(ScanSettings.CALLBACK_TYPE_MATCH_LOST);
-        builder.setCallbackType(
-                ScanSettings.CALLBACK_TYPE_FIRST_MATCH | ScanSettings.CALLBACK_TYPE_MATCH_LOST);
-        try {
-            builder.setCallbackType(
-                    ScanSettings.CALLBACK_TYPE_ALL_MATCHES | ScanSettings.CALLBACK_TYPE_MATCH_LOST);
-            fail("should have thrown IllegalArgumentException!");
-        } catch (IllegalArgumentException e) {
-            // nothing to do
-        }
-
-        try {
-            builder.setCallbackType(
-                    ScanSettings.CALLBACK_TYPE_ALL_MATCHES |
-                    ScanSettings.CALLBACK_TYPE_FIRST_MATCH);
-            fail("should have thrown IllegalArgumentException!");
-        } catch (IllegalArgumentException e) {
-            // nothing to do
-        }
-
-        try {
-            builder.setCallbackType(
-                    ScanSettings.CALLBACK_TYPE_ALL_MATCHES |
-                    ScanSettings.CALLBACK_TYPE_FIRST_MATCH |
-                    ScanSettings.CALLBACK_TYPE_MATCH_LOST);
-            fail("should have thrown IllegalArgumentException!");
-        } catch (IllegalArgumentException e) {
-            // nothing to do
-        }
-
-    }
-}
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsProviderTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsProviderTest.java
index 74b6dbe..93910b9 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsProviderTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsProviderTest.java
@@ -39,6 +39,8 @@
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
+import libcore.testing.io.TestIoUtils;
+
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -52,8 +54,11 @@
     private static final int APP_UID = Process.FIRST_APPLICATION_UID + 42;
     private static final long MINUTE_IN_MS = 60 * 1000;
 
+    private final File mHistoryDir =
+            TestIoUtils.createTemporaryDirectory(getClass().getSimpleName());
+
     @Rule
-    public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule(12345)
+    public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule(12345, mHistoryDir)
             .setAveragePower(PowerProfile.POWER_FLASHLIGHT, 360.0);
 
     @Test
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsRule.java b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsRule.java
index 083090c..2c6f5fa 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsRule.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsRule.java
@@ -40,6 +40,7 @@
 import org.junit.runners.model.Statement;
 import org.mockito.stubbing.Answer;
 
+import java.io.File;
 import java.util.Arrays;
 
 public class BatteryUsageStatsRule implements TestRule {
@@ -57,14 +58,18 @@
     private boolean mScreenOn;
 
     public BatteryUsageStatsRule() {
-        this(0);
+        this(0, null);
     }
 
     public BatteryUsageStatsRule(long currentTime) {
+        this(currentTime, null);
+    }
+
+    public BatteryUsageStatsRule(long currentTime, File historyDir) {
         Context context = InstrumentationRegistry.getContext();
         mPowerProfile = spy(new PowerProfile(context, true /* forTest */));
         mMockClocks.currentTime = currentTime;
-        mBatteryStats = new MockBatteryStatsImpl(mMockClocks);
+        mBatteryStats = new MockBatteryStatsImpl(mMockClocks, historyDir);
         mBatteryStats.setPowerProfile(mPowerProfile);
         mBatteryStats.onSystemReady();
     }
diff --git a/core/tests/coretests/src/com/android/internal/os/MockBatteryStatsImpl.java b/core/tests/coretests/src/com/android/internal/os/MockBatteryStatsImpl.java
index db0c934..11d20f2 100644
--- a/core/tests/coretests/src/com/android/internal/os/MockBatteryStatsImpl.java
+++ b/core/tests/coretests/src/com/android/internal/os/MockBatteryStatsImpl.java
@@ -29,6 +29,7 @@
 import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidUserSysTimeReader;
 import com.android.internal.power.MeasuredEnergyStats;
 
+import java.io.File;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Queue;
@@ -40,10 +41,16 @@
 public class MockBatteryStatsImpl extends BatteryStatsImpl {
     public BatteryStatsImpl.Clocks clocks;
     public boolean mForceOnBattery;
+    // The mNetworkStats will be used for both wifi and mobile categories
     private NetworkStats mNetworkStats;
 
     MockBatteryStatsImpl(Clocks clocks) {
-        super(clocks);
+        this(clocks, null);
+    }
+
+    MockBatteryStatsImpl(Clocks clocks, File historyDirectory) {
+        super(clocks, historyDirectory);
+
         this.clocks = mClocks;
         initTimersAndCounters();
 
@@ -107,11 +114,16 @@
     }
 
     @Override
-    protected NetworkStats readNetworkStatsLocked(@NonNull NetworkStatsManager networkStatsManager,
-            String[] ifaces) {
+    protected NetworkStats readMobileNetworkStatsLocked(
+            @NonNull NetworkStatsManager networkStatsManager) {
         return mNetworkStats;
     }
 
+    @Override
+    protected NetworkStats readWifiNetworkStatsLocked(
+            @NonNull NetworkStatsManager networkStatsManager) {
+        return mNetworkStats;
+    }
     public MockBatteryStatsImpl setPowerProfile(PowerProfile powerProfile) {
         mPowerProfile = powerProfile;
         return this;
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index fefcebe..fa6b086 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -390,6 +390,9 @@
         <permission name="android.permission.SET_WALLPAPER" />
         <permission name="android.permission.SET_WALLPAPER_COMPONENT" />
         <permission name="android.permission.REQUEST_NOTIFICATION_ASSISTANT_SERVICE" />
+        <!-- Permission required for CTS test - TrustTestCases -->
+        <permission name="android.permission.PROVIDE_TRUST_AGENT" />
+        <permission name="android.permission.ACCESS_KEYGUARD_SECURE_STORAGE" />
         <!-- Permissions required for Incremental CTS tests -->
         <permission name="com.android.permission.USE_INSTALLER_V2"/>
         <permission name="android.permission.LOADER_USAGE_STATS"/>
@@ -458,6 +461,7 @@
         <!-- Permission needed for CTS test - WifiManagerTest -->
         <permission name="android.permission.WIFI_ACCESS_COEX_UNSAFE_CHANNELS" />
         <permission name="android.permission.WIFI_UPDATE_COEX_UNSAFE_CHANNELS" />
+        <permission name="android.permission.OVERRIDE_WIFI_CONFIG" />
         <!-- Permission required for CTS test CarrierMessagingServiceWrapperTest -->
         <permission name="android.permission.BIND_CARRIER_SERVICES"/>
         <!-- Permission required for CTS test - MusicRecognitionManagerTest -->
diff --git a/identity/java/android/security/identity/CredentialDataRequest.java b/identity/java/android/security/identity/CredentialDataRequest.java
new file mode 100644
index 0000000..2a47a02
--- /dev/null
+++ b/identity/java/android/security/identity/CredentialDataRequest.java
@@ -0,0 +1,232 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.identity;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * An object representing a request for credential data.
+ */
+public class CredentialDataRequest {
+    CredentialDataRequest() {}
+
+    /**
+     * Gets the device-signed entries to request.
+     *
+     * @return the device-signed entries to request.
+     */
+    public @NonNull Map<String, Collection<String>> getDeviceSignedEntriesToRequest() {
+        return mDeviceSignedEntriesToRequest;
+    }
+
+    /**
+     * Gets the issuer-signed entries to request.
+     *
+     * @return the issuer-signed entries to request.
+     */
+    public @NonNull Map<String, Collection<String>> getIssuerSignedEntriesToRequest() {
+        return mIssuerSignedEntriesToRequest;
+    }
+
+    /**
+     * Gets whether to allow using an authentication key which use count has been exceeded.
+     *
+     * <p>By default this is set to true.
+     *
+     * @return whether to allow using an authentication key which use
+     *         count has been exceeded if no other key is available.
+     */
+    public boolean isAllowUsingExhaustedKeys() {
+        return mAllowUsingExhaustedKeys;
+    }
+
+    /**
+     * Gets whether to allow using an authentication key which is expired.
+     *
+     * <p>By default this is set to false.
+     *
+     * @return whether to allow using an authentication key which is
+     *         expired if no other key is available.
+     */
+    public boolean isAllowUsingExpiredKeys() {
+        return mAllowUsingExpiredKeys;
+    }
+
+    /**
+     * Gets whether to increment the use-count for the authentication key used.
+     *
+     * <p>By default this is set to true.
+     *
+     * @return whether to increment the use count of the authentication key used.
+     */
+    public boolean isIncrementUseCount() {
+        return mIncrementUseCount;
+    }
+
+    /**
+     * Gets the request message CBOR.
+     *
+     * <p>This data structure is described in the documentation for the
+     * {@link PresentationSession#getCredentialData(String, CredentialDataRequest)} method.
+     *
+     * @return the request message CBOR as described above.
+     */
+    public @Nullable byte[] getRequestMessage() {
+        return mRequestMessage;
+    }
+
+    /**
+     * Gets the reader signature.
+     *
+     * <p>This data structure is described in the documentation for the
+     * {@link PresentationSession#getCredentialData(String, CredentialDataRequest)} method.
+     *
+     * @return a {@code COSE_Sign1} structure as described above.
+     */
+    public @Nullable byte[] getReaderSignature() {
+        return mReaderSignature;
+    }
+
+    Map<String, Collection<String>> mDeviceSignedEntriesToRequest = new LinkedHashMap<>();
+    Map<String, Collection<String>> mIssuerSignedEntriesToRequest = new LinkedHashMap<>();
+    boolean mAllowUsingExhaustedKeys = true;
+    boolean mAllowUsingExpiredKeys = false;
+    boolean mIncrementUseCount = true;
+    byte[] mRequestMessage = null;
+    byte[] mReaderSignature = null;
+
+    /**
+     * A builder for {@link CredentialDataRequest}.
+     */
+    public static final class Builder {
+        private CredentialDataRequest mData;
+
+        /**
+         * Creates a new builder.
+         */
+        public Builder() {
+            mData = new CredentialDataRequest();
+        }
+
+        /**
+         * Sets the device-signed entries to request.
+         *
+         * @param entriesToRequest the device-signed entries to request.
+         */
+        public @NonNull Builder setDeviceSignedEntriesToRequest(
+                @NonNull Map<String, Collection<String>> entriesToRequest) {
+            mData.mDeviceSignedEntriesToRequest = entriesToRequest;
+            return this;
+        }
+
+        /**
+         * Sets the issuer-signed entries to request.
+         *
+         * @param entriesToRequest the issuer-signed entries to request.
+         * @return the builder.
+         */
+        public @NonNull Builder setIssuerSignedEntriesToRequest(
+                @NonNull Map<String, Collection<String>> entriesToRequest) {
+            mData.mIssuerSignedEntriesToRequest = entriesToRequest;
+            return this;
+        }
+
+        /**
+         * Sets whether to allow using an authentication key which use count has been exceeded.
+         *
+         * By default this is set to true.
+         *
+         * @param allowUsingExhaustedKeys whether to allow using an authentication key which use
+         *                                count has been exceeded if no other key is available.
+         * @return the builder.
+         */
+        public @NonNull Builder setAllowUsingExhaustedKeys(boolean allowUsingExhaustedKeys) {
+            mData.mAllowUsingExhaustedKeys = allowUsingExhaustedKeys;
+            return this;
+        }
+
+        /**
+         * Sets whether to allow using an authentication key which is expired.
+         *
+         * By default this is set to false.
+         *
+         * @param allowUsingExpiredKeys whether to allow using an authentication key which is
+         *                              expired if no other key is available.
+         * @return the builder.
+         */
+        public @NonNull Builder setAllowUsingExpiredKeys(boolean allowUsingExpiredKeys) {
+            mData.mAllowUsingExpiredKeys = allowUsingExpiredKeys;
+            return this;
+        }
+
+        /**
+         * Sets whether to increment the use-count for the authentication key used.
+         *
+         * By default this is set to true.
+         *
+         * @param incrementUseCount whether to increment the use count of the authentication
+         *                          key used.
+         * @return the builder.
+         */
+        public @NonNull Builder setIncrementUseCount(boolean incrementUseCount) {
+            mData.mIncrementUseCount = incrementUseCount;
+            return this;
+        }
+
+        /**
+         * Sets the request message CBOR.
+         *
+         * <p>This data structure is described in the documentation for the
+         * {@link PresentationSession#getCredentialData(String, CredentialDataRequest)} method.
+         *
+         * @param requestMessage the request message CBOR as described above.
+         * @return the builder.
+         */
+        public @NonNull Builder setRequestMessage(@NonNull byte[] requestMessage) {
+            mData.mRequestMessage = requestMessage;
+            return this;
+        }
+
+        /**
+         * Sets the reader signature.
+         *
+         * <p>This data structure is described in the documentation for the
+         * {@link PresentationSession#getCredentialData(String, CredentialDataRequest)} method.
+         *
+         * @param readerSignature a {@code COSE_Sign1} structure as described above.
+         * @return the builder.
+         */
+        public @NonNull Builder setReaderSignature(@NonNull byte[] readerSignature) {
+            mData.mReaderSignature = readerSignature;
+            return this;
+        }
+
+        /**
+         * Finishes building a {@link CredentialDataRequest}.
+         *
+         * @return the {@link CredentialDataRequest} object.
+         */
+        public @NonNull CredentialDataRequest build() {
+            return mData;
+        }
+    }
+}
diff --git a/identity/java/android/security/identity/CredentialDataResult.java b/identity/java/android/security/identity/CredentialDataResult.java
new file mode 100644
index 0000000..beb03af
--- /dev/null
+++ b/identity/java/android/security/identity/CredentialDataResult.java
@@ -0,0 +1,232 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.identity;
+
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+import java.lang.annotation.Retention;
+import java.util.Collection;
+
+
+/**
+ * An object that contains the result of retrieving data from a credential. This is used to return
+ * data requested in a {@link PresentationSession}.
+ */
+public abstract class CredentialDataResult {
+    /**
+     * @hide
+     */
+    protected CredentialDataResult() {}
+
+    /**
+     * Returns a CBOR structure containing the retrieved device-signed data.
+     *
+     * <p>This structure - along with the session transcript - may be cryptographically
+     * authenticated to prove to the reader that the data is from a trusted credential and
+     * {@link #getDeviceMac()} can be used to get a MAC.
+     *
+     * <p>The CBOR structure which is cryptographically authenticated is the
+     * {@code DeviceAuthenticationBytes} structure according to the following
+     * <a href="https://tools.ietf.org/html/rfc8610">CDDL</a> schema:
+     *
+     * <pre>
+     *   DeviceAuthentication = [
+     *     "DeviceAuthentication",
+     *     SessionTranscript,
+     *     DocType,
+     *     DeviceNameSpacesBytes
+     *   ]
+     *
+     *   DocType = tstr
+     *   SessionTranscript = any
+     *   DeviceNameSpacesBytes = #6.24(bstr .cbor DeviceNameSpaces)
+     *   DeviceAuthenticationBytes = #6.24(bstr .cbor DeviceAuthentication)
+     * </pre>
+     *
+     * <p>where
+     *
+     * <pre>
+     *   DeviceNameSpaces = {
+     *     * NameSpace => DeviceSignedItems
+     *   }
+     *
+     *   DeviceSignedItems = {
+     *     + DataItemName => DataItemValue
+     *   }
+     *
+     *   NameSpace = tstr
+     *   DataItemName = tstr
+     *   DataItemValue = any
+     * </pre>
+     *
+     * <p>The returned data is the binary encoding of the {@code DeviceNameSpaces} structure
+     * as defined above.
+     *
+     * @return The bytes of the {@code DeviceNameSpaces} CBOR structure.
+     */
+    public abstract @NonNull byte[] getDeviceNameSpaces();
+
+    /**
+     * Returns a message authentication code over the {@code DeviceAuthenticationBytes} CBOR
+     * specified in {@link #getDeviceNameSpaces()}, to prove to the reader that the data
+     * is from a trusted credential.
+     *
+     * <p>The MAC proves to the reader that the data is from a trusted credential. This code is
+     * produced by using the key agreement and key derivation function from the ciphersuite
+     * with the authentication private key and the reader ephemeral public key to compute a
+     * shared message authentication code (MAC) key, then using the MAC function from the
+     * ciphersuite to compute a MAC of the authenticated data. See section 9.2.3.5 of
+     * ISO/IEC 18013-5 for details of this operation.
+     *
+     * <p>If the session transcript or reader ephemeral key wasn't set on the {@link
+     * PresentationSession} used to obtain this data no message authencation code will be produced
+     * and this method will return {@code null}.
+     *
+     * @return A COSE_Mac0 structure with the message authentication code as described above
+     *         or {@code null} if the conditions specified above are not met.
+     */
+    public abstract @Nullable byte[] getDeviceMac();
+
+    /**
+     * Returns the static authentication data associated with the dynamic authentication
+     * key used to MAC the data returned by {@link #getDeviceNameSpaces()}.
+     *
+     * @return The static authentication data associated with dynamic authentication key used to
+     * MAC the data.
+     */
+    public abstract @NonNull byte[] getStaticAuthenticationData();
+
+    /**
+     * Gets the device-signed entries that was returned.
+     *
+     * @return an object to examine the entries returned.
+     */
+    public abstract @NonNull Entries getDeviceSignedEntries();
+
+    /**
+     * Gets the issuer-signed entries that was returned.
+     *
+     * @return an object to examine the entries returned.
+     */
+    public abstract @NonNull Entries getIssuerSignedEntries();
+
+    /**
+     * A class for representing data elements returned.
+     */
+    public interface Entries {
+        /** Value was successfully retrieved. */
+        int STATUS_OK = 0;
+
+        /** The entry does not exist. */
+        int STATUS_NO_SUCH_ENTRY = 1;
+
+        /** The entry was not requested. */
+        int STATUS_NOT_REQUESTED = 2;
+
+        /** The entry wasn't in the request message. */
+        int STATUS_NOT_IN_REQUEST_MESSAGE = 3;
+
+        /** The entry was not retrieved because user authentication failed. */
+        int STATUS_USER_AUTHENTICATION_FAILED = 4;
+
+        /** The entry was not retrieved because reader authentication failed. */
+        int STATUS_READER_AUTHENTICATION_FAILED = 5;
+
+        /**
+         * The entry was not retrieved because it was configured without any access
+         * control profile.
+         */
+        int STATUS_NO_ACCESS_CONTROL_PROFILES = 6;
+
+        /**
+         * Gets the names of namespaces with retrieved entries.
+         *
+         * @return collection of name of namespaces containing retrieved entries. May be empty if no
+         *     data was retrieved.
+         */
+        @NonNull Collection<String> getNamespaces();
+
+        /**
+         * Get the names of all requested entries in a name space.
+         *
+         * <p>This includes the name of entries that wasn't successfully retrieved.
+         *
+         * @param namespaceName the namespace name to get entries for.
+         * @return A collection of names for the given namespace or the empty collection if no
+         *   entries was returned for the given name space.
+         */
+        @NonNull Collection<String> getEntryNames(@NonNull String namespaceName);
+
+        /**
+         * Get the names of all entries that was successfully retrieved from a name space.
+         *
+         * <p>This only return entries for which {@link #getStatus(String, String)} will return
+         * {@link #STATUS_OK}.
+         *
+         * @param namespaceName the namespace name to get entries for.
+         * @return The entries in the given namespace that were successfully rerieved or the
+         *   empty collection if no entries was returned for the given name space.
+         */
+        @NonNull Collection<String> getRetrievedEntryNames(@NonNull String namespaceName);
+
+        /**
+         * Gets the status of an entry.
+         *
+         * <p>This returns {@link #STATUS_OK} if the value was retrieved, {@link
+         * #STATUS_NO_SUCH_ENTRY} if the given entry wasn't retrieved, {@link
+         * #STATUS_NOT_REQUESTED} if it wasn't requested, {@link #STATUS_NOT_IN_REQUEST_MESSAGE} if
+         * the request message was set but the entry wasn't present in the request message, {@link
+         * #STATUS_USER_AUTHENTICATION_FAILED} if the value wasn't retrieved because the necessary
+         * user authentication wasn't performed, {@link #STATUS_READER_AUTHENTICATION_FAILED} if
+         * the supplied reader certificate chain didn't match the set of certificates the entry was
+         * provisioned with, or {@link #STATUS_NO_ACCESS_CONTROL_PROFILES} if the entry was
+         * configured without any access control profiles.
+         *
+         * @param namespaceName the namespace name of the entry.
+         * @param name the name of the entry to get the value for.
+         * @return the status indicating whether the value was retrieved and if not, why.
+         */
+        @Status int getStatus(@NonNull String namespaceName, @NonNull String name);
+
+        /**
+         * Gets the raw CBOR data for the value of an entry.
+         *
+         * <p>This should only be called on an entry for which the {@link #getStatus(String,
+         * String)} method returns {@link #STATUS_OK}.
+         *
+         * @param namespaceName the namespace name of the entry.
+         * @param name the name of the entry to get the value for.
+         * @return the raw CBOR data or {@code null} if no entry with the given name exists.
+         */
+        @Nullable byte[] getEntry(@NonNull String namespaceName, @NonNull String name);
+
+        /**
+         * The type of the entry status.
+         * @hide
+         */
+        @Retention(SOURCE)
+        @IntDef({STATUS_OK, STATUS_NO_SUCH_ENTRY, STATUS_NOT_REQUESTED,
+                    STATUS_NOT_IN_REQUEST_MESSAGE, STATUS_USER_AUTHENTICATION_FAILED,
+                    STATUS_READER_AUTHENTICATION_FAILED, STATUS_NO_ACCESS_CONTROL_PROFILES})
+                    @interface Status {}
+    }
+
+}
diff --git a/identity/java/android/security/identity/CredstoreCredentialDataResult.java b/identity/java/android/security/identity/CredstoreCredentialDataResult.java
new file mode 100644
index 0000000..7afe3d4
--- /dev/null
+++ b/identity/java/android/security/identity/CredstoreCredentialDataResult.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.identity;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+import java.util.Collection;
+import java.util.LinkedList;
+
+class CredstoreCredentialDataResult extends CredentialDataResult {
+
+    ResultData mDeviceSignedResult;
+    ResultData mIssuerSignedResult;
+    CredstoreEntries mDeviceSignedEntries;
+    CredstoreEntries mIssuerSignedEntries;
+
+    CredstoreCredentialDataResult(ResultData deviceSignedResult, ResultData issuerSignedResult) {
+        mDeviceSignedResult = deviceSignedResult;
+        mIssuerSignedResult = issuerSignedResult;
+        mDeviceSignedEntries = new CredstoreEntries(deviceSignedResult);
+        mIssuerSignedEntries = new CredstoreEntries(issuerSignedResult);
+    }
+
+    @Override
+    public @NonNull byte[] getDeviceNameSpaces() {
+        return mDeviceSignedResult.getAuthenticatedData();
+    }
+
+    @Override
+    public @Nullable byte[] getDeviceMac() {
+        return mDeviceSignedResult.getMessageAuthenticationCode();
+    }
+
+    @Override
+    public @NonNull byte[] getStaticAuthenticationData() {
+        return mDeviceSignedResult.getStaticAuthenticationData();
+    }
+
+    @Override
+    public @NonNull CredentialDataResult.Entries getDeviceSignedEntries() {
+        return mDeviceSignedEntries;
+    }
+
+    @Override
+    public @NonNull CredentialDataResult.Entries getIssuerSignedEntries() {
+        return mIssuerSignedEntries;
+    }
+
+    static class CredstoreEntries implements CredentialDataResult.Entries {
+        ResultData mResultData;
+
+        CredstoreEntries(ResultData resultData) {
+            mResultData = resultData;
+        }
+
+        @Override
+        public @NonNull Collection<String> getNamespaces() {
+            return mResultData.getNamespaces();
+        }
+
+        @Override
+        public @NonNull Collection<String> getEntryNames(@NonNull String namespaceName) {
+            Collection<String> ret = mResultData.getEntryNames(namespaceName);
+            if (ret == null) {
+                ret = new LinkedList<String>();
+            }
+            return ret;
+        }
+
+        @Override
+        public @NonNull Collection<String> getRetrievedEntryNames(@NonNull String namespaceName) {
+            Collection<String> ret = mResultData.getRetrievedEntryNames(namespaceName);
+            if (ret == null) {
+                ret = new LinkedList<String>();
+            }
+            return ret;
+        }
+
+        @Override
+        @Status
+        public int getStatus(@NonNull String namespaceName, @NonNull String name) {
+            return mResultData.getStatus(namespaceName, name);
+        }
+
+        @Override
+        public @Nullable byte[] getEntry(@NonNull String namespaceName, @NonNull String name) {
+            return mResultData.getEntry(namespaceName, name);
+        }
+    }
+
+}
diff --git a/identity/java/android/security/identity/CredstoreIdentityCredential.java b/identity/java/android/security/identity/CredstoreIdentityCredential.java
index 6398cee..8e01105 100644
--- a/identity/java/android/security/identity/CredstoreIdentityCredential.java
+++ b/identity/java/android/security/identity/CredstoreIdentityCredential.java
@@ -58,14 +58,17 @@
     private @IdentityCredentialStore.Ciphersuite int mCipherSuite;
     private Context mContext;
     private ICredential mBinder;
+    private CredstorePresentationSession mSession;
 
     CredstoreIdentityCredential(Context context, String credentialName,
             @IdentityCredentialStore.Ciphersuite int cipherSuite,
-            ICredential binder) {
+            ICredential binder,
+            @Nullable CredstorePresentationSession session) {
         mContext = context;
         mCredentialName = credentialName;
         mCipherSuite = cipherSuite;
         mBinder = binder;
+        mSession = session;
     }
 
     private KeyPair mEphemeralKeyPair = null;
@@ -239,6 +242,7 @@
 
     private boolean mAllowUsingExhaustedKeys = true;
     private boolean mAllowUsingExpiredKeys = false;
+    private boolean mIncrementKeyUsageCount = true;
 
     @Override
     public void setAllowUsingExhaustedKeys(boolean allowUsingExhaustedKeys) {
@@ -250,6 +254,11 @@
         mAllowUsingExpiredKeys = allowUsingExpiredKeys;
     }
 
+    @Override
+    public void setIncrementKeyUsageCount(boolean incrementKeyUsageCount) {
+        mIncrementKeyUsageCount = incrementKeyUsageCount;
+    }
+
     private boolean mOperationHandleSet = false;
     private long mOperationHandle = 0;
 
@@ -264,7 +273,8 @@
         if (!mOperationHandleSet) {
             try {
                 mOperationHandle = mBinder.selectAuthKey(mAllowUsingExhaustedKeys,
-                        mAllowUsingExpiredKeys);
+                                                         mAllowUsingExpiredKeys,
+                                                         mIncrementKeyUsageCount);
                 mOperationHandleSet = true;
             } catch (android.os.RemoteException e) {
                 throw new RuntimeException("Unexpected RemoteException ", e);
@@ -315,7 +325,8 @@
                 sessionTranscript != null ? sessionTranscript : new byte[0],
                 readerSignature != null ? readerSignature : new byte[0],
                 mAllowUsingExhaustedKeys,
-                mAllowUsingExpiredKeys);
+                mAllowUsingExpiredKeys,
+                mIncrementKeyUsageCount);
         } catch (android.os.RemoteException e) {
             throw new RuntimeException("Unexpected RemoteException ", e);
         } catch (android.os.ServiceSpecificException e) {
diff --git a/identity/java/android/security/identity/CredstoreIdentityCredentialStore.java b/identity/java/android/security/identity/CredstoreIdentityCredentialStore.java
index d8d4742..fb0880c 100644
--- a/identity/java/android/security/identity/CredstoreIdentityCredentialStore.java
+++ b/identity/java/android/security/identity/CredstoreIdentityCredentialStore.java
@@ -126,7 +126,8 @@
             ICredential credstoreCredential;
             credstoreCredential = mStore.getCredentialByName(credentialName, cipherSuite);
             return new CredstoreIdentityCredential(mContext, credentialName, cipherSuite,
-                    credstoreCredential);
+                    credstoreCredential,
+                    null);
         } catch (android.os.RemoteException e) {
             throw new RuntimeException("Unexpected RemoteException ", e);
         } catch (android.os.ServiceSpecificException e) {
@@ -162,4 +163,23 @@
                     + e.errorCode, e);
         }
     }
+
+    @Override
+    public @NonNull PresentationSession createPresentationSession(@Ciphersuite int cipherSuite)
+            throws CipherSuiteNotSupportedException {
+        try {
+            ISession credstoreSession = mStore.createPresentationSession(cipherSuite);
+            return new CredstorePresentationSession(mContext, cipherSuite, this, credstoreSession);
+        } catch (android.os.RemoteException e) {
+            throw new RuntimeException("Unexpected RemoteException ", e);
+        } catch (android.os.ServiceSpecificException e) {
+            if (e.errorCode == ICredentialStore.ERROR_CIPHER_SUITE_NOT_SUPPORTED) {
+                throw new CipherSuiteNotSupportedException(e.getMessage(), e);
+            } else {
+                throw new RuntimeException("Unexpected ServiceSpecificException with code "
+                        + e.errorCode, e);
+            }
+        }
+    }
+
 }
diff --git a/identity/java/android/security/identity/CredstorePresentationSession.java b/identity/java/android/security/identity/CredstorePresentationSession.java
new file mode 100644
index 0000000..e3c6689
--- /dev/null
+++ b/identity/java/android/security/identity/CredstorePresentationSession.java
@@ -0,0 +1,214 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.identity;
+
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.security.InvalidKeyException;
+import java.security.KeyPair;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+class CredstorePresentationSession extends PresentationSession {
+    private static final String TAG = "CredstorePresentationSession";
+
+    private @IdentityCredentialStore.Ciphersuite int mCipherSuite;
+    private Context mContext;
+    private CredstoreIdentityCredentialStore mStore;
+    private ISession mBinder;
+    private Map<String, CredstoreIdentityCredential> mCredentialCache = new LinkedHashMap<>();
+    private KeyPair mEphemeralKeyPair = null;
+    private byte[] mSessionTranscript = null;
+    private boolean mOperationHandleSet = false;
+    private long mOperationHandle = 0;
+
+    CredstorePresentationSession(Context context,
+            @IdentityCredentialStore.Ciphersuite int cipherSuite,
+            CredstoreIdentityCredentialStore store,
+            ISession binder) {
+        mContext = context;
+        mCipherSuite = cipherSuite;
+        mStore = store;
+        mBinder = binder;
+    }
+
+    private void ensureEphemeralKeyPair() {
+        if (mEphemeralKeyPair != null) {
+            return;
+        }
+        try {
+            // This PKCS#12 blob is generated in credstore, using BoringSSL.
+            //
+            // The main reason for this convoluted approach and not just sending the decomposed
+            // key-pair is that this would require directly using (device-side) BouncyCastle which
+            // is tricky due to various API hiding efforts. So instead we have credstore generate
+            // this PKCS#12 blob. The blob is encrypted with no password (sadly, also, BoringSSL
+            // doesn't support not using encryption when building a PKCS#12 blob).
+            //
+            byte[] pkcs12 = mBinder.getEphemeralKeyPair();
+            String alias = "ephemeralKey";
+            char[] password = {};
+
+            KeyStore ks = KeyStore.getInstance("PKCS12");
+            ByteArrayInputStream bais = new ByteArrayInputStream(pkcs12);
+            ks.load(bais, password);
+            PrivateKey privKey = (PrivateKey) ks.getKey(alias, password);
+
+            Certificate cert = ks.getCertificate(alias);
+            PublicKey pubKey = cert.getPublicKey();
+
+            mEphemeralKeyPair = new KeyPair(pubKey, privKey);
+        } catch (android.os.ServiceSpecificException e) {
+            throw new RuntimeException("Unexpected ServiceSpecificException with code "
+                    + e.errorCode, e);
+        } catch (android.os.RemoteException
+                | KeyStoreException
+                | CertificateException
+                | UnrecoverableKeyException
+                | NoSuchAlgorithmException
+                | IOException e) {
+            throw new RuntimeException("Unexpected exception ", e);
+        }
+    }
+
+    @Override
+    public @NonNull KeyPair getEphemeralKeyPair() {
+        ensureEphemeralKeyPair();
+        return mEphemeralKeyPair;
+    }
+
+    @Override
+    public void setReaderEphemeralPublicKey(@NonNull PublicKey readerEphemeralPublicKey)
+            throws InvalidKeyException {
+        try {
+            byte[] uncompressedForm =
+                    Util.publicKeyEncodeUncompressedForm(readerEphemeralPublicKey);
+            mBinder.setReaderEphemeralPublicKey(uncompressedForm);
+        } catch (android.os.RemoteException e) {
+            throw new RuntimeException("Unexpected RemoteException ", e);
+        } catch (android.os.ServiceSpecificException e) {
+            throw new RuntimeException("Unexpected ServiceSpecificException with code "
+                    + e.errorCode, e);
+        }
+    }
+
+    @Override
+    public void setSessionTranscript(@NonNull byte[] sessionTranscript) {
+        try {
+            mBinder.setSessionTranscript(sessionTranscript);
+            mSessionTranscript = sessionTranscript;
+        } catch (android.os.RemoteException e) {
+            throw new RuntimeException("Unexpected RemoteException ", e);
+        } catch (android.os.ServiceSpecificException e) {
+            throw new RuntimeException("Unexpected ServiceSpecificException with code "
+                    + e.errorCode, e);
+        }
+    }
+
+    @Override
+    public @Nullable CredentialDataResult getCredentialData(@NonNull String credentialName,
+                                                            @NonNull CredentialDataRequest request)
+            throws NoAuthenticationKeyAvailableException, InvalidReaderSignatureException,
+            InvalidRequestMessageException, EphemeralPublicKeyNotFoundException {
+        try {
+            // Cache the IdentityCredential to satisfy the property that AuthKey usage counts are
+            // incremented on only the _first_ getCredentialData() call.
+            //
+            CredstoreIdentityCredential credential = mCredentialCache.get(credentialName);
+            if (credential == null) {
+                ICredential credstoreCredential =
+                    mBinder.getCredentialForPresentation(credentialName);
+                credential = new CredstoreIdentityCredential(mContext, credentialName,
+                                                             mCipherSuite, credstoreCredential,
+                                                             this);
+                mCredentialCache.put(credentialName, credential);
+
+                credential.setAllowUsingExhaustedKeys(request.isAllowUsingExhaustedKeys());
+                credential.setAllowUsingExpiredKeys(request.isAllowUsingExpiredKeys());
+                credential.setIncrementKeyUsageCount(request.isIncrementUseCount());
+            }
+
+            ResultData deviceSignedResult = credential.getEntries(
+                    request.getRequestMessage(),
+                    request.getDeviceSignedEntriesToRequest(),
+                    mSessionTranscript,
+                    request.getReaderSignature());
+
+            // By design this second getEntries() call consumes the same auth-key.
+
+            ResultData issuerSignedResult = credential.getEntries(
+                    request.getRequestMessage(),
+                    request.getIssuerSignedEntriesToRequest(),
+                    mSessionTranscript,
+                    request.getReaderSignature());
+
+            return new CredstoreCredentialDataResult(deviceSignedResult, issuerSignedResult);
+
+        } catch (SessionTranscriptMismatchException e) {
+            throw new RuntimeException("Unexpected ", e);
+        } catch (android.os.RemoteException e) {
+            throw new RuntimeException("Unexpected RemoteException ", e);
+        } catch (android.os.ServiceSpecificException e) {
+            if (e.errorCode == ICredentialStore.ERROR_NO_SUCH_CREDENTIAL) {
+                return null;
+            } else {
+                throw new RuntimeException("Unexpected ServiceSpecificException with code "
+                        + e.errorCode, e);
+            }
+        }
+    }
+
+    /**
+     * Called by android.hardware.biometrics.CryptoObject#getOpId() to get an
+     * operation handle.
+     *
+     * @hide
+     */
+    @Override
+    public long getCredstoreOperationHandle() {
+        if (!mOperationHandleSet) {
+            try {
+                mOperationHandle = mBinder.getAuthChallenge();
+                mOperationHandleSet = true;
+            } catch (android.os.RemoteException e) {
+                throw new RuntimeException("Unexpected RemoteException ", e);
+            } catch (android.os.ServiceSpecificException e) {
+                if (e.errorCode == ICredentialStore.ERROR_NO_AUTHENTICATION_KEY_AVAILABLE) {
+                    // The NoAuthenticationKeyAvailableException will be thrown when
+                    // the caller proceeds to call getEntries().
+                }
+                throw new RuntimeException("Unexpected ServiceSpecificException with code "
+                        + e.errorCode, e);
+            }
+        }
+        return mOperationHandle;
+    }
+
+}
diff --git a/identity/java/android/security/identity/IdentityCredential.java b/identity/java/android/security/identity/IdentityCredential.java
index 1e68585..cdf746f 100644
--- a/identity/java/android/security/identity/IdentityCredential.java
+++ b/identity/java/android/security/identity/IdentityCredential.java
@@ -48,7 +48,9 @@
      * encryption".
      *
      * @return ephemeral key pair to use to establish a secure channel with a reader.
+     * @deprecated Use {@link PresentationSession} instead.
      */
+    @Deprecated
     public @NonNull abstract KeyPair createEphemeralKeyPair();
 
     /**
@@ -58,7 +60,9 @@
      * @param readerEphemeralPublicKey The ephemeral public key provided by the reader to
      *                                 establish a secure session.
      * @throws InvalidKeyException if the given key is invalid.
+     * @deprecated Use {@link PresentationSession} instead.
      */
+    @Deprecated
     public abstract void setReaderEphemeralPublicKey(@NonNull PublicKey readerEphemeralPublicKey)
             throws InvalidKeyException;
 
@@ -72,7 +76,10 @@
      *
      * @param messagePlaintext unencrypted message to encrypt.
      * @return encrypted message.
+     * @deprecated Applications should use {@link PresentationSession} and
+     *             implement encryption/decryption themselves.
      */
+    @Deprecated
     public @NonNull abstract byte[] encryptMessageToReader(@NonNull byte[] messagePlaintext);
 
     /**
@@ -86,7 +93,10 @@
      * @param messageCiphertext encrypted message to decrypt.
      * @return decrypted message.
      * @throws MessageDecryptionException if the ciphertext couldn't be decrypted.
+     * @deprecated Applications should use {@link PresentationSession} and
+     *             implement encryption/decryption themselves.
      */
+    @Deprecated
     public @NonNull abstract byte[] decryptMessageFromReader(@NonNull byte[] messageCiphertext)
             throws MessageDecryptionException;
 
@@ -111,7 +121,9 @@
      *
      * @param allowUsingExhaustedKeys whether to allow using an authentication key which use count
      *                                has been exceeded if no other key is available.
+     * @deprecated Use {@link PresentationSession} instead.
      */
+    @Deprecated
     public abstract void setAllowUsingExhaustedKeys(boolean allowUsingExhaustedKeys);
 
     /**
@@ -128,12 +140,36 @@
      *
      * @param allowUsingExpiredKeys whether to allow using an authentication key which use count
      *                              has been exceeded if no other key is available.
+     * @deprecated Use {@link PresentationSession} instead.
      */
+    @Deprecated
     public void setAllowUsingExpiredKeys(boolean allowUsingExpiredKeys) {
         throw new UnsupportedOperationException();
     }
 
     /**
+     * @hide
+     *
+     * Sets whether the usage count of an authentication key should be increased. This must be
+     * called prior to calling
+     * {@link #getEntries(byte[], Map, byte[], byte[])} or using a
+     * {@link android.hardware.biometrics.BiometricPrompt.CryptoObject} which references this object.
+     *
+     * <p>By default this is set to true.
+     *
+     * <p>This is only implemented in feature version 202201 or later. If not implemented, the call
+     * fails with {@link UnsupportedOperationException}. See
+     * {@link android.content.pm.PackageManager#FEATURE_IDENTITY_CREDENTIAL_HARDWARE} for known
+     * feature versions.
+     *
+     * @param incrementKeyUsageCount whether the usage count of the key should be increased.
+     * @deprecated Use {@link PresentationSession} instead.
+     */
+    public void setIncrementKeyUsageCount(boolean incrementKeyUsageCount) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
      * Called by android.hardware.biometrics.CryptoObject#getOpId() to get an
      * operation handle.
      *
@@ -149,15 +185,19 @@
      * by using the {@link ResultData#getStatus(String, String)} method on each of the requested
      * entries.
      *
-     * <p>It is the responsibility of the calling application to know if authentication is needed
-     * and use e.g. {@link android.hardware.biometrics.BiometricPrompt} to make the user
-     * authenticate using a {@link android.hardware.biometrics.BiometricPrompt.CryptoObject} which
-     * references this object. If needed, this must be done before calling
-     * {@link #getEntries(byte[], Map, byte[], byte[])}.
-     *
      * <p>It is permissible to call this method multiple times using the same instance but if this
      * is done, the {@code sessionTranscript} parameter must be identical for each call. If this is
      * not the case, the {@link SessionTranscriptMismatchException} exception is thrown.
+     * Additionally, if this is done the same auth-key will be used.
+     *
+     * <p>The application should not make any assumptions on whether user authentication is needed.
+     * Instead, the application should request the data elements values first and then examine
+     * the returned {@link ResultData}. If {@link ResultData#STATUS_USER_AUTHENTICATION_FAILED}
+     * is returned the application should get a
+     * {@link android.hardware.biometrics.BiometricPrompt.CryptoObject} which references this
+     * object and use it with a {@link android.hardware.biometrics.BiometricPrompt}. Upon successful
+     * authentication the application may call {@link #getEntries(byte[], Map, byte[], byte[])}
+     * again.
      *
      * <p>If not {@code null} the {@code requestMessage} parameter must contain data for the request
      * from the verifier. The content can be defined in the way appropriate for the credential, but
@@ -269,7 +309,9 @@
      * @throws InvalidRequestMessageException         if the requestMessage is malformed.
      * @throws EphemeralPublicKeyNotFoundException    if the ephemeral public key was not found in
      *                                                the session transcript.
+     * @deprecated Use {@link PresentationSession} instead.
      */
+    @Deprecated
     public abstract @NonNull ResultData getEntries(
             @Nullable byte[] requestMessage,
             @NonNull Map<String, Collection<String>> entriesToRequest,
diff --git a/identity/java/android/security/identity/IdentityCredentialStore.java b/identity/java/android/security/identity/IdentityCredentialStore.java
index 6ccd0e8..dbb8aaa 100644
--- a/identity/java/android/security/identity/IdentityCredentialStore.java
+++ b/identity/java/android/security/identity/IdentityCredentialStore.java
@@ -209,6 +209,25 @@
     @Deprecated
     public abstract @Nullable byte[] deleteCredentialByName(@NonNull String credentialName);
 
+    /**
+     * Creates a new presentation session.
+     *
+     * <p>This method gets an object to be used for interaction with a remote verifier for
+     * presentation of one or more credentials.
+     *
+     * <p>This is only implemented in feature version 202201 or later. If not implemented, the call
+     * fails with {@link UnsupportedOperationException}. See
+     * {@link android.content.pm.PackageManager#FEATURE_IDENTITY_CREDENTIAL_HARDWARE} for known
+     * feature versions.
+     *
+     * @param cipherSuite    the cipher suite to use for communicating with the verifier.
+     * @return The presentation session.
+     */
+    public @NonNull PresentationSession createPresentationSession(@Ciphersuite int cipherSuite)
+            throws CipherSuiteNotSupportedException {
+        throw new UnsupportedOperationException();
+    }
+
     /** @hide */
     @IntDef(value = {CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256})
     @Retention(RetentionPolicy.SOURCE)
diff --git a/identity/java/android/security/identity/PresentationSession.java b/identity/java/android/security/identity/PresentationSession.java
new file mode 100644
index 0000000..afaafce
--- /dev/null
+++ b/identity/java/android/security/identity/PresentationSession.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.identity;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+import java.security.InvalidKeyException;
+import java.security.KeyPair;
+import java.security.PublicKey;
+
+/**
+ * Class for presenting multiple documents to a remote verifier.
+ *
+ * Use {@link IdentityCredentialStore#createPresentationSession(int)} to create a {@link
+ * PresentationSession} instance.
+ */
+public abstract class PresentationSession {
+    /**
+     * @hide
+     */
+    protected PresentationSession() {}
+
+    /**
+     * Gets the ephemeral key pair to use to establish a secure channel with the verifier.
+     *
+     * <p>Applications should use this key-pair for the communications channel with the verifier
+     * using a protocol / cipher-suite appropriate for the application. One example of such a
+     * protocol is the one used for Mobile Driving Licenses, see ISO 18013-5.
+     *
+     * <p>The ephemeral key pair is tied to the {@link PresentationSession} instance so subsequent
+     * calls to this method will return the same key-pair.
+     *
+     * @return ephemeral key pair to use to establish a secure channel with a reader.
+     */
+    public @NonNull abstract KeyPair getEphemeralKeyPair();
+
+    /**
+     * Set the ephemeral public key provided by the verifier.
+     *
+     * <p>If called, this must be called before any calls to
+     * {@link #getCredentialData(String, CredentialDataRequest)}.
+     *
+     * <p>This method can only be called once per {@link PresentationSession} instance.
+     *
+     * @param readerEphemeralPublicKey The ephemeral public key provided by the reader to
+     *                                 establish a secure session.
+     * @throws InvalidKeyException if the given key is invalid.
+     */
+    public abstract void setReaderEphemeralPublicKey(@NonNull PublicKey readerEphemeralPublicKey)
+            throws InvalidKeyException;
+
+    /**
+     * Set the session transcript.
+     *
+     * <p>If called, this must be called before any calls to
+     * {@link #getCredentialData(String, CredentialDataRequest)}.
+     *
+     * <p>The X and Y coordinates of the public part of the key-pair returned by {@link
+     * #getEphemeralKeyPair()} must appear somewhere in the bytes of the passed in CBOR.  Each of
+     * these coordinates must appear encoded with the most significant bits first and use the exact
+     * amount of bits indicated by the key size of the ephemeral keys. For example, if the
+     * ephemeral key is using the P-256 curve then the 32 bytes for the X coordinate encoded with
+     * the most significant bits first must appear somewhere and ditto for the 32 bytes for the Y
+     * coordinate.
+     *
+     * <p>This method can only be called once per {@link PresentationSession} instance.
+     *
+     * @param sessionTranscript the session transcript.
+     */
+    public abstract void setSessionTranscript(@NonNull byte[] sessionTranscript);
+
+    /**
+     * Retrieves data from a named credential in the current presentation session.
+     *
+     * <p>If an access control check fails for one of the requested entries or if the entry
+     * doesn't exist, the entry is simply not returned. The application can detect this
+     * by using the {@link CredentialDataResult.Entries#getStatus(String, String)} method on
+     * each of the requested entries.
+     *
+     * <p>The application should not make any assumptions on whether user authentication is needed.
+     * Instead, the application should request the data elements values first and then examine
+     * the returned {@link CredentialDataResult.Entries}. If
+     * {@link CredentialDataResult.Entries#STATUS_USER_AUTHENTICATION_FAILED} is returned the
+     * application should get a
+     * {@link android.hardware.biometrics.BiometricPrompt.CryptoObject} which references this
+     * object and use it with a {@link android.hardware.biometrics.BiometricPrompt}. Upon successful
+     * authentication the application may call
+     * {@link #getCredentialData(String, CredentialDataRequest)} again.
+     *
+     * <p>It is permissible to call this method multiple times using the same credential name.
+     * If this is done the same auth-key will be used.
+     *
+     * <p>If the reader signature is set in the request parameter (via the
+     * {@link CredentialDataRequest.Builder#setReaderSignature(byte[])} method) it must contain
+     * the bytes of a {@code COSE_Sign1} structure as defined in RFC 8152. For the payload
+     * {@code nil} shall be used and the detached payload is the {@code ReaderAuthenticationBytes}
+     * CBOR described below.
+     * <pre>
+     *     ReaderAuthentication = [
+     *       "ReaderAuthentication",
+     *       SessionTranscript,
+     *       ItemsRequestBytes
+     *     ]
+     *
+     *     ItemsRequestBytes = #6.24(bstr .cbor ItemsRequest)
+     *
+     *     ReaderAuthenticationBytes = #6.24(bstr .cbor ReaderAuthentication)
+     * </pre>
+     *
+     * <p>where {@code ItemsRequestBytes} are the bytes of the request message set in
+     * the request parameter (via the
+     * {@link CredentialDataRequest.Builder#setRequestMessage(byte[])} method).
+     *
+     * <p>The public key corresponding to the key used to make the signature, can be found in the
+     * {@code x5chain} unprotected header element of the {@code COSE_Sign1} structure (as as
+     * described in
+     * <a href="https://tools.ietf.org/html/draft-ietf-cose-x509-08">draft-ietf-cose-x509-08</a>).
+     * There will be at least one certificate in said element and there may be more (and if so,
+     * each certificate must be signed by its successor).
+     *
+     * <p>Data elements protected by reader authentication are returned if, and only if,
+     * {@code requestMessage} is signed by the top-most certificate in the reader's certificate
+     * chain, and the data element is configured with an {@link AccessControlProfile} configured
+     * with an X.509 certificate for a key which appear in the certificate chain.
+     *
+     * <p>Note that the request message CBOR is used only for enforcing reader authentication, it's
+     * not used for determining which entries this API will return. The application is expected to
+     * have parsed the request message and filtered it according to user preference and/or consent.
+     *
+     * @param credentialName the name of the credential to retrieve.
+     * @param request the data to retrieve from the credential
+     * @return If the credential wasn't found, returns null. Otherwise a
+     *         {@link CredentialDataResult} object containing entry data organized by namespace and
+     *         a cryptographically authenticated representation of the same data, bound to the
+     *         current session.
+     * @throws NoAuthenticationKeyAvailableException  if authentication keys were never
+     *                                                provisioned for the credential or if they
+     *                                                are expired or exhausted their use-count.
+     * @throws InvalidRequestMessageException         if the requestMessage is malformed.
+     * @throws InvalidReaderSignatureException        if the reader signature is invalid, or it
+     *                                                doesn't contain a certificate chain, or if
+     *                                                the signature failed to validate.
+     * @throws EphemeralPublicKeyNotFoundException    if the ephemeral public key was not found in
+     *                                                the session transcript.
+     */
+    public abstract @Nullable CredentialDataResult getCredentialData(
+            @NonNull String credentialName, @NonNull CredentialDataRequest request)
+            throws NoAuthenticationKeyAvailableException, InvalidReaderSignatureException,
+            InvalidRequestMessageException, EphemeralPublicKeyNotFoundException;
+
+    /**
+     * Called by android.hardware.biometrics.CryptoObject#getOpId() to get an
+     * operation handle.
+     *
+     * @hide
+     */
+    public abstract long getCredstoreOperationHandle();
+}
diff --git a/identity/java/android/security/identity/ResultData.java b/identity/java/android/security/identity/ResultData.java
index 71860d2..d46f985 100644
--- a/identity/java/android/security/identity/ResultData.java
+++ b/identity/java/android/security/identity/ResultData.java
@@ -28,7 +28,10 @@
 /**
  * An object that contains the result of retrieving data from a credential. This is used to return
  * data requested from a {@link IdentityCredential}.
+ *
+ * @deprecated Use {@link PresentationSession} instead.
  */
+@Deprecated
 public abstract class ResultData {
 
     /** Value was successfully retrieved. */
diff --git a/keystore/java/android/security/AndroidKeyStoreMaintenance.java b/keystore/java/android/security/AndroidKeyStoreMaintenance.java
index 919a93b..05fb4c3 100644
--- a/keystore/java/android/security/AndroidKeyStoreMaintenance.java
+++ b/keystore/java/android/security/AndroidKeyStoreMaintenance.java
@@ -20,6 +20,7 @@
 import android.annotation.Nullable;
 import android.os.ServiceManager;
 import android.os.ServiceSpecificException;
+import android.security.keystore.KeyProperties;
 import android.security.maintenance.IKeystoreMaintenance;
 import android.system.keystore2.Domain;
 import android.system.keystore2.KeyDescriptor;
@@ -157,6 +158,11 @@
      * Migrates a key given by the source descriptor to the location designated by the destination
      * descriptor.
      *
+     * If Domain::APP is selected in either source or destination, nspace must be set to
+     * {@link KeyProperties#NAMESPACE_APPLICATION}, implying the caller's UID.
+     * If the caller has the MIGRATE_ANY_KEY permission, Domain::APP may be used with
+     * other nspace values which then indicates the UID of a different application.
+     *
      * @param source - The key to migrate may be specified by Domain.APP, Domain.SELINUX, or
      *               Domain.KEY_ID. The caller needs the permissions use, delete, and grant for the
      *               source namespace.
@@ -183,4 +189,20 @@
             return SYSTEM_ERROR;
         }
     }
+
+    /**
+     * @see IKeystoreMaintenance#listEntries(int, long)
+     */
+    @Nullable
+    public static KeyDescriptor[] listEntries(int domain, long nspace) {
+        try {
+            return getService().listEntries(domain, nspace);
+        } catch (ServiceSpecificException e) {
+            Log.e(TAG, "listEntries failed", e);
+            return null;
+        } catch (Exception e) {
+            Log.e(TAG, "Can not connect to keystore", e);
+            return null;
+        }
+    }
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/OWNERS b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/OWNERS
new file mode 100644
index 0000000..8446b37
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/OWNERS
@@ -0,0 +1,2 @@
+# window manager > wm shell > Split Screen
+# Bug component: 928697
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/OWNERS b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/OWNERS
new file mode 100644
index 0000000..566acc8
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/OWNERS
@@ -0,0 +1,2 @@
+# window manager > wm shell > Bubbles
+# Bug component: 555586
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/OWNERS b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/OWNERS
new file mode 100644
index 0000000..8446b37
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/OWNERS
@@ -0,0 +1,2 @@
+# window manager > wm shell > Split Screen
+# Bug component: 928697
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/OWNERS b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/OWNERS
new file mode 100644
index 0000000..172e24bf
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/OWNERS
@@ -0,0 +1,2 @@
+# window manager > wm shell > Picture-In-Picture
+# Bug component: 316251
diff --git a/libs/usb/tests/accessorytest/f_accessory.h b/libs/usb/tests/accessorytest/f_accessory.h
index 312f4ba..75e017c 100644
--- a/libs/usb/tests/accessorytest/f_accessory.h
+++ b/libs/usb/tests/accessorytest/f_accessory.h
@@ -1,148 +1,53 @@
-/*
- * Gadget Function Driver for Android USB accessories
- *
- * Copyright (C) 2011 Google, Inc.
- * Author: Mike Lockwood <lockwood@android.com>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-
-#ifndef __LINUX_USB_F_ACCESSORY_H
-#define __LINUX_USB_F_ACCESSORY_H
-
-/* Use Google Vendor ID when in accessory mode */
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ***   To edit the content of this header, modify the corresponding
+ ***   source file (e.g. under external/kernel-headers/original/) then
+ ***   run bionic/libc/kernel/tools/update_all.py
+ ***
+ ***   Any manual change here will be lost the next time this script will
+ ***   be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _UAPI_LINUX_USB_F_ACCESSORY_H
+#define _UAPI_LINUX_USB_F_ACCESSORY_H
 #define USB_ACCESSORY_VENDOR_ID 0x18D1
-
-
-/* Product ID to use when in accessory mode */
 #define USB_ACCESSORY_PRODUCT_ID 0x2D00
-
-/* Product ID to use when in accessory mode and adb is enabled */
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define USB_ACCESSORY_ADB_PRODUCT_ID 0x2D01
-
-/* Indexes for strings sent by the host via ACCESSORY_SEND_STRING */
-#define ACCESSORY_STRING_MANUFACTURER   0
-#define ACCESSORY_STRING_MODEL          1
-#define ACCESSORY_STRING_DESCRIPTION    2
-#define ACCESSORY_STRING_VERSION        3
-#define ACCESSORY_STRING_URI            4
-#define ACCESSORY_STRING_SERIAL         5
-
-/* Control request for retrieving device's protocol version
- *
- *	requestType:    USB_DIR_IN | USB_TYPE_VENDOR
- *	request:        ACCESSORY_GET_PROTOCOL
- *	value:          0
- *	index:          0
- *	data            version number (16 bits little endian)
- *                    1 for original accessory support
- *                    2 adds audio and HID support
- */
-#define ACCESSORY_GET_PROTOCOL  51
-
-/* Control request for host to send a string to the device
- *
- *	requestType:    USB_DIR_OUT | USB_TYPE_VENDOR
- *	request:        ACCESSORY_SEND_STRING
- *	value:          0
- *	index:          string ID
- *	data            zero terminated UTF8 string
- *
- *  The device can later retrieve these strings via the
- *  ACCESSORY_GET_STRING_* ioctls
- */
-#define ACCESSORY_SEND_STRING   52
-
-/* Control request for starting device in accessory mode.
- * The host sends this after setting all its strings to the device.
- *
- *	requestType:    USB_DIR_OUT | USB_TYPE_VENDOR
- *	request:        ACCESSORY_START
- *	value:          0
- *	index:          0
- *	data            none
- */
-#define ACCESSORY_START         53
-
-/* Control request for registering a HID device.
- * Upon registering, a unique ID is sent by the accessory in the
- * value parameter. This ID will be used for future commands for
- * the device
- *
- *	requestType:    USB_DIR_OUT | USB_TYPE_VENDOR
- *	request:        ACCESSORY_REGISTER_HID_DEVICE
- *	value:          Accessory assigned ID for the HID device
- *	index:          total length of the HID report descriptor
- *	data            none
- */
-#define ACCESSORY_REGISTER_HID         54
-
-/* Control request for unregistering a HID device.
- *
- *	requestType:    USB_DIR_OUT | USB_TYPE_VENDOR
- *	request:        ACCESSORY_REGISTER_HID
- *	value:          Accessory assigned ID for the HID device
- *	index:          0
- *	data            none
- */
-#define ACCESSORY_UNREGISTER_HID         55
-
-/* Control request for sending the HID report descriptor.
- * If the HID descriptor is longer than the endpoint zero max packet size,
- * the descriptor will be sent in multiple ACCESSORY_SET_HID_REPORT_DESC
- * commands. The data for the descriptor must be sent sequentially
- * if multiple packets are needed.
- *
- *	requestType:    USB_DIR_OUT | USB_TYPE_VENDOR
- *	request:        ACCESSORY_SET_HID_REPORT_DESC
- *	value:          Accessory assigned ID for the HID device
- *	index:          offset of data in descriptor
- *                  (needed when HID descriptor is too big for one packet)
- *	data            the HID report descriptor
- */
-#define ACCESSORY_SET_HID_REPORT_DESC         56
-
-/* Control request for sending HID events.
- *
- *	requestType:    USB_DIR_OUT | USB_TYPE_VENDOR
- *	request:        ACCESSORY_SEND_HID_EVENT
- *	value:          Accessory assigned ID for the HID device
- *	index:          0
- *	data            the HID report for the event
- */
-#define ACCESSORY_SEND_HID_EVENT         57
-
-/* Control request for setting the audio mode.
- *
- *	requestType:    USB_DIR_OUT | USB_TYPE_VENDOR
- *	request:        ACCESSORY_SET_AUDIO_MODE
- *	value:          0 - no audio
- *                  1 - device to host, 44100 16-bit stereo PCM
- *	index:          0
- *	data            the HID report for the event
- */
-#define ACCESSORY_SET_AUDIO_MODE         58
-
-
-
-/* ioctls for retrieving strings set by the host */
-#define ACCESSORY_GET_STRING_MANUFACTURER   _IOW('M', 1, char[256])
-#define ACCESSORY_GET_STRING_MODEL          _IOW('M', 2, char[256])
-#define ACCESSORY_GET_STRING_DESCRIPTION    _IOW('M', 3, char[256])
-#define ACCESSORY_GET_STRING_VERSION        _IOW('M', 4, char[256])
-#define ACCESSORY_GET_STRING_URI            _IOW('M', 5, char[256])
-#define ACCESSORY_GET_STRING_SERIAL         _IOW('M', 6, char[256])
-/* returns 1 if there is a start request pending */
-#define ACCESSORY_IS_START_REQUESTED        _IO('M', 7)
-/* returns audio mode (set via the ACCESSORY_SET_AUDIO_MODE control request) */
-#define ACCESSORY_GET_AUDIO_MODE            _IO('M', 8)
-
-#endif /* __LINUX_USB_F_ACCESSORY_H */
+#define ACCESSORY_STRING_MANUFACTURER 0
+#define ACCESSORY_STRING_MODEL 1
+#define ACCESSORY_STRING_DESCRIPTION 2
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ACCESSORY_STRING_VERSION 3
+#define ACCESSORY_STRING_URI 4
+#define ACCESSORY_STRING_SERIAL 5
+#define ACCESSORY_GET_PROTOCOL 51
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ACCESSORY_SEND_STRING 52
+#define ACCESSORY_START 53
+#define ACCESSORY_REGISTER_HID 54
+#define ACCESSORY_UNREGISTER_HID 55
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ACCESSORY_SET_HID_REPORT_DESC 56
+#define ACCESSORY_SEND_HID_EVENT 57
+#define ACCESSORY_SET_AUDIO_MODE 58
+#define ACCESSORY_GET_STRING_MANUFACTURER _IOW('M', 1, char[256])
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ACCESSORY_GET_STRING_MODEL _IOW('M', 2, char[256])
+#define ACCESSORY_GET_STRING_DESCRIPTION _IOW('M', 3, char[256])
+#define ACCESSORY_GET_STRING_VERSION _IOW('M', 4, char[256])
+#define ACCESSORY_GET_STRING_URI _IOW('M', 5, char[256])
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ACCESSORY_GET_STRING_SERIAL _IOW('M', 6, char[256])
+#define ACCESSORY_IS_START_REQUESTED _IO('M', 7)
+#define ACCESSORY_GET_AUDIO_MODE _IO('M', 8)
+#endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/media/java/Android.bp b/media/java/Android.bp
index eeaf6e9..c7c1d54 100644
--- a/media/java/Android.bp
+++ b/media/java/Android.bp
@@ -8,7 +8,7 @@
 }
 
 filegroup {
-    name: "framework-media-sources",
+    name: "framework-media-non-updatable-sources",
     srcs: [
         "**/*.java",
         "**/*.aidl",
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index f0e42c0..143b11f 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -242,7 +242,8 @@
             AUDIO_FORMAT_SBC,
             AUDIO_FORMAT_APTX,
             AUDIO_FORMAT_APTX_HD,
-            AUDIO_FORMAT_LDAC}
+            AUDIO_FORMAT_LDAC,
+            AUDIO_FORMAT_LC3}
     )
     @Retention(RetentionPolicy.SOURCE)
     public @interface AudioFormatNativeEnumForBtCodec {}
@@ -274,6 +275,7 @@
             case AUDIO_FORMAT_APTX: return BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX;
             case AUDIO_FORMAT_APTX_HD: return BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD;
             case AUDIO_FORMAT_LDAC: return BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC;
+            case AUDIO_FORMAT_LC3: return BluetoothCodecConfig.SOURCE_CODEC_TYPE_LC3;
             default:
                 Log.e(TAG, "Unknown audio format 0x" + Integer.toHexString(audioFormat)
                         + " for conversion to BT codec");
@@ -314,6 +316,8 @@
                 return AudioSystem.AUDIO_FORMAT_APTX_HD;
             case BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC:
                 return AudioSystem.AUDIO_FORMAT_LDAC;
+            case BluetoothCodecConfig.SOURCE_CODEC_TYPE_LC3:
+                return AudioSystem.AUDIO_FORMAT_LC3;
             default:
                 Log.e(TAG, "Unknown BT codec 0x" + Integer.toHexString(btCodec)
                         + " for conversion to audio format");
@@ -414,6 +418,8 @@
                 return "AUDIO_FORMAT_LHDC_LL";
             case /* AUDIO_FORMAT_APTX_TWSP       */ 0x2A000000:
                 return "AUDIO_FORMAT_APTX_TWSP";
+            case /* AUDIO_FORMAT_LC3             */ 0x2B000000:
+                return "AUDIO_FORMAT_LC3";
 
             /* Aliases */
             case /* AUDIO_FORMAT_PCM_16_BIT        */ 0x1:
diff --git a/media/java/android/media/BtProfileConnectionInfo.java b/media/java/android/media/BtProfileConnectionInfo.java
index 19ea2de..d1bb41e 100644
--- a/media/java/android/media/BtProfileConnectionInfo.java
+++ b/media/java/android/media/BtProfileConnectionInfo.java
@@ -34,7 +34,7 @@
     /** @hide */
     @IntDef({
             BluetoothProfile.A2DP,
-            BluetoothProfile.A2DP_SINK, // Can only be set by BtHelper
+            BluetoothProfile.A2DP_SINK,
             BluetoothProfile.HEADSET, // Can only be set by BtHelper
             BluetoothProfile.HEARING_AID,
             BluetoothProfile.LE_AUDIO,
@@ -105,6 +105,16 @@
     }
 
     /**
+     * Constructor for A2dp sink info
+     * The {@link AudioManager.ACTION_AUDIO_BECOMING_NOISY} intent will not be sent.
+     *
+     * @param volume of device -1 to ignore value
+     */
+    public static @NonNull BtProfileConnectionInfo a2dpSinkInfo(int volume) {
+        return new BtProfileConnectionInfo(BluetoothProfile.A2DP_SINK, true, volume, false);
+    }
+
+    /**
      * Constructor for hearing aid info
      *
      * @param suppressNoisyIntent if true the {@link AudioManager.ACTION_AUDIO_BECOMING_NOISY}
diff --git a/media/java/android/media/MediaCodecInfo.java b/media/java/android/media/MediaCodecInfo.java
index 3c152fb..41c8887 100644
--- a/media/java/android/media/MediaCodecInfo.java
+++ b/media/java/android/media/MediaCodecInfo.java
@@ -426,10 +426,30 @@
         /** @deprecated Use {@link #COLOR_Format32bitABGR8888}. */
         public static final int COLOR_Format24BitABGR6666           = 43;
 
-        /** @hide
-         * P010 is a 4:2:0 YCbCr semiplanar format comprised of a WxH Y plane
-         * followed by a Wx(H/2) CbCr plane. Each sample is represented by a 16-bit
-         * little-endian value, with the lower 6 bits set to zero. */
+        /**
+         * P010 is 10-bit-per component 4:2:0 YCbCr semiplanar format.
+         * <p>
+         * This format uses 24 allocated bits per pixel with 15 bits of
+         * data per pixel. Chroma planes are subsampled by 2 both
+         * horizontally and vertically. Each chroma and luma component
+         * has 16 allocated bits in little-endian configuration with 10
+         * MSB of actual data.
+         *
+         * <pre>
+         *            byte                   byte
+         *  <--------- i --------> | <------ i + 1 ------>
+         * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+         * |     UNUSED      |      Y/Cb/Cr                |
+         * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+         *  0               5 6   7 0                    7
+         * bit
+         * </pre>
+         *
+         * Use this format with {@link Image}. This format corresponds
+         * to {@link android.graphics.ImageFormat#YCBCR_P010}.
+         * <p>
+         */
+        @SuppressLint("AllUpper")
         public static final int COLOR_FormatYUVP010                 = 54;
 
         /** @deprecated Use {@link #COLOR_FormatYUV420Flexible}. */
@@ -439,6 +459,25 @@
         public static final int COLOR_FormatSurface                   = 0x7F000789;
 
         /**
+         * 64 bits per pixel RGBA color format, with 16-bit signed
+         * floating point red, green, blue, and alpha components.
+         * <p>
+         *
+         * <pre>
+         *         byte              byte             byte              byte
+         *  <-- i -->|<- i+1 ->|<- i+2 ->|<- i+3 ->|<- i+4 ->|<- i+5 ->|<- i+6 ->|<- i+7 ->
+         * +---------+---------+-------------------+---------+---------+---------+---------+
+         * |        RED        |       GREEN       |       BLUE        |       ALPHA       |
+         * +---------+---------+-------------------+---------+---------+---------+---------+
+         *  0       7 0       7 0       7 0       7 0       7 0       7 0       7 0       7
+         * </pre>
+         *
+         * This corresponds to {@link android.graphics.PixelFormat#RGBA_F16}.
+         */
+        @SuppressLint("AllUpper")
+        public static final int COLOR_Format64bitABGRFloat            = 0x7F000F16;
+
+        /**
          * 32 bits per pixel RGBA color format, with 8-bit red, green, blue, and alpha components.
          * <p>
          * Using 32-bit little-endian representation, colors stored as Red 7:0, Green 15:8,
@@ -456,6 +495,26 @@
         public static final int COLOR_Format32bitABGR8888             = 0x7F00A000;
 
         /**
+         * 32 bits per pixel RGBA color format, with 10-bit red, green,
+         * blue, and 2-bit alpha components.
+         * <p>
+         * Using 32-bit little-endian representation, colors stored as
+         * Red 9:0, Green 19:10, Blue 29:20, and Alpha 31:30.
+         * <pre>
+         *         byte              byte             byte              byte
+         *  <------ i -----> | <---- i+1 ----> | <---- i+2 ----> | <---- i+3 ----->
+         * +-----------------+---+-------------+-------+---------+-----------+-----+
+         * |       RED           |      GREEN          |       BLUE          |ALPHA|
+         * +-----------------+---+-------------+-------+---------+-----------+-----+
+         *  0               7 0 1 2           7 0     3 4       7 0         5 6   7
+         * </pre>
+         *
+         * This corresponds to {@link android.graphics.PixelFormat#RGBA_1010102}.
+         */
+        @SuppressLint("AllUpper")
+        public static final int COLOR_Format32bitABGR2101010          = 0x7F00AAA2;
+
+        /**
          * Flexible 12 bits per pixel, subsampled YUV color format with 8-bit chroma and luma
          * components.
          * <p>
@@ -603,6 +662,18 @@
         public static final String FEATURE_QpBounds = "qp-bounds";
 
         /**
+         * <b>video encoder only</b>: codec supports exporting encoding statistics.
+         * Encoders with this feature can provide the App clients with the encoding statistics
+         * information about the frame.
+         * The scope of encoding statistics is controlled by
+         * {@link MediaFormat#KEY_VIDEO_ENCODING_STATISTICS_LEVEL}.
+         *
+         * @see MediaFormat#KEY_VIDEO_ENCODING_STATISTICS_LEVEL
+         */
+        @SuppressLint("AllUpper") // for consistency with other FEATURE_* constants
+        public static final String FEATURE_EncodingStatistics = "encoding-statistics";
+
+        /**
          * Query codec feature capabilities.
          * <p>
          * These features are supported to be used by the codec.  These
@@ -641,6 +712,7 @@
             new Feature(FEATURE_MultipleFrames, (1 << 1), false),
             new Feature(FEATURE_DynamicTimestamp, (1 << 2), false),
             new Feature(FEATURE_QpBounds, (1 << 3), false),
+            new Feature(FEATURE_EncodingStatistics, (1 << 4), false),
             // feature to exclude codec from REGULAR codec list
             new Feature(FEATURE_SpecialCodec,     (1 << 30), false, true),
         };
diff --git a/media/java/android/media/MediaFormat.java b/media/java/android/media/MediaFormat.java
index 9bf0db5..aa5c404 100644
--- a/media/java/android/media/MediaFormat.java
+++ b/media/java/android/media/MediaFormat.java
@@ -1102,6 +1102,76 @@
     public static final String KEY_VIDEO_QP_B_MIN = "video-qp-b-min";
 
     /**
+     * A key describing the level of encoding statistics information emitted from video encoder.
+     *
+     * The associated value is an integer.
+     */
+    public static final String KEY_VIDEO_ENCODING_STATISTICS_LEVEL =
+            "video-encoding-statistics-level";
+
+    /**
+     * Encoding Statistics Level None.
+     * Encoder generates no information about Encoding statistics.
+     */
+    public static final int VIDEO_ENCODING_STATISTICS_LEVEL_NONE = 0;
+
+    /**
+     * Encoding Statistics Level 1.
+     * Encoder generates {@link MediaFormat#KEY_PICTURE_TYPE} and
+     * {@link MediaFormat#KEY_VIDEO_QP_AVERAGE} for each frame.
+     */
+    public static final int VIDEO_ENCODING_STATISTICS_LEVEL_1 = 1;
+
+    /** @hide */
+    @IntDef({
+        VIDEO_ENCODING_STATISTICS_LEVEL_NONE,
+        VIDEO_ENCODING_STATISTICS_LEVEL_1,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface VideoEncodingStatisticsLevel {}
+
+    /**
+     * A key describing the per-frame average block QP (Quantization Parameter).
+     * This is a part of a video 'Encoding Statistics' export feature.
+     * This value is emitted from video encoder for a video frame.
+     * The average value is rounded down (using floor()) to integer value.
+     *
+     * The associated value is an integer.
+     */
+    public static final String KEY_VIDEO_QP_AVERAGE = "video-qp-average";
+
+    /**
+     * A key describing the picture type of the encoded frame.
+     * This is a part of a video 'Encoding Statistics' export feature.
+     * This value is emitted from video encoder for a video frame.
+     *
+     * The associated value is an integer.
+     */
+    public static final String KEY_PICTURE_TYPE = "picture-type";
+
+    /** Picture Type is unknown. */
+    public static final int PICTURE_TYPE_UNKNOWN = 0;
+
+    /** Picture Type is I Frame. */
+    public static final int PICTURE_TYPE_I = 1;
+
+    /** Picture Type is P Frame. */
+    public static final int PICTURE_TYPE_P = 2;
+
+    /** Picture Type is B Frame. */
+    public static final int PICTURE_TYPE_B = 3;
+
+    /** @hide */
+    @IntDef({
+        PICTURE_TYPE_UNKNOWN,
+        PICTURE_TYPE_I,
+        PICTURE_TYPE_P,
+        PICTURE_TYPE_B,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface PictureType {}
+
+    /**
      * A key describing the audio session ID of the AudioTrack associated
      * to a tunneled video codec.
      * The associated value is an integer.
diff --git a/media/java/android/media/Ringtone.java b/media/java/android/media/Ringtone.java
index 3cf0341..86a94a9 100644
--- a/media/java/android/media/Ringtone.java
+++ b/media/java/android/media/Ringtone.java
@@ -504,49 +504,51 @@
     }
 
     private boolean playFallbackRingtone() {
-        if (mAudioManager.getStreamVolume(AudioAttributes.toLegacyStreamType(mAudioAttributes))
-                != 0) {
-            int ringtoneType = RingtoneManager.getDefaultType(mUri);
-            if (ringtoneType == -1 ||
-                    RingtoneManager.getActualDefaultRingtoneUri(mContext, ringtoneType) != null) {
-                // Default ringtone, try fallback ringtone.
-                try {
-                    AssetFileDescriptor afd = mContext.getResources().openRawResourceFd(
-                            com.android.internal.R.raw.fallbackring);
-                    if (afd != null) {
-                        mLocalPlayer = new MediaPlayer();
-                        if (afd.getDeclaredLength() < 0) {
-                            mLocalPlayer.setDataSource(afd.getFileDescriptor());
-                        } else {
-                            mLocalPlayer.setDataSource(afd.getFileDescriptor(),
-                                    afd.getStartOffset(),
-                                    afd.getDeclaredLength());
-                        }
-                        mLocalPlayer.setAudioAttributes(mAudioAttributes);
-                        synchronized (mPlaybackSettingsLock) {
-                            applyPlaybackProperties_sync();
-                        }
-                        if (mVolumeShaperConfig != null) {
-                            mVolumeShaper = mLocalPlayer.createVolumeShaper(mVolumeShaperConfig);
-                        }
-                        mLocalPlayer.prepare();
-                        startLocalPlayer();
-                        afd.close();
-                        return true;
-                    } else {
-                        Log.e(TAG, "Could not load fallback ringtone");
-                    }
-                } catch (IOException ioe) {
-                    destroyLocalPlayer();
-                    Log.e(TAG, "Failed to open fallback ringtone");
-                } catch (NotFoundException nfe) {
-                    Log.e(TAG, "Fallback ringtone does not exist");
-                }
-            } else {
-                Log.w(TAG, "not playing fallback for " + mUri);
-            }
+        int streamType = AudioAttributes.toLegacyStreamType(mAudioAttributes);
+        if (mAudioManager.getStreamVolume(streamType) == 0) {
+            return false;
         }
-        return false;
+        int ringtoneType = RingtoneManager.getDefaultType(mUri);
+        if (ringtoneType != -1 &&
+                RingtoneManager.getActualDefaultRingtoneUri(mContext, ringtoneType) == null) {
+            Log.w(TAG, "not playing fallback for " + mUri);
+            return false;
+        }
+        // Default ringtone, try fallback ringtone.
+        try {
+            AssetFileDescriptor afd = mContext.getResources().openRawResourceFd(
+                    com.android.internal.R.raw.fallbackring);
+            if (afd == null) {
+                Log.e(TAG, "Could not load fallback ringtone");
+                return false;
+            }
+            mLocalPlayer = new MediaPlayer();
+            if (afd.getDeclaredLength() < 0) {
+                mLocalPlayer.setDataSource(afd.getFileDescriptor());
+            } else {
+                mLocalPlayer.setDataSource(afd.getFileDescriptor(),
+                        afd.getStartOffset(),
+                        afd.getDeclaredLength());
+            }
+            mLocalPlayer.setAudioAttributes(mAudioAttributes);
+            synchronized (mPlaybackSettingsLock) {
+                applyPlaybackProperties_sync();
+            }
+            if (mVolumeShaperConfig != null) {
+                mVolumeShaper = mLocalPlayer.createVolumeShaper(mVolumeShaperConfig);
+            }
+            mLocalPlayer.prepare();
+            startLocalPlayer();
+            afd.close();
+        } catch (IOException ioe) {
+            destroyLocalPlayer();
+            Log.e(TAG, "Failed to open fallback ringtone");
+            return false;
+        } catch (NotFoundException nfe) {
+            Log.e(TAG, "Fallback ringtone does not exist");
+            return false;
+        }
+        return true;
     }
 
     void setTitle(String title) {
diff --git a/media/java/android/media/tv/OWNERS b/media/java/android/media/tv/OWNERS
index 33acd0d..fa04293 100644
--- a/media/java/android/media/tv/OWNERS
+++ b/media/java/android/media/tv/OWNERS
@@ -1,6 +1,6 @@
-nchalko@google.com
 quxiangfang@google.com
 shubang@google.com
+hgchen@google.com
 
 # For android remote service
 per-file ITvRemoteServiceInput.aidl = file:/media/lib/tvremote/OWNERS
diff --git a/media/java/android/media/tv/TvInputManager.java b/media/java/android/media/tv/TvInputManager.java
index efd9d10..420f4ef 100644
--- a/media/java/android/media/tv/TvInputManager.java
+++ b/media/java/android/media/tv/TvInputManager.java
@@ -18,6 +18,7 @@
 
 import android.annotation.CallbackExecutor;
 import android.annotation.IntDef;
+import android.annotation.IntRange;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
@@ -27,6 +28,8 @@
 import android.content.Context;
 import android.content.Intent;
 import android.graphics.Rect;
+import android.media.AudioDeviceInfo;
+import android.media.AudioFormat.Encoding;
 import android.media.PlaybackParams;
 import android.net.Uri;
 import android.os.Binder;
@@ -59,6 +62,7 @@
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.concurrent.Executor;
 
 /**
@@ -2998,6 +3002,16 @@
             return false;
         }
 
+        /**
+         * Override default audio sink from audio policy.
+         *
+         * @param audioType device type of the audio sink to override with.
+         * @param audioAddress device address of the audio sink to override with.
+         * @param samplingRate desired sampling rate. Use default when it's 0.
+         * @param channelMask desired channel mask. Use default when it's
+         *        AudioFormat.CHANNEL_OUT_DEFAULT.
+         * @param format desired format. Use default when it's AudioFormat.ENCODING_DEFAULT.
+         */
         public void overrideAudioSink(int audioType, String audioAddress, int samplingRate,
                 int channelMask, int format) {
             try {
@@ -3007,5 +3021,27 @@
                 throw new RuntimeException(e);
             }
         }
+
+        /**
+         * Override default audio sink from audio policy.
+         *
+         * @param device {@link android.media.AudioDeviceInfo} to use.
+         * @param samplingRate desired sampling rate. Use default when it's 0.
+         * @param channelMask desired channel mask. Use default when it's
+         *        AudioFormat.CHANNEL_OUT_DEFAULT.
+         * @param format desired format. Use default when it's AudioFormat.ENCODING_DEFAULT.
+         */
+        public void overrideAudioSink(@NonNull AudioDeviceInfo device,
+                @IntRange(from = 0) int samplingRate,
+                int channelMask, @Encoding int format) {
+            Objects.requireNonNull(device);
+            try {
+                mInterface.overrideAudioSink(
+                        AudioDeviceInfo.convertDeviceTypeToInternalDevice(device.getType()),
+                        device.getAddress(), samplingRate, channelMask, format);
+            } catch (RemoteException e) {
+                throw new RuntimeException(e);
+            }
+        }
     }
 }
diff --git a/media/java/android/media/tv/tunerresourcemanager/OWNER b/media/java/android/media/tv/tunerresourcemanager/OWNER
index 76b84d9..0eb1c31 100644
--- a/media/java/android/media/tv/tunerresourcemanager/OWNER
+++ b/media/java/android/media/tv/tunerresourcemanager/OWNER
@@ -1,4 +1,3 @@
-amyjojo@google.com
-nchalko@google.com
 quxiangfang@google.com
-shubang@google.com
\ No newline at end of file
+shubang@google.com
+kemiyagi@google.com
\ No newline at end of file
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/BtProfileConnectionInfoTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/BtProfileConnectionInfoTest.java
new file mode 100644
index 0000000..fd66d3b
--- /dev/null
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/BtProfileConnectionInfoTest.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.mediaframeworktest.unit;
+
+import static org.junit.Assert.assertEquals;
+
+import android.bluetooth.BluetoothProfile;
+import android.media.BtProfileConnectionInfo;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class BtProfileConnectionInfoTest {
+
+    @Test
+    public void testCoverageA2dp() {
+        final boolean supprNoisy = false;
+        final int volume = 42;
+        final BtProfileConnectionInfo info = BtProfileConnectionInfo.a2dpInfo(supprNoisy, volume);
+        assertEquals(info.getProfile(), BluetoothProfile.A2DP);
+        assertEquals(info.getSuppressNoisyIntent(), supprNoisy);
+        assertEquals(info.getVolume(), volume);
+    }
+
+    @Test
+    public void testCoverageA2dpSink() {
+        final int volume = 42;
+        final BtProfileConnectionInfo info = BtProfileConnectionInfo.a2dpSinkInfo(volume);
+        assertEquals(info.getProfile(), BluetoothProfile.A2DP_SINK);
+        assertEquals(info.getVolume(), volume);
+    }
+
+    @Test
+    public void testCoveragehearingAid() {
+        final boolean supprNoisy = true;
+        final BtProfileConnectionInfo info = BtProfileConnectionInfo.hearingAidInfo(supprNoisy);
+        assertEquals(info.getProfile(), BluetoothProfile.HEARING_AID);
+        assertEquals(info.getSuppressNoisyIntent(), supprNoisy);
+    }
+
+    @Test
+    public void testCoverageLeAudio() {
+        final boolean supprNoisy = false;
+        final boolean isLeOutput = true;
+        final BtProfileConnectionInfo info = BtProfileConnectionInfo.leAudio(supprNoisy,
+                isLeOutput);
+        assertEquals(info.getProfile(), BluetoothProfile.LE_AUDIO);
+        assertEquals(info.getSuppressNoisyIntent(), supprNoisy);
+        assertEquals(info.getIsLeOutput(), isLeOutput);
+    }
+}
+
diff --git a/media/tests/TunerTest/OWNERS b/media/tests/TunerTest/OWNERS
index 73ea663..7554889 100644
--- a/media/tests/TunerTest/OWNERS
+++ b/media/tests/TunerTest/OWNERS
@@ -1,4 +1,4 @@
-amyjojo@google.com
-nchalko@google.com
 quxiangfang@google.com
 shubang@google.com
+hgchen@google.com
+kemiyagi@google.com
\ No newline at end of file
diff --git a/native/android/libandroid_net.map.txt b/native/android/libandroid_net.map.txt
index a6c1b50..32fd734 100644
--- a/native/android/libandroid_net.map.txt
+++ b/native/android/libandroid_net.map.txt
@@ -18,6 +18,10 @@
     android_getprocnetwork; # llndk
     android_setprocdns; # llndk
     android_getprocdns; # llndk
+    # These functions have been part of the NDK since API 33.
+    android_tag_socket_with_uid; # llndk
+    android_tag_socket;  # llndk
+    android_untag_socket; # llndk
   local:
     *;
 };
diff --git a/native/android/net.c b/native/android/net.c
index e2f36a7..d7c22e1 100644
--- a/native/android/net.c
+++ b/native/android/net.c
@@ -161,3 +161,15 @@
 void android_res_cancel(int nsend_fd) {
     resNetworkCancel(nsend_fd);
 }
+
+int android_tag_socket_with_uid(int sockfd, int tag, uid_t uid) {
+    return tagSocket(sockfd, tag, uid);
+}
+
+int android_tag_socket(int sockfd, int tag) {
+    return tagSocket(sockfd, tag, -1);
+}
+
+int android_untag_socket(int sockfd) {
+    return untagSocket(sockfd);
+}
diff --git a/packages/ConnectivityT/framework-t/Android.bp b/packages/ConnectivityT/framework-t/Android.bp
index 90bb76a..223bdcdd 100644
--- a/packages/ConnectivityT/framework-t/Android.bp
+++ b/packages/ConnectivityT/framework-t/Android.bp
@@ -129,6 +129,11 @@
         "src/android/net/EthernetNetworkSpecifier.java",
         "src/android/net/IEthernetManager.aidl",
         "src/android/net/IEthernetServiceListener.aidl",
+        "src/android/net/IInternalNetworkManagementListener.aidl",
+        "src/android/net/InternalNetworkUpdateRequest.java",
+        "src/android/net/InternalNetworkUpdateRequest.aidl",
+        "src/android/net/InternalNetworkManagementException.java",
+        "src/android/net/InternalNetworkManagementException.aidl",
         "src/android/net/ITetheredInterfaceCallback.aidl",
     ],
     path: "src",
@@ -156,8 +161,18 @@
         ":framework-connectivity-ethernet-sources",
         ":framework-connectivity-ipsec-sources",
         ":framework-connectivity-netstats-sources",
+    ],
+    visibility: ["//frameworks/base"],
+}
+
+filegroup {
+    name: "framework-connectivity-tiramisu-updatable-sources",
+    srcs: [
         ":framework-connectivity-nsd-sources",
         ":framework-connectivity-tiramisu-internal-sources",
     ],
-    visibility: ["//frameworks/base"],
+    visibility: [
+        "//frameworks/base",
+        "//packages/modules/Connectivity:__subpackages__",
+    ],
 }
diff --git a/packages/ConnectivityT/framework-t/src/android/app/usage/NetworkStats.java b/packages/ConnectivityT/framework-t/src/android/app/usage/NetworkStats.java
index f684a4d..2b6570a 100644
--- a/packages/ConnectivityT/framework-t/src/android/app/usage/NetworkStats.java
+++ b/packages/ConnectivityT/framework-t/src/android/app/usage/NetworkStats.java
@@ -545,9 +545,18 @@
     }
 
     /**
+     * Collects tagged summary results and sets summary enumeration mode.
+     * @throws RemoteException
+     */
+    void startTaggedSummaryEnumeration() throws RemoteException {
+        mSummary = mSession.getTaggedSummaryForAllUid(mTemplate, mStartTimeStamp, mEndTimeStamp);
+        mEnumerationIndex = 0;
+    }
+
+    /**
      * Collects history results for uid and resets history enumeration index.
      */
-    void startHistoryEnumeration(int uid, int tag, int state) {
+    void startHistoryUidEnumeration(int uid, int tag, int state) {
         mHistory = null;
         try {
             mHistory = mSession.getHistoryIntervalForUid(mTemplate, uid,
@@ -562,6 +571,20 @@
     }
 
     /**
+     * Collects history results for network and resets history enumeration index.
+     */
+    void startHistoryDeviceEnumeration() {
+        try {
+            mHistory = mSession.getHistoryIntervalForNetwork(
+                    mTemplate, NetworkStatsHistory.FIELD_ALL, mStartTimeStamp, mEndTimeStamp);
+        } catch (RemoteException e) {
+            Log.w(TAG, e);
+            mHistory = null;
+        }
+        mEnumerationIndex = 0;
+    }
+
+    /**
      * Starts uid enumeration for current user.
      * @throws RemoteException
      */
diff --git a/packages/ConnectivityT/framework-t/src/android/app/usage/NetworkStatsManager.java b/packages/ConnectivityT/framework-t/src/android/app/usage/NetworkStatsManager.java
index 583f7ba..28f930f 100644
--- a/packages/ConnectivityT/framework-t/src/android/app/usage/NetworkStatsManager.java
+++ b/packages/ConnectivityT/framework-t/src/android/app/usage/NetworkStatsManager.java
@@ -17,7 +17,11 @@
 package android.app.usage;
 
 import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
+import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
+import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
 
+import android.Manifest;
+import android.annotation.CallbackExecutor;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
@@ -36,14 +40,11 @@
 import android.net.NetworkStateSnapshot;
 import android.net.NetworkTemplate;
 import android.net.UnderlyingNetworkInfo;
+import android.net.netstats.IUsageCallback;
 import android.net.netstats.provider.INetworkStatsProviderCallback;
 import android.net.netstats.provider.NetworkStatsProvider;
-import android.os.Binder;
 import android.os.Build;
 import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.Messenger;
 import android.os.RemoteException;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
@@ -54,7 +55,7 @@
 
 import java.util.List;
 import java.util.Objects;
-import java.util.Set;
+import java.util.concurrent.Executor;
 
 /**
  * Provides access to network usage history and statistics. Usage data is collected in
@@ -124,6 +125,19 @@
     private final Context mContext;
     private final INetworkStatsService mService;
 
+    /**
+     * Type constants for reading different types of Data Usage.
+     * @hide
+     */
+    // @SystemApi(client = MODULE_LIBRARIES)
+    public static final String PREFIX_DEV = "dev";
+    /** @hide */
+    public static final String PREFIX_XT = "xt";
+    /** @hide */
+    public static final String PREFIX_UID = "uid";
+    /** @hide */
+    public static final String PREFIX_UID_TAG = "uid_tag";
+
     /** @hide */
     public static final int FLAG_POLL_ON_OPEN = 1 << 0;
     /** @hide */
@@ -143,6 +157,25 @@
     }
 
     /** @hide */
+    public INetworkStatsService getBinder() {
+        return mService;
+    }
+
+    /**
+     * Set poll on open flag to indicate the poll is needed before service gets statistics
+     * result. This is default enabled. However, for any non-privileged caller, the poll might
+     * be omitted in case of rate limiting.
+     *
+     * @param pollOnOpen true if poll is needed.
+     * @hide
+     */
+    // The system will ignore any non-default values for non-privileged
+    // processes, so processes that don't hold the appropriate permissions
+    // can make no use of this API.
+    @SystemApi(client = MODULE_LIBRARIES)
+    @RequiresPermission(anyOf = {
+            NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
+            android.Manifest.permission.NETWORK_STACK})
     public void setPollOnOpen(boolean pollOnOpen) {
         if (pollOnOpen) {
             mFlags |= FLAG_POLL_ON_OPEN;
@@ -196,9 +229,10 @@
      */
     @NonNull
     @WorkerThread
-    // @SystemApi(client = MODULE_LIBRARIES)
+    @SystemApi(client = MODULE_LIBRARIES)
     public Bucket querySummaryForDevice(@NonNull NetworkTemplate template,
             long startTime, long endTime) {
+        Objects.requireNonNull(template);
         try {
             NetworkStats stats =
                     new NetworkStats(mContext, template, mFlags, startTime, endTime, mService);
@@ -369,11 +403,12 @@
      * @return Statistics which is described above.
      * @hide
      */
-    @Nullable
-    // @SystemApi(client = MODULE_LIBRARIES)
+    @NonNull
+    @SystemApi(client = MODULE_LIBRARIES)
     @WorkerThread
     public NetworkStats querySummary(@NonNull NetworkTemplate template, long startTime,
             long endTime) throws SecurityException {
+        Objects.requireNonNull(template);
         try {
             NetworkStats result =
                     new NetworkStats(mContext, template, mFlags, startTime, endTime, mService);
@@ -386,6 +421,77 @@
     }
 
     /**
+     * Query tagged network usage statistics summaries.
+     *
+     * The results will only include tagged traffic made by UIDs belonging to the calling user
+     * profile. The results are aggregated over time, so that all buckets will have the same
+     * start and end timestamps as the passed arguments. Not aggregated over state, uid,
+     * default network, metered, or roaming.
+     * This may take a long time, and apps should avoid calling this on their main thread.
+     *
+     * @param template Template used to match networks. See {@link NetworkTemplate}.
+     * @param startTime Start of period, in milliseconds since the Unix epoch, see
+     *            {@link System#currentTimeMillis}.
+     * @param endTime End of period, in milliseconds since the Unix epoch, see
+     *            {@link System#currentTimeMillis}.
+     * @return Statistics which is described above.
+     * @hide
+     */
+    @NonNull
+    @SystemApi(client = MODULE_LIBRARIES)
+    @WorkerThread
+    public NetworkStats queryTaggedSummary(@NonNull NetworkTemplate template, long startTime,
+            long endTime) throws SecurityException {
+        Objects.requireNonNull(template);
+        try {
+            NetworkStats result =
+                    new NetworkStats(mContext, template, mFlags, startTime, endTime, mService);
+            result.startTaggedSummaryEnumeration();
+            return result;
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+        return null; // To make the compiler happy.
+    }
+
+    /**
+     * Query usage statistics details for networks matching a given {@link NetworkTemplate}.
+     *
+     * Result is not aggregated over time. This means buckets' start and
+     * end timestamps will be between 'startTime' and 'endTime' parameters.
+     * <p>Only includes buckets whose entire time period is included between
+     * startTime and endTime. Doesn't interpolate or return partial buckets.
+     * Since bucket length is in the order of hours, this
+     * method cannot be used to measure data usage on a fine grained time scale.
+     * This may take a long time, and apps should avoid calling this on their main thread.
+     *
+     * @param template Template used to match networks. See {@link NetworkTemplate}.
+     * @param startTime Start of period, in milliseconds since the Unix epoch, see
+     *                  {@link java.lang.System#currentTimeMillis}.
+     * @param endTime End of period, in milliseconds since the Unix epoch, see
+     *                {@link java.lang.System#currentTimeMillis}.
+     * @return Statistics which is described above.
+     * @hide
+     */
+    @NonNull
+    @SystemApi(client = MODULE_LIBRARIES)
+    @WorkerThread
+    public NetworkStats queryDetailsForDevice(@NonNull NetworkTemplate template,
+            long startTime, long endTime) {
+        Objects.requireNonNull(template);
+        try {
+            final NetworkStats result =
+                    new NetworkStats(mContext, template, mFlags, startTime, endTime, mService);
+            result.startHistoryDeviceEnumeration();
+            return result;
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+
+        return null; // To make the compiler happy.
+    }
+
+    /**
      * Query network usage statistics details for a given uid.
      * This may take a long time, and apps should avoid calling this on their main thread.
      *
@@ -451,7 +557,8 @@
      * @param endTime End of period. Defined in terms of "Unix time", see
      *            {@link java.lang.System#currentTimeMillis}.
      * @param uid UID of app
-     * @param tag TAG of interest. Use {@link NetworkStats.Bucket#TAG_NONE} for no tags.
+     * @param tag TAG of interest. Use {@link NetworkStats.Bucket#TAG_NONE} for aggregated data
+     *            across all the tags.
      * @param state state of interest. Use {@link NetworkStats.Bucket#STATE_ALL} to aggregate
      *            traffic from all states.
      * @return Statistics object or null if an error happened during statistics collection.
@@ -466,21 +573,52 @@
         return queryDetailsForUidTagState(template, startTime, endTime, uid, tag, state);
     }
 
-    /** @hide */
-    public NetworkStats queryDetailsForUidTagState(NetworkTemplate template,
+    /**
+     * Query network usage statistics details for a given template, uid, tag, and state.
+     *
+     * Only usable for uids belonging to calling user. Result is not aggregated over time.
+     * This means buckets' start and end timestamps are going to be between 'startTime' and
+     * 'endTime' parameters. The uid is going to be the same as the 'uid' parameter, the tag
+     * the same as the 'tag' parameter, and the state the same as the 'state' parameter.
+     * defaultNetwork is going to be {@link NetworkStats.Bucket#DEFAULT_NETWORK_ALL},
+     * metered is going to be {@link NetworkStats.Bucket#METERED_ALL}, and
+     * roaming is going to be {@link NetworkStats.Bucket#ROAMING_ALL}.
+     * <p>Only includes buckets that atomically occur in the inclusive time range. Doesn't
+     * interpolate across partial buckets. Since bucket length is in the order of hours, this
+     * method cannot be used to measure data usage on a fine grained time scale.
+     * This may take a long time, and apps should avoid calling this on their main thread.
+     *
+     * @param template Template used to match networks. See {@link NetworkTemplate}.
+     * @param startTime Start of period, in milliseconds since the Unix epoch, see
+     *                  {@link java.lang.System#currentTimeMillis}.
+     * @param endTime End of period, in milliseconds since the Unix epoch, see
+     *                {@link java.lang.System#currentTimeMillis}.
+     * @param uid UID of app
+     * @param tag TAG of interest. Use {@link NetworkStats.Bucket#TAG_NONE} for aggregated data
+     *            across all the tags.
+     * @param state state of interest. Use {@link NetworkStats.Bucket#STATE_ALL} to aggregate
+     *            traffic from all states.
+     * @return Statistics which is described above.
+     * @hide
+     */
+    @NonNull
+    @SystemApi(client = MODULE_LIBRARIES)
+    @WorkerThread
+    public NetworkStats queryDetailsForUidTagState(@NonNull NetworkTemplate template,
             long startTime, long endTime, int uid, int tag, int state) throws SecurityException {
-
-        NetworkStats result;
+        Objects.requireNonNull(template);
         try {
-            result = new NetworkStats(mContext, template, mFlags, startTime, endTime, mService);
-            result.startHistoryEnumeration(uid, tag, state);
+            final NetworkStats result = new NetworkStats(
+                    mContext, template, mFlags, startTime, endTime, mService);
+            result.startHistoryUidEnumeration(uid, tag, state);
+            return result;
         } catch (RemoteException e) {
             Log.e(TAG, "Error while querying stats for uid=" + uid + " tag=" + tag
                     + " state=" + state, e);
-            return null;
+            e.rethrowFromSystemServer();
         }
 
-        return result;
+        return null; // To make the compiler happy.
     }
 
     /**
@@ -537,50 +675,83 @@
     }
 
     /**
-     * Query realtime network usage statistics details with interfaces constrains.
-     * Return snapshot of current UID statistics, including any {@link TrafficStats#UID_TETHERING},
-     * video calling data usage and count of network operations that set by
-     * {@link TrafficStats#incrementOperationCount}. The returned data doesn't include any
-     * statistics that is reported by {@link NetworkStatsProvider}.
+     * Query realtime mobile network usage statistics.
      *
-     * @param requiredIfaces A list of interfaces the stats should be restricted to, or
-     *               {@link NetworkStats#INTERFACES_ALL}.
+     * Return a snapshot of current UID network statistics, as it applies
+     * to the mobile radios of the device. The snapshot will include any
+     * tethering traffic, video calling data usage and count of
+     * network operations set by {@link TrafficStats#incrementOperationCount}
+     * made over a mobile radio.
+     * The snapshot will not include any statistics that cannot be seen by
+     * the kernel, e.g. statistics reported by {@link NetworkStatsProvider}s.
      *
      * @hide
      */
-    //@SystemApi
+    @SystemApi
     @RequiresPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK)
-    @NonNull public android.net.NetworkStats getDetailedUidStats(
-                @NonNull Set<String> requiredIfaces) {
-        Objects.requireNonNull(requiredIfaces, "requiredIfaces cannot be null");
+    @NonNull public android.net.NetworkStats getMobileUidStats() {
         try {
-            return mService.getDetailedUidStats(requiredIfaces.toArray(new String[0]));
+            return mService.getUidStatsForTransport(TRANSPORT_CELLULAR);
         } catch (RemoteException e) {
-            if (DBG) Log.d(TAG, "Remote exception when get detailed uid stats");
+            if (DBG) Log.d(TAG, "Remote exception when get Mobile uid stats");
             throw e.rethrowFromSystemServer();
         }
     }
 
-    /** @hide */
-    public void registerUsageCallback(NetworkTemplate template, int networkType,
-            long thresholdBytes, UsageCallback callback, @Nullable Handler handler) {
-        Objects.requireNonNull(callback, "UsageCallback cannot be null");
-
-        final Looper looper;
-        if (handler == null) {
-            looper = Looper.myLooper();
-        } else {
-            looper = handler.getLooper();
+    /**
+     * Query realtime Wi-Fi network usage statistics.
+     *
+     * Return a snapshot of current UID network statistics, as it applies
+     * to the Wi-Fi radios of the device. The snapshot will include any
+     * tethering traffic, video calling data usage and count of
+     * network operations set by {@link TrafficStats#incrementOperationCount}
+     * made over a Wi-Fi radio.
+     * The snapshot will not include any statistics that cannot be seen by
+     * the kernel, e.g. statistics reported by {@link NetworkStatsProvider}s.
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK)
+    @NonNull public android.net.NetworkStats getWifiUidStats() {
+        try {
+            return mService.getUidStatsForTransport(TRANSPORT_WIFI);
+        } catch (RemoteException e) {
+            if (DBG) Log.d(TAG, "Remote exception when get WiFi uid stats");
+            throw e.rethrowFromSystemServer();
         }
+    }
 
-        DataUsageRequest request = new DataUsageRequest(DataUsageRequest.REQUEST_ID_UNSET,
+    /**
+     * Registers to receive notifications about data usage on specified networks.
+     *
+     * <p>The callbacks will continue to be called as long as the process is alive or
+     * {@link #unregisterUsageCallback} is called.
+     *
+     * @param template Template used to match networks. See {@link NetworkTemplate}.
+     * @param thresholdBytes Threshold in bytes to be notified on. The provided value that lower
+     *                       than 2MiB will be clamped for non-privileged callers.
+     * @param executor The executor on which callback will be invoked. The provided {@link Executor}
+     *                 must run callback sequentially, otherwise the order of callbacks cannot be
+     *                 guaranteed.
+     * @param callback The {@link UsageCallback} that the system will call when data usage
+     *                 has exceeded the specified threshold.
+     * @hide
+     */
+    @SystemApi(client = MODULE_LIBRARIES)
+    public void registerUsageCallback(@NonNull NetworkTemplate template, long thresholdBytes,
+            @NonNull @CallbackExecutor Executor executor, @NonNull UsageCallback callback) {
+        Objects.requireNonNull(template, "NetworkTemplate cannot be null");
+        Objects.requireNonNull(callback, "UsageCallback cannot be null");
+        Objects.requireNonNull(executor, "Executor cannot be null");
+
+        final DataUsageRequest request = new DataUsageRequest(DataUsageRequest.REQUEST_ID_UNSET,
                 template, thresholdBytes);
         try {
-            CallbackHandler callbackHandler = new CallbackHandler(looper, networkType,
-                    template.getSubscriberId(), callback);
+            final UsageCallbackWrapper callbackWrapper =
+                    new UsageCallbackWrapper(executor, callback);
             callback.request = mService.registerUsageCallback(
-                    mContext.getOpPackageName(), request, new Messenger(callbackHandler),
-                    new Binder());
+                    mContext.getOpPackageName(), request, callbackWrapper);
             if (DBG) Log.d(TAG, "registerUsageCallback returned " + callback.request);
 
             if (callback.request == null) {
@@ -633,12 +804,15 @@
         NetworkTemplate template = createTemplate(networkType, subscriberId);
         if (DBG) {
             Log.d(TAG, "registerUsageCallback called with: {"
-                + " networkType=" + networkType
-                + " subscriberId=" + subscriberId
-                + " thresholdBytes=" + thresholdBytes
-                + " }");
+                    + " networkType=" + networkType
+                    + " subscriberId=" + subscriberId
+                    + " thresholdBytes=" + thresholdBytes
+                    + " }");
         }
-        registerUsageCallback(template, networkType, thresholdBytes, callback, handler);
+
+        final Executor executor = handler == null ? r -> r.run() : r -> handler.post(r);
+
+        registerUsageCallback(template, thresholdBytes, executor, callback);
     }
 
     /**
@@ -663,6 +837,26 @@
      * Base class for usage callbacks. Should be extended by applications wanting notifications.
      */
     public static abstract class UsageCallback {
+        /**
+         * Called when data usage has reached the given threshold.
+         *
+         * Called by {@code NetworkStatsService} when the registered threshold is reached.
+         * If a caller implements {@link #onThresholdReached(NetworkTemplate)}, the system
+         * will not call {@link #onThresholdReached(int, String)}.
+         *
+         * @param template The {@link NetworkTemplate} that associated with this callback.
+         * @hide
+         */
+        @SystemApi(client = MODULE_LIBRARIES)
+        public void onThresholdReached(@NonNull NetworkTemplate template) {
+            // Backward compatibility for those who didn't override this function.
+            final int networkType = networkTypeForTemplate(template);
+            if (networkType != ConnectivityManager.TYPE_NONE) {
+                final String subscriberId = template.getSubscriberIds().isEmpty() ? null
+                        : template.getSubscriberIds().iterator().next();
+                onThresholdReached(networkType, subscriberId);
+            }
+        }
 
         /**
          * Called when data usage has reached the given threshold.
@@ -673,6 +867,25 @@
          * @hide used for internal bookkeeping
          */
         private DataUsageRequest request;
+
+        /**
+         * Get network type from a template if feasible.
+         *
+         * @param template the target {@link NetworkTemplate}.
+         * @return legacy network type, only supports for the types which is already supported in
+         *         {@link #registerUsageCallback(int, String, long, UsageCallback, Handler)}.
+         *         {@link ConnectivityManager#TYPE_NONE} for other types.
+         */
+        private static int networkTypeForTemplate(@NonNull NetworkTemplate template) {
+            switch (template.getMatchRule()) {
+                case NetworkTemplate.MATCH_MOBILE:
+                    return ConnectivityManager.TYPE_MOBILE;
+                case NetworkTemplate.MATCH_WIFI:
+                    return ConnectivityManager.TYPE_WIFI;
+                default:
+                    return ConnectivityManager.TYPE_NONE;
+            }
+        }
     }
 
     /**
@@ -791,43 +1004,111 @@
         }
     }
 
-    private static class CallbackHandler extends Handler {
-        private final int mNetworkType;
-        private final String mSubscriberId;
-        private UsageCallback mCallback;
+    private static class UsageCallbackWrapper extends IUsageCallback.Stub {
+        // Null if unregistered.
+        private volatile UsageCallback mCallback;
 
-        CallbackHandler(Looper looper, int networkType, String subscriberId,
-                UsageCallback callback) {
-            super(looper);
-            mNetworkType = networkType;
-            mSubscriberId = subscriberId;
+        private final Executor mExecutor;
+
+        UsageCallbackWrapper(@NonNull Executor executor, @NonNull UsageCallback callback) {
             mCallback = callback;
+            mExecutor = executor;
         }
 
         @Override
-        public void handleMessage(Message message) {
-            DataUsageRequest request =
-                    (DataUsageRequest) getObject(message, DataUsageRequest.PARCELABLE_KEY);
-
-            switch (message.what) {
-                case CALLBACK_LIMIT_REACHED: {
-                    if (mCallback != null) {
-                        mCallback.onThresholdReached(mNetworkType, mSubscriberId);
-                    } else {
-                        Log.e(TAG, "limit reached with released callback for " + request);
-                    }
-                    break;
-                }
-                case CALLBACK_RELEASED: {
-                    if (DBG) Log.d(TAG, "callback released for " + request);
-                    mCallback = null;
-                    break;
-                }
+        public void onThresholdReached(DataUsageRequest request) {
+            // Copy it to a local variable in case mCallback changed inside the if condition.
+            final UsageCallback callback = mCallback;
+            if (callback != null) {
+                mExecutor.execute(() -> callback.onThresholdReached(request.template));
+            } else {
+                Log.e(TAG, "onThresholdReached with released callback for " + request);
             }
         }
 
-        private static Object getObject(Message msg, String key) {
-            return msg.getData().getParcelable(key);
+        @Override
+        public void onCallbackReleased(DataUsageRequest request) {
+            if (DBG) Log.d(TAG, "callback released for " + request);
+            mCallback = null;
+        }
+    }
+
+    /**
+     * Mark given UID as being in foreground for stats purposes.
+     *
+     * @hide
+     */
+    @SystemApi(client = MODULE_LIBRARIES)
+    @RequiresPermission(anyOf = {
+            NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
+            android.Manifest.permission.NETWORK_STACK})
+    public void setUidForeground(int uid, boolean uidForeground) {
+        try {
+            mService.setUidForeground(uid, uidForeground);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Set default value of global alert bytes, the value will be clamped to [128kB, 2MB].
+     *
+     * @hide
+     */
+    @SystemApi(client = MODULE_LIBRARIES)
+    @RequiresPermission(anyOf = {
+            NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
+            Manifest.permission.NETWORK_STACK})
+    public void setDefaultGlobalAlert(long alertBytes) {
+        try {
+            // TODO: Sync internal naming with the API surface.
+            mService.advisePersistThreshold(alertBytes);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Force update of statistics.
+     *
+     * @hide
+     */
+    @SystemApi(client = MODULE_LIBRARIES)
+    @RequiresPermission(anyOf = {
+            NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
+            android.Manifest.permission.NETWORK_STACK})
+    public void forceUpdate() {
+        try {
+            mService.forceUpdate();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Set the warning and limit to all registered custom network stats providers.
+     * Note that invocation of any interface will be sent to all providers.
+     *
+     * Asynchronicity notes : because traffic may be happening on the device at the same time, it
+     * doesn't make sense to wait for the warning and limit to be set – a caller still wouldn't
+     * know when exactly it was effective. All that can matter is that it's done quickly. Also,
+     * this method can't fail, so there is no status to return. All providers will see the new
+     * values soon.
+     * As such, this method returns immediately and sends the warning and limit to all providers
+     * as soon as possible through a one-way binder call.
+     *
+     * @hide
+     */
+    @SystemApi(client = MODULE_LIBRARIES)
+    @RequiresPermission(anyOf = {
+            NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
+            android.Manifest.permission.NETWORK_STACK})
+    public void setStatsProviderWarningAndLimitAsync(@NonNull String iface, long warning,
+            long limit) {
+        try {
+            mService.setStatsProviderWarningAndLimitAsync(iface, warning, limit);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
         }
     }
 }
diff --git a/packages/ConnectivityT/framework-t/src/android/net/EthernetNetworkSpecifier.java b/packages/ConnectivityT/framework-t/src/android/net/EthernetNetworkSpecifier.java
index 62c5761..925d12b 100644
--- a/packages/ConnectivityT/framework-t/src/android/net/EthernetNetworkSpecifier.java
+++ b/packages/ConnectivityT/framework-t/src/android/net/EthernetNetworkSpecifier.java
@@ -23,8 +23,6 @@
 import android.os.Parcelable;
 import android.text.TextUtils;
 
-import com.android.internal.util.Preconditions;
-
 import java.util.Objects;
 
 /**
@@ -47,7 +45,9 @@
      * @param interfaceName Name of the ethernet interface the specifier refers to.
      */
     public EthernetNetworkSpecifier(@NonNull String interfaceName) {
-        Preconditions.checkStringNotEmpty(interfaceName);
+        if (TextUtils.isEmpty(interfaceName)) {
+            throw new IllegalArgumentException();
+        }
         mInterfaceName = interfaceName;
     }
 
diff --git a/core/java/android/net/IInternalNetworkManagementListener.aidl b/packages/ConnectivityT/framework-t/src/android/net/IInternalNetworkManagementListener.aidl
similarity index 100%
rename from core/java/android/net/IInternalNetworkManagementListener.aidl
rename to packages/ConnectivityT/framework-t/src/android/net/IInternalNetworkManagementListener.aidl
diff --git a/packages/ConnectivityT/framework-t/src/android/net/INetworkStatsService.aidl b/packages/ConnectivityT/framework-t/src/android/net/INetworkStatsService.aidl
index 12937b5..efe626d 100644
--- a/packages/ConnectivityT/framework-t/src/android/net/INetworkStatsService.aidl
+++ b/packages/ConnectivityT/framework-t/src/android/net/INetworkStatsService.aidl
@@ -24,6 +24,7 @@
 import android.net.NetworkStatsHistory;
 import android.net.NetworkTemplate;
 import android.net.UnderlyingNetworkInfo;
+import android.net.netstats.IUsageCallback;
 import android.net.netstats.provider.INetworkStatsProvider;
 import android.net.netstats.provider.INetworkStatsProviderCallback;
 import android.os.IBinder;
@@ -49,14 +50,8 @@
     @UnsupportedAppUsage
     NetworkStats getDataLayerSnapshotForUid(int uid);
 
-    /** Get a detailed snapshot of stats since boot for all UIDs.
-    *
-    * <p>Results will not always be limited to stats on requiredIfaces when specified: stats for
-    * interfaces stacked on the specified interfaces, or for interfaces on which the specified
-    * interfaces are stacked on, will also be included.
-    * @param requiredIfaces Interface names to get data for, or {@link NetworkStats#INTERFACES_ALL}.
-    */
-    NetworkStats getDetailedUidStats(in String[] requiredIfaces);
+    /** Get the transport NetworkStats for all UIDs since boot. */
+    NetworkStats getUidStatsForTransport(int transport);
 
     /** Return set of any ifaces associated with mobile networks since boot. */
     @UnsupportedAppUsage
@@ -77,7 +72,7 @@
 
     /** Registers a callback on data usage. */
     DataUsageRequest registerUsageCallback(String callingPackage,
-            in DataUsageRequest request, in Messenger messenger, in IBinder binder);
+            in DataUsageRequest request, in IUsageCallback callback);
 
     /** Unregisters a callback on data usage. */
     void unregisterUsageRequest(in DataUsageRequest request);
@@ -94,4 +89,16 @@
     /** Registers a network stats provider */
     INetworkStatsProviderCallback registerNetworkStatsProvider(String tag,
             in INetworkStatsProvider provider);
+
+    /** Mark given UID as being in foreground for stats purposes. */
+    void setUidForeground(int uid, boolean uidForeground);
+
+    /** Advise persistence threshold; may be overridden internally. */
+    void advisePersistThreshold(long thresholdBytes);
+
+    /**
+     * Set the warning and limit to all registered custom network stats providers.
+     * Note that invocation of any interface will be sent to all providers.
+     */
+     void setStatsProviderWarningAndLimitAsync(String iface, long warning, long limit);
 }
diff --git a/packages/ConnectivityT/framework-t/src/android/net/INetworkStatsSession.aidl b/packages/ConnectivityT/framework-t/src/android/net/INetworkStatsSession.aidl
index dfedf66..ab70be8 100644
--- a/packages/ConnectivityT/framework-t/src/android/net/INetworkStatsSession.aidl
+++ b/packages/ConnectivityT/framework-t/src/android/net/INetworkStatsSession.aidl
@@ -32,6 +32,11 @@
     /** Return historical network layer stats for traffic that matches template. */
     @UnsupportedAppUsage
     NetworkStatsHistory getHistoryForNetwork(in NetworkTemplate template, int fields);
+    /**
+     * Return historical network layer stats for traffic that matches template, start and end
+     * timestamp.
+     */
+    NetworkStatsHistory getHistoryIntervalForNetwork(in NetworkTemplate template, int fields, long start, long end);
 
     /**
      * Return network layer usage summary per UID for traffic that matches template.
@@ -46,6 +51,10 @@
      */
     @UnsupportedAppUsage
     NetworkStats getSummaryForAllUid(in NetworkTemplate template, long start, long end, boolean includeTags);
+
+    /** Return network layer usage summary per UID for tagged traffic that matches template. */
+    NetworkStats getTaggedSummaryForAllUid(in NetworkTemplate template, long start, long end);
+
     /** Return historical network layer stats for specific UID traffic that matches template. */
     @UnsupportedAppUsage
     NetworkStatsHistory getHistoryForUid(in NetworkTemplate template, int uid, int set, int tag, int fields);
diff --git a/core/java/android/net/InternalNetworkManagementException.aidl b/packages/ConnectivityT/framework-t/src/android/net/InternalNetworkManagementException.aidl
similarity index 100%
rename from core/java/android/net/InternalNetworkManagementException.aidl
rename to packages/ConnectivityT/framework-t/src/android/net/InternalNetworkManagementException.aidl
diff --git a/core/java/android/net/InternalNetworkManagementException.java b/packages/ConnectivityT/framework-t/src/android/net/InternalNetworkManagementException.java
similarity index 100%
rename from core/java/android/net/InternalNetworkManagementException.java
rename to packages/ConnectivityT/framework-t/src/android/net/InternalNetworkManagementException.java
diff --git a/core/java/android/net/InternalNetworkUpdateRequest.aidl b/packages/ConnectivityT/framework-t/src/android/net/InternalNetworkUpdateRequest.aidl
similarity index 100%
rename from core/java/android/net/InternalNetworkUpdateRequest.aidl
rename to packages/ConnectivityT/framework-t/src/android/net/InternalNetworkUpdateRequest.aidl
diff --git a/core/java/android/net/InternalNetworkUpdateRequest.java b/packages/ConnectivityT/framework-t/src/android/net/InternalNetworkUpdateRequest.java
similarity index 100%
rename from core/java/android/net/InternalNetworkUpdateRequest.java
rename to packages/ConnectivityT/framework-t/src/android/net/InternalNetworkUpdateRequest.java
diff --git a/packages/ConnectivityT/framework-t/src/android/net/IpSecAlgorithm.java b/packages/ConnectivityT/framework-t/src/android/net/IpSecAlgorithm.java
index a84e7a9..10a22ac 100644
--- a/packages/ConnectivityT/framework-t/src/android/net/IpSecAlgorithm.java
+++ b/packages/ConnectivityT/framework-t/src/android/net/IpSecAlgorithm.java
@@ -343,7 +343,7 @@
         // Load and validate the optional algorithm resource. Undefined or duplicate algorithms in
         // the resource are not allowed.
         final String[] resourceAlgos = systemResources.getStringArray(
-                com.android.internal.R.array.config_optionalIpSecAlgorithms);
+                android.R.array.config_optionalIpSecAlgorithms);
         for (String str : resourceAlgos) {
             if (!ALGO_TO_REQUIRED_FIRST_SDK.containsKey(str) || !enabledAlgos.add(str)) {
                 // This error should be caught by CTS and never be thrown to API callers
diff --git a/packages/ConnectivityT/framework-t/src/android/net/IpSecManager.java b/packages/ConnectivityT/framework-t/src/android/net/IpSecManager.java
index 0d15dff..a423783 100644
--- a/packages/ConnectivityT/framework-t/src/android/net/IpSecManager.java
+++ b/packages/ConnectivityT/framework-t/src/android/net/IpSecManager.java
@@ -17,6 +17,7 @@
 
 import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
 
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.RequiresFeature;
 import android.annotation.RequiresPermission;
@@ -25,8 +26,8 @@
 import android.annotation.TestApi;
 import android.content.Context;
 import android.content.pm.PackageManager;
-import android.net.annotations.PolicyDirection;
 import android.os.Binder;
+import android.os.IBinder;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
 import android.os.ServiceSpecificException;
@@ -41,6 +42,8 @@
 
 import java.io.FileDescriptor;
 import java.io.IOException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.net.DatagramSocket;
 import java.net.InetAddress;
 import java.net.Socket;
@@ -88,6 +91,11 @@
     @SystemApi(client = MODULE_LIBRARIES)
     public static final int DIRECTION_FWD = 2;
 
+    /** @hide */
+    @IntDef(value = {DIRECTION_IN, DIRECTION_OUT})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface PolicyDirection {}
+
     /**
      * The Security Parameter Index (SPI) 0 indicates an unknown or invalid index.
      *
@@ -981,6 +989,29 @@
     }
 
     /**
+     * @hide
+     */
+    public IpSecTransformResponse createTransform(IpSecConfig config, IBinder binder,
+            String callingPackage) {
+        try {
+            return mService.createTransform(config, binder, callingPackage);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @hide
+     */
+    public void deleteTransform(int resourceId) {
+        try {
+            mService.deleteTransform(resourceId);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Construct an instance of IpSecManager within an application context.
      *
      * @param context the application context for this manager
diff --git a/packages/ConnectivityT/framework-t/src/android/net/IpSecTransform.java b/packages/ConnectivityT/framework-t/src/android/net/IpSecTransform.java
index 36199a0..68ae5de 100644
--- a/packages/ConnectivityT/framework-t/src/android/net/IpSecTransform.java
+++ b/packages/ConnectivityT/framework-t/src/android/net/IpSecTransform.java
@@ -26,9 +26,6 @@
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.os.Binder;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.os.ServiceSpecificException;
 import android.util.Log;
 
@@ -93,16 +90,9 @@
         mResourceId = INVALID_RESOURCE_ID;
     }
 
-    private IIpSecService getIpSecService() {
-        IBinder b = ServiceManager.getService(android.content.Context.IPSEC_SERVICE);
-        if (b == null) {
-            throw new RemoteException("Failed to connect to IpSecService")
-                    .rethrowAsRuntimeException();
-        }
-
-        return IIpSecService.Stub.asInterface(b);
+    private IpSecManager getIpSecManager(Context context) {
+        return context.getSystemService(IpSecManager.class);
     }
-
     /**
      * Checks the result status and throws an appropriate exception if the status is not Status.OK.
      */
@@ -130,8 +120,7 @@
                     IpSecManager.SpiUnavailableException {
         synchronized (this) {
             try {
-                IIpSecService svc = getIpSecService();
-                IpSecTransformResponse result = svc.createTransform(
+                IpSecTransformResponse result = getIpSecManager(mContext).createTransform(
                         mConfig, new Binder(), mContext.getOpPackageName());
                 int status = result.status;
                 checkResultStatus(status);
@@ -140,8 +129,6 @@
                 mCloseGuard.open("build");
             } catch (ServiceSpecificException e) {
                 throw IpSecManager.rethrowUncheckedExceptionFromServiceSpecificException(e);
-            } catch (RemoteException e) {
-                throw e.rethrowAsRuntimeException();
             }
         }
 
@@ -177,10 +164,7 @@
             return;
         }
         try {
-            IIpSecService svc = getIpSecService();
-            svc.deleteTransform(mResourceId);
-        } catch (RemoteException e) {
-            throw e.rethrowAsRuntimeException();
+            getIpSecManager(mContext).deleteTransform(mResourceId);
         } catch (Exception e) {
             // On close we swallow all random exceptions since failure to close is not
             // actionable by the user.
diff --git a/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentity.java b/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentity.java
index 8f1115e..77fc171 100644
--- a/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentity.java
+++ b/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentity.java
@@ -16,18 +16,29 @@
 
 package android.net;
 
+import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
+import static android.net.ConnectivityManager.TYPE_MOBILE;
 import static android.net.ConnectivityManager.TYPE_WIFI;
+import static android.net.NetworkTemplate.NETWORK_TYPE_ALL;
 
+import android.annotation.IntDef;
+import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.SuppressLint;
+import android.annotation.SystemApi;
 import android.content.Context;
 import android.net.wifi.WifiInfo;
 import android.service.NetworkIdentityProto;
-import android.telephony.Annotation.NetworkType;
+import android.telephony.Annotation;
+import android.telephony.TelephonyManager;
 import android.util.proto.ProtoOutputStream;
 
+import com.android.net.module.util.CollectionUtils;
 import com.android.net.module.util.NetworkCapabilitiesUtils;
 import com.android.net.module.util.NetworkIdentityUtils;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.Objects;
 
@@ -37,11 +48,24 @@
  *
  * @hide
  */
-public class NetworkIdentity implements Comparable<NetworkIdentity> {
+@SystemApi(client = MODULE_LIBRARIES)
+public class NetworkIdentity {
     private static final String TAG = "NetworkIdentity";
 
+    /** @hide */
+    // TODO: Remove this after migrating all callers to use
+    //  {@link NetworkTemplate#NETWORK_TYPE_ALL} instead.
     public static final int SUBTYPE_COMBINED = -1;
 
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = { "OEM_MANAGED_" }, flag = true, value = {
+            NetworkTemplate.OEM_MANAGED_NO,
+            NetworkTemplate.OEM_MANAGED_PAID,
+            NetworkTemplate.OEM_MANAGED_PRIVATE
+    })
+    public @interface OemManaged{}
+
     /**
      * Network has no {@code NetworkCapabilities#NET_CAPABILITY_OEM_*}.
      * @hide
@@ -51,29 +75,32 @@
      * Network has {@link NetworkCapabilities#NET_CAPABILITY_OEM_PAID}.
      * @hide
      */
-    public static final int OEM_PAID = 0x1;
+    public static final int OEM_PAID = 1 << 0;
     /**
      * Network has {@link NetworkCapabilities#NET_CAPABILITY_OEM_PRIVATE}.
      * @hide
      */
-    public static final int OEM_PRIVATE = 0x2;
+    public static final int OEM_PRIVATE = 1 << 1;
+
+    private static final long SUPPORTED_OEM_MANAGED_TYPES = OEM_PAID | OEM_PRIVATE;
 
     final int mType;
-    final int mSubType;
+    final int mRatType;
     final String mSubscriberId;
-    final String mNetworkId;
+    final String mWifiNetworkKey;
     final boolean mRoaming;
     final boolean mMetered;
     final boolean mDefaultNetwork;
     final int mOemManaged;
 
+    /** @hide */
     public NetworkIdentity(
-            int type, int subType, String subscriberId, String networkId, boolean roaming,
-            boolean metered, boolean defaultNetwork, int oemManaged) {
+            int type, int ratType, @Nullable String subscriberId, @Nullable String wifiNetworkKey,
+            boolean roaming, boolean metered, boolean defaultNetwork, int oemManaged) {
         mType = type;
-        mSubType = subType;
+        mRatType = ratType;
         mSubscriberId = subscriberId;
-        mNetworkId = networkId;
+        mWifiNetworkKey = wifiNetworkKey;
         mRoaming = roaming;
         mMetered = metered;
         mDefaultNetwork = defaultNetwork;
@@ -82,7 +109,7 @@
 
     @Override
     public int hashCode() {
-        return Objects.hash(mType, mSubType, mSubscriberId, mNetworkId, mRoaming, mMetered,
+        return Objects.hash(mType, mRatType, mSubscriberId, mWifiNetworkKey, mRoaming, mMetered,
                 mDefaultNetwork, mOemManaged);
     }
 
@@ -90,9 +117,9 @@
     public boolean equals(@Nullable Object obj) {
         if (obj instanceof NetworkIdentity) {
             final NetworkIdentity ident = (NetworkIdentity) obj;
-            return mType == ident.mType && mSubType == ident.mSubType && mRoaming == ident.mRoaming
+            return mType == ident.mType && mRatType == ident.mRatType && mRoaming == ident.mRoaming
                     && Objects.equals(mSubscriberId, ident.mSubscriberId)
-                    && Objects.equals(mNetworkId, ident.mNetworkId)
+                    && Objects.equals(mWifiNetworkKey, ident.mWifiNetworkKey)
                     && mMetered == ident.mMetered
                     && mDefaultNetwork == ident.mDefaultNetwork
                     && mOemManaged == ident.mOemManaged;
@@ -104,18 +131,18 @@
     public String toString() {
         final StringBuilder builder = new StringBuilder("{");
         builder.append("type=").append(mType);
-        builder.append(", subType=");
-        if (mSubType == SUBTYPE_COMBINED) {
+        builder.append(", ratType=");
+        if (mRatType == NETWORK_TYPE_ALL) {
             builder.append("COMBINED");
         } else {
-            builder.append(mSubType);
+            builder.append(mRatType);
         }
         if (mSubscriberId != null) {
             builder.append(", subscriberId=")
                     .append(NetworkIdentityUtils.scrubSubscriberId(mSubscriberId));
         }
-        if (mNetworkId != null) {
-            builder.append(", networkId=").append(mNetworkId);
+        if (mWifiNetworkKey != null) {
+            builder.append(", wifiNetworkKey=").append(mWifiNetworkKey);
         }
         if (mRoaming) {
             builder.append(", ROAMING");
@@ -153,18 +180,14 @@
         }
     }
 
+    /** @hide */
     public void dumpDebug(ProtoOutputStream proto, long tag) {
         final long start = proto.start(tag);
 
         proto.write(NetworkIdentityProto.TYPE, mType);
 
-        // Not dumping mSubType, subtypes are no longer supported.
+        // TODO: dump mRatType as well.
 
-        if (mSubscriberId != null) {
-            proto.write(NetworkIdentityProto.SUBSCRIBER_ID,
-                    NetworkIdentityUtils.scrubSubscriberId(mSubscriberId));
-        }
-        proto.write(NetworkIdentityProto.NETWORK_ID, mNetworkId);
         proto.write(NetworkIdentityProto.ROAMING, mRoaming);
         proto.write(NetworkIdentityProto.METERED, mMetered);
         proto.write(NetworkIdentityProto.DEFAULT_NETWORK, mDefaultNetwork);
@@ -173,77 +196,99 @@
         proto.end(start);
     }
 
+    /** Get the network type of this instance. */
     public int getType() {
         return mType;
     }
 
-    public int getSubType() {
-        return mSubType;
+    /** Get the Radio Access Technology(RAT) type of this instance. */
+    public int getRatType() {
+        return mRatType;
     }
 
+    /** Get the Subscriber Id of this instance. */
+    @Nullable
     public String getSubscriberId() {
         return mSubscriberId;
     }
 
-    public String getNetworkId() {
-        return mNetworkId;
+    /** Get the Wifi Network Key of this instance. See {@link WifiInfo#getNetworkKey()}. */
+    @Nullable
+    public String getWifiNetworkKey() {
+        return mWifiNetworkKey;
     }
 
+    /** @hide */
+    // TODO: Remove this function after all callers are removed.
     public boolean getRoaming() {
         return mRoaming;
     }
 
+    /** Return whether this network is roaming. */
+    public boolean isRoaming() {
+        return mRoaming;
+    }
+
+    /** @hide */
+    // TODO: Remove this function after all callers are removed.
     public boolean getMetered() {
         return mMetered;
     }
 
+    /** Return whether this network is metered. */
+    public boolean isMetered() {
+        return mMetered;
+    }
+
+    /** @hide */
+    // TODO: Remove this function after all callers are removed.
     public boolean getDefaultNetwork() {
         return mDefaultNetwork;
     }
 
+    /** Return whether this network is the default network. */
+    public boolean isDefaultNetwork() {
+        return mDefaultNetwork;
+    }
+
+    /** Get the OEM managed type of this instance. */
     public int getOemManaged() {
         return mOemManaged;
     }
 
     /**
-     * Build a {@link NetworkIdentity} from the given {@link NetworkStateSnapshot} and
-     * {@code subType}, assuming that any mobile networks are using the current IMSI.
-     * The subType if applicable, should be set as one of the TelephonyManager.NETWORK_TYPE_*
-     * constants, or {@link android.telephony.TelephonyManager#NETWORK_TYPE_UNKNOWN} if not.
+     * Assemble a {@link NetworkIdentity} from the passed arguments.
+     *
+     * This methods builds an identity based on the capabilities of the network in the
+     * snapshot and other passed arguments. The identity is used as a key to record data usage.
+     *
+     * @param snapshot the snapshot of network state. See {@link NetworkStateSnapshot}.
+     * @param defaultNetwork whether the network is a default network.
+     * @param ratType the Radio Access Technology(RAT) type of the network. Or
+     *                {@link TelephonyManager#NETWORK_TYPE_UNKNOWN} if not applicable.
+     *                See {@code TelephonyManager.NETWORK_TYPE_*}.
+     * @hide
+     * @deprecated See {@link NetworkIdentity.Builder}.
      */
+    // TODO: Remove this after all callers are migrated to use new Api.
+    @Deprecated
+    @NonNull
     public static NetworkIdentity buildNetworkIdentity(Context context,
-            NetworkStateSnapshot snapshot, boolean defaultNetwork, @NetworkType int subType) {
-        final int legacyType = snapshot.getLegacyType();
-
-        final String subscriberId = snapshot.getSubscriberId();
-        String networkId = null;
-        boolean roaming = !snapshot.getNetworkCapabilities().hasCapability(
-                NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING);
-        boolean metered = !(snapshot.getNetworkCapabilities().hasCapability(
-                NetworkCapabilities.NET_CAPABILITY_NOT_METERED)
-                || snapshot.getNetworkCapabilities().hasCapability(
-                NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED));
-
-        final int oemManaged = getOemBitfield(snapshot.getNetworkCapabilities());
-
-        if (legacyType == TYPE_WIFI) {
-            final TransportInfo transportInfo = snapshot.getNetworkCapabilities()
-                    .getTransportInfo();
-            if (transportInfo instanceof WifiInfo) {
-                final WifiInfo info = (WifiInfo) transportInfo;
-                networkId = info != null ? info.getCurrentNetworkKey() : null;
-            }
+            @NonNull NetworkStateSnapshot snapshot,
+            boolean defaultNetwork, @Annotation.NetworkType int ratType) {
+        final NetworkIdentity.Builder builder = new NetworkIdentity.Builder()
+                .setNetworkStateSnapshot(snapshot).setDefaultNetwork(defaultNetwork);
+        if (snapshot.getLegacyType() == TYPE_MOBILE && ratType != NETWORK_TYPE_ALL) {
+            builder.setRatType(ratType);
         }
-
-        return new NetworkIdentity(legacyType, subType, subscriberId, networkId, roaming, metered,
-                defaultNetwork, oemManaged);
+        return builder.build();
     }
 
     /**
      * Builds a bitfield of {@code NetworkIdentity.OEM_*} based on {@link NetworkCapabilities}.
      * @hide
      */
-    public static int getOemBitfield(NetworkCapabilities nc) {
+    public static int getOemBitfield(@NonNull NetworkCapabilities nc) {
         int oemManaged = OEM_NONE;
 
         if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PAID)) {
@@ -256,30 +301,266 @@
         return oemManaged;
     }
 
-    @Override
-    public int compareTo(NetworkIdentity another) {
-        int res = Integer.compare(mType, another.mType);
+    /** @hide */
+    public static int compare(@NonNull NetworkIdentity left, @NonNull NetworkIdentity right) {
+        Objects.requireNonNull(right);
+        int res = Integer.compare(left.mType, right.mType);
         if (res == 0) {
-            res = Integer.compare(mSubType, another.mSubType);
+            res = Integer.compare(left.mRatType, right.mRatType);
         }
-        if (res == 0 && mSubscriberId != null && another.mSubscriberId != null) {
-            res = mSubscriberId.compareTo(another.mSubscriberId);
+        if (res == 0 && left.mSubscriberId != null && right.mSubscriberId != null) {
+            res = left.mSubscriberId.compareTo(right.mSubscriberId);
         }
-        if (res == 0 && mNetworkId != null && another.mNetworkId != null) {
-            res = mNetworkId.compareTo(another.mNetworkId);
+        if (res == 0 && left.mWifiNetworkKey != null && right.mWifiNetworkKey != null) {
+            res = left.mWifiNetworkKey.compareTo(right.mWifiNetworkKey);
         }
         if (res == 0) {
-            res = Boolean.compare(mRoaming, another.mRoaming);
+            res = Boolean.compare(left.mRoaming, right.mRoaming);
         }
         if (res == 0) {
-            res = Boolean.compare(mMetered, another.mMetered);
+            res = Boolean.compare(left.mMetered, right.mMetered);
         }
         if (res == 0) {
-            res = Boolean.compare(mDefaultNetwork, another.mDefaultNetwork);
+            res = Boolean.compare(left.mDefaultNetwork, right.mDefaultNetwork);
         }
         if (res == 0) {
-            res = Integer.compare(mOemManaged, another.mOemManaged);
+            res = Integer.compare(left.mOemManaged, right.mOemManaged);
         }
         return res;
     }
+
+    /**
+     * Builder class for {@link NetworkIdentity}.
+     */
+    public static final class Builder {
+        // Need to be synchronized with ConnectivityManager.
+        // TODO: Use {@link ConnectivityManager#MAX_NETWORK_TYPE} when this file is in the module.
+        private static final int MAX_NETWORK_TYPE = 18; // TYPE_TEST
+        private static final int MIN_NETWORK_TYPE = TYPE_MOBILE;
+
+        private int mType;
+        private int mRatType;
+        private String mSubscriberId;
+        private String mWifiNetworkKey;
+        private boolean mRoaming;
+        private boolean mMetered;
+        private boolean mDefaultNetwork;
+        private int mOemManaged;
+
+        /**
+         * Creates a new Builder.
+         */
+        public Builder() {
+            // Initialize with default values. Will be overwritten by setters.
+            mType = ConnectivityManager.TYPE_NONE;
+            mRatType = NetworkTemplate.NETWORK_TYPE_ALL;
+            mSubscriberId = null;
+            mWifiNetworkKey = null;
+            mRoaming = false;
+            mMetered = false;
+            mDefaultNetwork = false;
+            mOemManaged = NetworkTemplate.OEM_MANAGED_NO;
+        }
+
+        /**
+         * Add an {@link NetworkStateSnapshot} into the {@link NetworkIdentity} instance.
+         * This is a useful shorthand that will read from the snapshot and set the
+         * following fields, if they are set in the snapshot :
+         *  - type
+         *  - subscriberId
+         *  - roaming
+         *  - metered
+         *  - oemManaged
+         *  - wifiNetworkKey
+         *
+         * @param snapshot The target {@link NetworkStateSnapshot} object.
+         * @return The builder object.
+         */
+        @SuppressLint("MissingGetterMatchingBuilder")
+        @NonNull
+        public Builder setNetworkStateSnapshot(@NonNull NetworkStateSnapshot snapshot) {
+            setType(snapshot.getLegacyType());
+
+            setSubscriberId(snapshot.getSubscriberId());
+            setRoaming(!snapshot.getNetworkCapabilities().hasCapability(
+                    NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING));
+            setMetered(!(snapshot.getNetworkCapabilities().hasCapability(
+                    NetworkCapabilities.NET_CAPABILITY_NOT_METERED)
+                    || snapshot.getNetworkCapabilities().hasCapability(
+                    NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED)));
+
+            setOemManaged(getOemBitfield(snapshot.getNetworkCapabilities()));
+
+            if (mType == TYPE_WIFI) {
+                final TransportInfo transportInfo = snapshot.getNetworkCapabilities()
+                        .getTransportInfo();
+                if (transportInfo instanceof WifiInfo) {
+                    final WifiInfo info = (WifiInfo) transportInfo;
+                    setWifiNetworkKey(info.getNetworkKey());
+                }
+            }
+            return this;
+        }
+
+        /**
+         * Set the network type of the network.
+         *
+         * @param type the network type. See {@link ConnectivityManager#TYPE_*}.
+         *
+         * @return this builder.
+         */
+        @NonNull
+        public Builder setType(int type) {
+            // Include TYPE_NONE for compatibility, type field might not be filled by some
+            // networks such as test networks.
+            if ((type < MIN_NETWORK_TYPE || MAX_NETWORK_TYPE < type)
+                    && type != ConnectivityManager.TYPE_NONE) {
+                throw new IllegalArgumentException("Invalid network type: " + type);
+            }
+            mType = type;
+            return this;
+        }
+
+        /**
+         * Set the Radio Access Technology(RAT) type of the network.
+         *
+         * No RAT type is specified by default. Call clearRatType to reset.
+         *
+         * @param ratType the Radio Access Technology(RAT) type if applicable. See
+         *                {@code TelephonyManager.NETWORK_TYPE_*}.
+         *
+         * @return this builder.
+         */
+        @NonNull
+        public Builder setRatType(@Annotation.NetworkType int ratType) {
+            if (!CollectionUtils.contains(TelephonyManager.getAllNetworkTypes(), ratType)
+                    && ratType != TelephonyManager.NETWORK_TYPE_UNKNOWN
+                    && ratType != NetworkTemplate.NETWORK_TYPE_5G_NSA) {
+                throw new IllegalArgumentException("Invalid ratType " + ratType);
+            }
+            mRatType = ratType;
+            return this;
+        }
+
+        /**
+         * Clear the Radio Access Technology(RAT) type of the network.
+         *
+         * @return this builder.
+         */
+        @NonNull
+        public Builder clearRatType() {
+            mRatType = NetworkTemplate.NETWORK_TYPE_ALL;
+            return this;
+        }
+
+        /**
+         * Set the Subscriber Id.
+         *
+         * @param subscriberId the Subscriber Id of the network. Or null if not applicable.
+         * @return this builder.
+         */
+        @NonNull
+        public Builder setSubscriberId(@Nullable String subscriberId) {
+            mSubscriberId = subscriberId;
+            return this;
+        }
+
+        /**
+         * Set the Wifi Network Key.
+         *
+         * @param wifiNetworkKey Wifi Network Key of the network,
+         *                        see {@link WifiInfo#getNetworkKey()}.
+         *                        Or null if not applicable.
+         * @return this builder.
+         */
+        @NonNull
+        public Builder setWifiNetworkKey(@Nullable String wifiNetworkKey) {
+            mWifiNetworkKey = wifiNetworkKey;
+            return this;
+        }
+
+        /**
+         * Set whether this network is roaming.
+         *
+         * This field is false by default. Call with false to reset.
+         *
+         * @param roaming the roaming status of the network.
+         * @return this builder.
+         */
+        @NonNull
+        public Builder setRoaming(boolean roaming) {
+            mRoaming = roaming;
+            return this;
+        }
+
+        /**
+         * Set whether this network is metered.
+         *
+         * This field is false by default. Call with false to reset.
+         *
+         * @param metered the meteredness of the network.
+         * @return this builder.
+         */
+        @NonNull
+        public Builder setMetered(boolean metered) {
+            mMetered = metered;
+            return this;
+        }
+
+        /**
+         * Set whether this network is the default network.
+         *
+         * This field is false by default. Call with false to reset.
+         *
+         * @param defaultNetwork the default network status of the network.
+         * @return this builder.
+         */
+        @NonNull
+        public Builder setDefaultNetwork(boolean defaultNetwork) {
+            mDefaultNetwork = defaultNetwork;
+            return this;
+        }
+
+        /**
+         * Set the OEM managed type.
+         *
+         * @param oemManaged Type of OEM managed network or unmanaged networks.
+         *                   See {@code NetworkTemplate#OEM_MANAGED_*}.
+         * @return this builder.
+         */
+        @NonNull
+        public Builder setOemManaged(@OemManaged int oemManaged) {
+            // Assert input does not contain illegal oemManage bits.
+            if ((~SUPPORTED_OEM_MANAGED_TYPES & oemManaged) != 0) {
+                throw new IllegalArgumentException("Invalid value for OemManaged : " + oemManaged);
+            }
+            mOemManaged = oemManaged;
+            return this;
+        }
+
+        private void ensureValidParameters() {
+            // Assert non-mobile network cannot have a ratType.
+            if (mType != TYPE_MOBILE && mRatType != NetworkTemplate.NETWORK_TYPE_ALL) {
+                throw new IllegalArgumentException(
+                        "Invalid ratType " + mRatType + " for type " + mType);
+            }
+
+            // Assert non-wifi network cannot have a wifi network key.
+            if (mType != TYPE_WIFI && mWifiNetworkKey != null) {
+                throw new IllegalArgumentException("Invalid wifi network key for type " + mType);
+            }
+        }
+
+        /**
+         * Builds the instance of the {@link NetworkIdentity}.
+         *
+         * @return the built instance of {@link NetworkIdentity}.
+         */
+        @NonNull
+        public NetworkIdentity build() {
+            ensureValidParameters();
+            return new NetworkIdentity(mType, mRatType, mSubscriberId, mWifiNetworkKey,
+                    mRoaming, mMetered, mDefaultNetwork, mOemManaged);
+        }
+    }
 }
diff --git a/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentitySet.java b/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentitySet.java
index abbebef..dfa347f 100644
--- a/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentitySet.java
+++ b/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentitySet.java
@@ -18,6 +18,7 @@
 
 import static android.net.ConnectivityManager.TYPE_MOBILE;
 
+import android.annotation.NonNull;
 import android.service.NetworkIdentitySetProto;
 import android.util.proto.ProtoOutputStream;
 
@@ -25,6 +26,8 @@
 import java.io.DataOutput;
 import java.io.IOException;
 import java.util.HashSet;
+import java.util.Objects;
+import java.util.Set;
 
 /**
  * Identity of a {@code iface}, defined by the set of {@link NetworkIdentity}
@@ -32,8 +35,7 @@
  *
  * @hide
  */
-public class NetworkIdentitySet extends HashSet<NetworkIdentity> implements
-        Comparable<NetworkIdentitySet> {
+public class NetworkIdentitySet extends HashSet<NetworkIdentity> {
     private static final int VERSION_INIT = 1;
     private static final int VERSION_ADD_ROAMING = 2;
     private static final int VERSION_ADD_NETWORK_ID = 3;
@@ -41,9 +43,19 @@
     private static final int VERSION_ADD_DEFAULT_NETWORK = 5;
     private static final int VERSION_ADD_OEM_MANAGED_NETWORK = 6;
 
+    /**
+     * Construct a {@link NetworkIdentitySet} object.
+     */
     public NetworkIdentitySet() {
+        super();
     }
 
+    /** @hide */
+    public NetworkIdentitySet(@NonNull Set<NetworkIdentity> ident) {
+        super(ident);
+    }
+
+    /** @hide */
     public NetworkIdentitySet(DataInput in) throws IOException {
         final int version = in.readInt();
         final int size = in.readInt();
@@ -52,7 +64,7 @@
                 final int ignored = in.readInt();
             }
             final int type = in.readInt();
-            final int subType = in.readInt();
+            final int ratType = in.readInt();
             final String subscriberId = readOptionalString(in);
             final String networkId;
             if (version >= VERSION_ADD_NETWORK_ID) {
@@ -91,63 +103,73 @@
                 oemNetCapabilities = NetworkIdentity.OEM_NONE;
             }
 
-            add(new NetworkIdentity(type, subType, subscriberId, networkId, roaming, metered,
+            add(new NetworkIdentity(type, ratType, subscriberId, networkId, roaming, metered,
                     defaultNetwork, oemNetCapabilities));
         }
     }
 
     /**
      * Method to serialize this object into a {@code DataOutput}.
+     * @hide
      */
     public void writeToStream(DataOutput out) throws IOException {
         out.writeInt(VERSION_ADD_OEM_MANAGED_NETWORK);
         out.writeInt(size());
         for (NetworkIdentity ident : this) {
             out.writeInt(ident.getType());
-            out.writeInt(ident.getSubType());
+            out.writeInt(ident.getRatType());
             writeOptionalString(out, ident.getSubscriberId());
-            writeOptionalString(out, ident.getNetworkId());
-            out.writeBoolean(ident.getRoaming());
-            out.writeBoolean(ident.getMetered());
-            out.writeBoolean(ident.getDefaultNetwork());
+            writeOptionalString(out, ident.getWifiNetworkKey());
+            out.writeBoolean(ident.isRoaming());
+            out.writeBoolean(ident.isMetered());
+            out.writeBoolean(ident.isDefaultNetwork());
             out.writeInt(ident.getOemManaged());
         }
     }
 
-    /** @return whether any {@link NetworkIdentity} in this set is considered metered. */
+    /**
+     * @return whether any {@link NetworkIdentity} in this set is considered metered.
+     * @hide
+     */
     public boolean isAnyMemberMetered() {
         if (isEmpty()) {
             return false;
         }
         for (NetworkIdentity ident : this) {
-            if (ident.getMetered()) {
+            if (ident.isMetered()) {
                 return true;
             }
         }
         return false;
     }
 
-    /** @return whether any {@link NetworkIdentity} in this set is considered roaming. */
+    /**
+     * @return whether any {@link NetworkIdentity} in this set is considered roaming.
+     * @hide
+     */
     public boolean isAnyMemberRoaming() {
         if (isEmpty()) {
             return false;
         }
         for (NetworkIdentity ident : this) {
-            if (ident.getRoaming()) {
+            if (ident.isRoaming()) {
                 return true;
             }
         }
         return false;
     }
 
-    /** @return whether any {@link NetworkIdentity} in this set is considered on the default
-            network. */
+    /**
+     * @return whether any {@link NetworkIdentity} in this set is considered on the default
+     *         network.
+     * @hide
+     */
     public boolean areAllMembersOnDefaultNetwork() {
         if (isEmpty()) {
             return true;
         }
         for (NetworkIdentity ident : this) {
-            if (!ident.getDefaultNetwork()) {
+            if (!ident.isDefaultNetwork()) {
                 return false;
             }
         }
@@ -171,18 +193,20 @@
         }
     }
 
-    @Override
-    public int compareTo(NetworkIdentitySet another) {
-        if (isEmpty()) return -1;
-        if (another.isEmpty()) return 1;
+    public static int compare(@NonNull NetworkIdentitySet left, @NonNull NetworkIdentitySet right) {
+        Objects.requireNonNull(left);
+        Objects.requireNonNull(right);
+        if (left.isEmpty()) return -1;
+        if (right.isEmpty()) return 1;
 
-        final NetworkIdentity ident = iterator().next();
-        final NetworkIdentity anotherIdent = another.iterator().next();
-        return ident.compareTo(anotherIdent);
+        final NetworkIdentity leftIdent = left.iterator().next();
+        final NetworkIdentity rightIdent = right.iterator().next();
+        return NetworkIdentity.compare(leftIdent, rightIdent);
     }
 
     /**
      * Method to dump this object into proto debug file.
+     * @hide
      */
     public void dumpDebug(ProtoOutputStream proto, long tag) {
         final long start = proto.start(tag);
diff --git a/packages/ConnectivityT/framework-t/src/android/net/NetworkStats.java b/packages/ConnectivityT/framework-t/src/android/net/NetworkStats.java
index b00fea4..9175809 100644
--- a/packages/ConnectivityT/framework-t/src/android/net/NetworkStats.java
+++ b/packages/ConnectivityT/framework-t/src/android/net/NetworkStats.java
@@ -41,6 +41,7 @@
 import java.lang.annotation.RetentionPolicy;
 import java.util.Arrays;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
@@ -57,7 +58,7 @@
  */
 // @NotThreadSafe
 @SystemApi
-public final class NetworkStats implements Parcelable {
+public final class NetworkStats implements Parcelable, Iterable<NetworkStats.Entry> {
     private static final String TAG = "NetworkStats";
 
     /**
@@ -383,6 +384,95 @@
             this.operations += another.operations;
         }
 
+        /**
+         * @return interface name of this entry.
+         * @hide
+         */
+        @Nullable public String getIface() {
+            return iface;
+        }
+
+        /**
+         * @return the uid of this entry.
+         */
+        public int getUid() {
+            return uid;
+        }
+
+        /**
+         * @return the set state of this entry. Should be one of the following
+         * values: {@link #SET_DEFAULT}, {@link #SET_FOREGROUND}.
+         */
+        @State public int getSet() {
+            return set;
+        }
+
+        /**
+         * @return the tag value of this entry.
+         */
+        public int getTag() {
+            return tag;
+        }
+
+        /**
+         * @return the metered state. Should be one of the following
+         * values: {link #METERED_YES}, {link #METERED_NO}.
+         */
+        @Meteredness public int getMetered() {
+            return metered;
+        }
+
+        /**
+         * @return the roaming state. Should be one of the following
+         * values: {link #ROAMING_YES}, {link #ROAMING_NO}.
+         */
+        @Roaming public int getRoaming() {
+            return roaming;
+        }
+
+        /**
+         * @return the default network state. Should be one of the following
+         * values: {link #DEFAULT_NETWORK_YES}, {link #DEFAULT_NETWORK_NO}.
+         */
+        @DefaultNetwork public int getDefaultNetwork() {
+            return defaultNetwork;
+        }
+
+        /**
+         * @return the number of received bytes.
+         */
+        public long getRxBytes() {
+            return rxBytes;
+        }
+
+        /**
+         * @return the number of received packets.
+         */
+        public long getRxPackets() {
+            return rxPackets;
+        }
+
+        /**
+         * @return the number of transmitted bytes.
+         */
+        public long getTxBytes() {
+            return txBytes;
+        }
+
+        /**
+         * @return the number of transmitted packets.
+         */
+        public long getTxPackets() {
+            return txPackets;
+        }
+
+        /**
+         * @return the count of network operations performed for this entry.
+         */
+        public long getOperations() {
+            return operations;
+        }
+
         @Override
         public String toString() {
             final StringBuilder builder = new StringBuilder();
@@ -589,11 +679,40 @@
     }
 
     /**
+     * Iterate over Entry objects.
+     *
+     * Return an iterator of this object that will iterate through all contained Entry objects.
+     *
+     * This iterator does not support concurrent modification and makes no guarantee of fail-fast
+     * behavior. If any method that can mutate the contents of this object is called while
+     * iteration is in progress, either inside the loop or in another thread, then behavior is
+     * undefined.
+     * The remove() method is not implemented and will throw UnsupportedOperationException.
+     * @hide
+     */
+    @SystemApi
+    @NonNull public Iterator<Entry> iterator() {
+        return new Iterator<Entry>() {
+            int mIndex = 0;
+
+            @Override
+            public boolean hasNext() {
+                return mIndex < size;
+            }
+
+            @Override
+            public Entry next() {
+                return getValues(mIndex++, null);
+            }
+        };
+    }
+
+    /**
      * Return specific stats entry.
      * @hide
      */
     @UnsupportedAppUsage
-    public Entry getValues(int i, Entry recycle) {
+    public Entry getValues(int i, @Nullable Entry recycle) {
         final Entry entry = recycle != null ? recycle : new Entry();
         entry.iface = iface[i];
         entry.uid = uid[i];
diff --git a/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsCollection.java b/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsCollection.java
index 7935d28..735c44d 100644
--- a/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsCollection.java
+++ b/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsCollection.java
@@ -16,6 +16,7 @@
 
 package android.net;
 
+import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
 import static android.net.NetworkStats.DEFAULT_NETWORK_NO;
 import static android.net.NetworkStats.DEFAULT_NETWORK_YES;
 import static android.net.NetworkStats.IFACE_ALL;
@@ -32,6 +33,10 @@
 
 import static com.android.net.module.util.NetworkStatsUtils.multiplySafeByRational;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.net.NetworkStatsHistory.Entry;
 import android.os.Binder;
 import android.service.NetworkStatsCollectionKeyProto;
 import android.service.NetworkStatsCollectionProto;
@@ -46,8 +51,6 @@
 import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.FastDataInput;
-import com.android.internal.util.FastDataOutput;
 import com.android.internal.util.FileRotator;
 import com.android.net.module.util.CollectionUtils;
 import com.android.net.module.util.NetworkStatsUtils;
@@ -58,6 +61,7 @@
 import java.io.DataInput;
 import java.io.DataInputStream;
 import java.io.DataOutput;
+import java.io.DataOutputStream;
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.IOException;
@@ -70,7 +74,10 @@
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
 import java.util.Objects;
+import java.util.Set;
 
 /**
  * Collection of {@link NetworkStatsHistory}, stored based on combined key of
@@ -78,14 +85,12 @@
  *
  * @hide
  */
+@SystemApi(client = MODULE_LIBRARIES)
 public class NetworkStatsCollection implements FileRotator.Reader, FileRotator.Writer {
     private static final String TAG = NetworkStatsCollection.class.getSimpleName();
     /** File header magic number: "ANET" */
     private static final int FILE_MAGIC = 0x414E4554;
 
-    /** Default buffer size from BufferedInputStream */
-    private static final int BUFFER_SIZE = 8192;
-
     private static final int VERSION_NETWORK_INIT = 1;
 
     private static final int VERSION_UID_INIT = 1;
@@ -104,15 +109,23 @@
     private long mTotalBytes;
     private boolean mDirty;
 
+    /**
+     * Construct a {@link NetworkStatsCollection} object.
+     *
+     * @param bucketDuration duration of the buckets in this object, in milliseconds.
+     * @hide
+     */
     public NetworkStatsCollection(long bucketDuration) {
         mBucketDuration = bucketDuration;
         reset();
     }
 
+    /** @hide */
     public void clear() {
         reset();
     }
 
+    /** @hide */
     public void reset() {
         mStats.clear();
         mStartMillis = Long.MAX_VALUE;
@@ -121,6 +134,7 @@
         mDirty = false;
     }
 
+    /** @hide */
     public long getStartMillis() {
         return mStartMillis;
     }
@@ -128,6 +142,7 @@
     /**
      * Return first atomic bucket in this collection, which is more conservative
      * than {@link #mStartMillis}.
+     * @hide
      */
     public long getFirstAtomicBucketMillis() {
         if (mStartMillis == Long.MAX_VALUE) {
@@ -137,26 +152,32 @@
         }
     }
 
+    /** @hide */
     public long getEndMillis() {
         return mEndMillis;
     }
 
+    /** @hide */
     public long getTotalBytes() {
         return mTotalBytes;
     }
 
+    /** @hide */
     public boolean isDirty() {
         return mDirty;
     }
 
+    /** @hide */
     public void clearDirty() {
         mDirty = false;
     }
 
+    /** @hide */
     public boolean isEmpty() {
         return mStartMillis == Long.MAX_VALUE && mEndMillis == Long.MIN_VALUE;
     }
 
+    /** @hide */
     @VisibleForTesting
     public long roundUp(long time) {
         if (time == Long.MIN_VALUE || time == Long.MAX_VALUE
@@ -172,6 +193,7 @@
         }
     }
 
+    /** @hide */
     @VisibleForTesting
     public long roundDown(long time) {
         if (time == Long.MIN_VALUE || time == Long.MAX_VALUE
@@ -186,10 +208,12 @@
         }
     }
 
+    /** @hide */
     public int[] getRelevantUids(@NetworkStatsAccess.Level int accessLevel) {
         return getRelevantUids(accessLevel, Binder.getCallingUid());
     }
 
+    /** @hide */
     public int[] getRelevantUids(@NetworkStatsAccess.Level int accessLevel,
                 final int callerUid) {
         final ArrayList<Integer> uids = new ArrayList<>();
@@ -210,6 +234,7 @@
     /**
      * Combine all {@link NetworkStatsHistory} in this collection which match
      * the requested parameters.
+     * @hide
      */
     public NetworkStatsHistory getHistory(NetworkTemplate template, SubscriptionPlan augmentPlan,
             int uid, int set, int tag, int fields, long start, long end,
@@ -335,6 +360,7 @@
      * @param end - end of the range, timestamp in milliseconds since the epoch.
      * @param accessLevel - caller access level.
      * @param callerUid - caller UID.
+     * @hide
      */
     public NetworkStats getSummary(NetworkTemplate template, long start, long end,
             @NetworkStatsAccess.Level int accessLevel, int callerUid) {
@@ -381,6 +407,7 @@
 
     /**
      * Record given {@link android.net.NetworkStats.Entry} into this collection.
+     * @hide
      */
     public void recordData(NetworkIdentitySet ident, int uid, int set, int tag, long start,
             long end, NetworkStats.Entry entry) {
@@ -391,8 +418,12 @@
 
     /**
      * Record given {@link NetworkStatsHistory} into this collection.
+     *
+     * @hide
      */
-    private void recordHistory(Key key, NetworkStatsHistory history) {
+    public void recordHistory(@NonNull Key key, @NonNull NetworkStatsHistory history) {
+        Objects.requireNonNull(key);
+        Objects.requireNonNull(history);
         if (history.size() == 0) return;
         noteRecordedHistory(history.getStart(), history.getEnd(), history.getTotalBytes());
 
@@ -407,8 +438,11 @@
     /**
      * Record all {@link NetworkStatsHistory} contained in the given collection
      * into this collection.
+     *
+     * @hide
      */
-    public void recordCollection(NetworkStatsCollection another) {
+    public void recordCollection(@NonNull NetworkStatsCollection another) {
+        Objects.requireNonNull(another);
         for (int i = 0; i < another.mStats.size(); i++) {
             final Key key = another.mStats.keyAt(i);
             final NetworkStatsHistory value = another.mStats.valueAt(i);
@@ -437,10 +471,10 @@
         }
     }
 
+    /** @hide */
     @Override
     public void read(InputStream in) throws IOException {
-        final FastDataInput dataIn = new FastDataInput(in, BUFFER_SIZE);
-        read(dataIn);
+        read((DataInput) new DataInputStream(in));
     }
 
     private void read(DataInput in) throws IOException {
@@ -477,11 +511,11 @@
         }
     }
 
+    /** @hide */
     @Override
     public void write(OutputStream out) throws IOException {
-        final FastDataOutput dataOut = new FastDataOutput(out, BUFFER_SIZE);
-        write(dataOut);
-        dataOut.flush();
+        write((DataOutput) new DataOutputStream(out));
+        out.flush();
     }
 
     private void write(DataOutput out) throws IOException {
@@ -520,6 +554,7 @@
      * See {@code NetworkStatsService#maybeUpgradeLegacyStatsLocked}.
      *
      * @deprecated
+     * @hide
      */
     @Deprecated
     public void readLegacyNetwork(File file) throws IOException {
@@ -565,6 +600,7 @@
      * See {@code NetworkStatsService#maybeUpgradeLegacyStatsLocked}.
      *
      * @deprecated
+     * @hide
      */
     @Deprecated
     public void readLegacyUid(File file, boolean onlyTags) throws IOException {
@@ -635,6 +671,7 @@
      * Remove any {@link NetworkStatsHistory} attributed to the requested UID,
      * moving any {@link NetworkStats#TAG_NONE} series to
      * {@link TrafficStats#UID_REMOVED}.
+     * @hide
      */
     public void removeUids(int[] uids) {
         final ArrayList<Key> knownKeys = new ArrayList<>();
@@ -671,10 +708,11 @@
     private ArrayList<Key> getSortedKeys() {
         final ArrayList<Key> keys = new ArrayList<>();
         keys.addAll(mStats.keySet());
-        Collections.sort(keys);
+        Collections.sort(keys, (left, right) -> Key.compare(left, right));
         return keys;
     }
 
+    /** @hide */
     public void dump(IndentingPrintWriter pw) {
         for (Key key : getSortedKeys()) {
             pw.print("ident="); pw.print(key.ident.toString());
@@ -689,6 +727,7 @@
         }
     }
 
+    /** @hide */
     public void dumpDebug(ProtoOutputStream proto, long tag) {
         final long start = proto.start(tag);
 
@@ -712,6 +751,7 @@
         proto.end(start);
     }
 
+    /** @hide */
     public void dumpCheckin(PrintWriter pw, long start, long end) {
         dumpCheckin(pw, start, end, NetworkTemplate.buildTemplateMobileWildcard(), "cell");
         dumpCheckin(pw, start, end, NetworkTemplate.buildTemplateWifiWildcard(), "wifi");
@@ -774,16 +814,102 @@
         return false;
     }
 
-    private static class Key implements Comparable<Key> {
+    /**
+     * Get the all historical stats of the collection {@link NetworkStatsCollection}.
+     *
+     * @return All {@link NetworkStatsHistory} in this collection.
+     */
+    @NonNull
+    public Map<Key, NetworkStatsHistory> getEntries() {
+        return new ArrayMap(mStats);
+    }
+
+    /**
+     * Builder class for {@link NetworkStatsCollection}.
+     */
+    public static final class Builder {
+        private final long mBucketDuration;
+        private final ArrayMap<Key, NetworkStatsHistory> mEntries = new ArrayMap<>();
+
+        /**
+         * Creates a new Builder with given bucket duration.
+         *
+         * @param bucketDuration Duration of the buckets of the object, in milliseconds.
+         */
+        public Builder(long bucketDuration) {
+            mBucketDuration = bucketDuration;
+        }
+
+        /**
+         * Add association of the history with the specified key in this map.
+         *
+         * @param key The object used to identify a network, see {@link Key}.
+         * @param history {@link NetworkStatsHistory} instance associated to the given {@link Key}.
+         * @return The builder object.
+         */
+        @NonNull
+        public NetworkStatsCollection.Builder addEntry(@NonNull Key key,
+                @NonNull NetworkStatsHistory history) {
+            Objects.requireNonNull(key);
+            Objects.requireNonNull(history);
+            final List<Entry> historyEntries = history.getEntries();
+
+            final NetworkStatsHistory.Builder historyBuilder =
+                    new NetworkStatsHistory.Builder(mBucketDuration, historyEntries.size());
+            for (Entry entry : historyEntries) {
+                historyBuilder.addEntry(entry);
+            }
+
+            mEntries.put(key, historyBuilder.build());
+            return this;
+        }
+
+        /**
+         * Builds the instance of the {@link NetworkStatsCollection}.
+         *
+         * @return the built instance of {@link NetworkStatsCollection}.
+         */
+        @NonNull
+        public NetworkStatsCollection build() {
+            final NetworkStatsCollection collection = new NetworkStatsCollection(mBucketDuration);
+            for (int i = 0; i < mEntries.size(); i++) {
+                collection.recordHistory(mEntries.keyAt(i), mEntries.valueAt(i));
+            }
+            return collection;
+        }
+    }
+
+    /**
+     * the identifier that associate with the {@link NetworkStatsHistory} object to identify
+     * a certain record in the {@link NetworkStatsCollection} object.
+     */
+    public static class Key {
+        /** @hide */
         public final NetworkIdentitySet ident;
+        /** @hide */
         public final int uid;
+        /** @hide */
         public final int set;
+        /** @hide */
         public final int tag;
 
         private final int mHashCode;
 
-        Key(NetworkIdentitySet ident, int uid, int set, int tag) {
-            this.ident = ident;
+        /**
+         * Construct a {@link Key} object.
+         *
+         * @param ident a Set of {@link NetworkIdentity} that associated with the record.
+         * @param uid Uid of the record.
+         * @param set Set of the record, see {@code NetworkStats#SET_*}.
+         * @param tag Tag of the record, see {@link TrafficStats#setThreadStatsTag(int)}.
+         */
+        public Key(@NonNull Set<NetworkIdentity> ident, int uid, int set, int tag) {
+            this(new NetworkIdentitySet(Objects.requireNonNull(ident)), uid, set, tag);
+        }
+
+        /** @hide */
+        public Key(@NonNull NetworkIdentitySet ident, int uid, int set, int tag) {
+            this.ident = Objects.requireNonNull(ident);
             this.uid = uid;
             this.set = set;
             this.tag = tag;
@@ -796,7 +922,7 @@
         }
 
         @Override
-        public boolean equals(Object obj) {
+        public boolean equals(@Nullable Object obj) {
             if (obj instanceof Key) {
                 final Key key = (Key) obj;
                 return uid == key.uid && set == key.set && tag == key.tag
@@ -805,20 +931,22 @@
             return false;
         }
 
-        @Override
-        public int compareTo(Key another) {
+        /** @hide */
+        public static int compare(@NonNull Key left, @NonNull Key right) {
+            Objects.requireNonNull(left);
+            Objects.requireNonNull(right);
             int res = 0;
-            if (ident != null && another.ident != null) {
-                res = ident.compareTo(another.ident);
+            if (left.ident != null && right.ident != null) {
+                res = NetworkIdentitySet.compare(left.ident, right.ident);
             }
             if (res == 0) {
-                res = Integer.compare(uid, another.uid);
+                res = Integer.compare(left.uid, right.uid);
             }
             if (res == 0) {
-                res = Integer.compare(set, another.set);
+                res = Integer.compare(left.set, right.set);
             }
             if (res == 0) {
-                res = Integer.compare(tag, another.tag);
+                res = Integer.compare(left.tag, right.tag);
             }
             return res;
         }
diff --git a/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsHistory.java b/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsHistory.java
index 428bc6d..78c1370 100644
--- a/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsHistory.java
+++ b/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsHistory.java
@@ -16,6 +16,7 @@
 
 package android.net;
 
+import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
 import static android.net.NetworkStats.IFACE_ALL;
 import static android.net.NetworkStats.SET_DEFAULT;
 import static android.net.NetworkStats.TAG_NONE;
@@ -30,6 +31,8 @@
 
 import static com.android.net.module.util.NetworkStatsUtils.multiplySafeByRational;
 
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.os.Build;
 import android.os.Parcel;
@@ -50,7 +53,9 @@
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.net.ProtocolException;
+import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.List;
 import java.util.Random;
 
 /**
@@ -64,18 +69,25 @@
  *
  * @hide
  */
-public class NetworkStatsHistory implements Parcelable {
+@SystemApi(client = MODULE_LIBRARIES)
+public final class NetworkStatsHistory implements Parcelable {
     private static final int VERSION_INIT = 1;
     private static final int VERSION_ADD_PACKETS = 2;
     private static final int VERSION_ADD_ACTIVE = 3;
 
+    /** @hide */
     public static final int FIELD_ACTIVE_TIME = 0x01;
+    /** @hide */
     public static final int FIELD_RX_BYTES = 0x02;
+    /** @hide */
     public static final int FIELD_RX_PACKETS = 0x04;
+    /** @hide */
     public static final int FIELD_TX_BYTES = 0x08;
+    /** @hide */
     public static final int FIELD_TX_PACKETS = 0x10;
+    /** @hide */
     public static final int FIELD_OPERATIONS = 0x20;
-
+    /** @hide */
     public static final int FIELD_ALL = 0xFFFFFFFF;
 
     private long bucketDuration;
@@ -89,34 +101,171 @@
     private long[] operations;
     private long totalBytes;
 
-    public static class Entry {
-        public static final long UNKNOWN = -1;
-
-        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-        public long bucketDuration;
-        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-        public long bucketStart;
-        public long activeTime;
-        @UnsupportedAppUsage
-        public long rxBytes;
-        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-        public long rxPackets;
-        @UnsupportedAppUsage
-        public long txBytes;
-        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-        public long txPackets;
-        public long operations;
+    /** @hide */
+    public NetworkStatsHistory(long bucketDuration, long[] bucketStart, long[] activeTime,
+            long[] rxBytes, long[] rxPackets, long[] txBytes, long[] txPackets,
+            long[] operations, int bucketCount, long totalBytes) {
+        this.bucketDuration = bucketDuration;
+        this.bucketStart = bucketStart;
+        this.activeTime = activeTime;
+        this.rxBytes = rxBytes;
+        this.rxPackets = rxPackets;
+        this.txBytes = txBytes;
+        this.txPackets = txPackets;
+        this.operations = operations;
+        this.bucketCount = bucketCount;
+        this.totalBytes = totalBytes;
     }
 
+    /**
+     * An instance to represent a single record in a {@link NetworkStatsHistory} object.
+     */
+    public static final class Entry {
+        /** @hide */
+        public static final long UNKNOWN = -1;
+
+        /** @hide */
+        // TODO: Migrate all callers to get duration from the history object and remove this field.
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        public long bucketDuration;
+        /** @hide */
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        public long bucketStart;
+        /** @hide */
+        public long activeTime;
+        /** @hide */
+        @UnsupportedAppUsage
+        public long rxBytes;
+        /** @hide */
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        public long rxPackets;
+        /** @hide */
+        @UnsupportedAppUsage
+        public long txBytes;
+        /** @hide */
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        public long txPackets;
+        /** @hide */
+        public long operations;
+        /** @hide */
+        Entry() {}
+
+        /**
+         * Construct a {@link Entry} instance to represent a single record in a
+         * {@link NetworkStatsHistory} object.
+         *
+         * @param bucketStart Start of period for this {@link Entry}, in milliseconds since the
+         *                    Unix epoch, see {@link java.lang.System#currentTimeMillis}.
+         * @param activeTime Active time for this {@link Entry}, in milliseconds.
+         * @param rxBytes Number of bytes received for this {@link Entry}. Statistics should
+         *                represent the contents of IP packets, including IP headers.
+         * @param rxPackets Number of packets received for this {@link Entry}. Statistics should
+         *                  represent the contents of IP packets, including IP headers.
+         * @param txBytes Number of bytes transmitted for this {@link Entry}. Statistics should
+         *                represent the contents of IP packets, including IP headers.
+         * @param txPackets Number of bytes transmitted for this {@link Entry}. Statistics should
+         *                  represent the contents of IP packets, including IP headers.
+         * @param operations count of network operations performed for this {@link Entry}. This can
+         *                   be used to derive bytes-per-operation.
+         */
+        public Entry(long bucketStart, long activeTime, long rxBytes,
+                long rxPackets, long txBytes, long txPackets, long operations) {
+            this.bucketStart = bucketStart;
+            this.activeTime = activeTime;
+            this.rxBytes = rxBytes;
+            this.rxPackets = rxPackets;
+            this.txBytes = txBytes;
+            this.txPackets = txPackets;
+            this.operations = operations;
+        }
+
+        /**
+         * Get start timestamp of the bucket's time interval, in milliseconds since the Unix epoch.
+         */
+        public long getBucketStart() {
+            return bucketStart;
+        }
+
+        /**
+         * Get active time of the bucket's time interval, in milliseconds.
+         */
+        public long getActiveTime() {
+            return activeTime;
+        }
+
+        /** Get number of bytes received for this {@link Entry}. */
+        public long getRxBytes() {
+            return rxBytes;
+        }
+
+        /** Get number of packets received for this {@link Entry}. */
+        public long getRxPackets() {
+            return rxPackets;
+        }
+
+        /** Get number of bytes transmitted for this {@link Entry}. */
+        public long getTxBytes() {
+            return txBytes;
+        }
+
+        /** Get number of packets transmitted for this {@link Entry}. */
+        public long getTxPackets() {
+            return txPackets;
+        }
+
+        /** Get count of network operations performed for this {@link Entry}. */
+        public long getOperations() {
+            return operations;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o.getClass() != getClass()) return false;
+            Entry entry = (Entry) o;
+            return bucketStart == entry.bucketStart
+                    && activeTime == entry.activeTime && rxBytes == entry.rxBytes
+                    && rxPackets == entry.rxPackets && txBytes == entry.txBytes
+                    && txPackets == entry.txPackets && operations == entry.operations;
+        }
+
+        @Override
+        public int hashCode() {
+            return (int) (bucketStart * 2
+                    + activeTime * 3
+                    + rxBytes * 5
+                    + rxPackets * 7
+                    + txBytes * 11
+                    + txPackets * 13
+                    + operations * 17);
+        }
+
+        @Override
+        public String toString() {
+            return "Entry{"
+                    + "bucketStart=" + bucketStart
+                    + ", activeTime=" + activeTime
+                    + ", rxBytes=" + rxBytes
+                    + ", rxPackets=" + rxPackets
+                    + ", txBytes=" + txBytes
+                    + ", txPackets=" + txPackets
+                    + ", operations=" + operations
+                    + "}";
+        }
+    }
+
+    /** @hide */
     @UnsupportedAppUsage
     public NetworkStatsHistory(long bucketDuration) {
         this(bucketDuration, 10, FIELD_ALL);
     }
 
+    /** @hide */
     public NetworkStatsHistory(long bucketDuration, int initialSize) {
         this(bucketDuration, initialSize, FIELD_ALL);
     }
 
+    /** @hide */
     public NetworkStatsHistory(long bucketDuration, int initialSize, int fields) {
         this.bucketDuration = bucketDuration;
         bucketStart = new long[initialSize];
@@ -130,11 +279,13 @@
         totalBytes = 0;
     }
 
+    /** @hide */
     public NetworkStatsHistory(NetworkStatsHistory existing, long bucketDuration) {
         this(bucketDuration, existing.estimateResizeBuckets(bucketDuration));
         recordEntireHistory(existing);
     }
 
+    /** @hide */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     public NetworkStatsHistory(Parcel in) {
         bucketDuration = in.readLong();
@@ -150,7 +301,7 @@
     }
 
     @Override
-    public void writeToParcel(Parcel out, int flags) {
+    public void writeToParcel(@NonNull Parcel out, int flags) {
         out.writeLong(bucketDuration);
         writeLongArray(out, bucketStart, bucketCount);
         writeLongArray(out, activeTime, bucketCount);
@@ -162,6 +313,7 @@
         out.writeLong(totalBytes);
     }
 
+    /** @hide */
     public NetworkStatsHistory(DataInput in) throws IOException {
         final int version = in.readInt();
         switch (version) {
@@ -204,6 +356,7 @@
         }
     }
 
+    /** @hide */
     public void writeToStream(DataOutput out) throws IOException {
         out.writeInt(VERSION_ADD_ACTIVE);
         out.writeLong(bucketDuration);
@@ -221,15 +374,18 @@
         return 0;
     }
 
+    /** @hide */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     public int size() {
         return bucketCount;
     }
 
+    /** @hide */
     public long getBucketDuration() {
         return bucketDuration;
     }
 
+    /** @hide */
     @UnsupportedAppUsage
     public long getStart() {
         if (bucketCount > 0) {
@@ -239,6 +395,7 @@
         }
     }
 
+    /** @hide */
     @UnsupportedAppUsage
     public long getEnd() {
         if (bucketCount > 0) {
@@ -250,6 +407,7 @@
 
     /**
      * Return total bytes represented by this history.
+     * @hide
      */
     public long getTotalBytes() {
         return totalBytes;
@@ -258,6 +416,7 @@
     /**
      * Return index of bucket that contains or is immediately before the
      * requested time.
+     * @hide
      */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     public int getIndexBefore(long time) {
@@ -273,6 +432,7 @@
     /**
      * Return index of bucket that contains or is immediately after the
      * requested time.
+     * @hide
      */
     public int getIndexAfter(long time) {
         int index = Arrays.binarySearch(bucketStart, 0, bucketCount, time);
@@ -286,6 +446,7 @@
 
     /**
      * Return specific stats entry.
+     * @hide
      */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     public Entry getValues(int i, Entry recycle) {
@@ -301,6 +462,23 @@
         return entry;
     }
 
+    /**
+     * Get List of {@link Entry} of the {@link NetworkStatsHistory} instance.
+     *
+     * @return
+     */
+    @NonNull
+    public List<Entry> getEntries() {
+        // TODO: Return a wrapper that uses this list instead, to prevent the returned result
+        //  from being changed.
+        final ArrayList<Entry> ret = new ArrayList<>(size());
+        for (int i = 0; i < size(); i++) {
+            ret.add(getValues(i, null /* recycle */));
+        }
+        return ret;
+    }
+
+    /** @hide */
     public void setValues(int i, Entry entry) {
         // Unwind old values
         if (rxBytes != null) totalBytes -= rxBytes[i];
@@ -322,6 +500,7 @@
     /**
      * Record that data traffic occurred in the given time range. Will
      * distribute across internal buckets, creating new buckets as needed.
+     * @hide
      */
     @Deprecated
     public void recordData(long start, long end, long rxBytes, long txBytes) {
@@ -332,6 +511,7 @@
     /**
      * Record that data traffic occurred in the given time range. Will
      * distribute across internal buckets, creating new buckets as needed.
+     * @hide
      */
     public void recordData(long start, long end, NetworkStats.Entry entry) {
         long rxBytes = entry.rxBytes;
@@ -392,6 +572,7 @@
     /**
      * Record an entire {@link NetworkStatsHistory} into this history. Usually
      * for combining together stats for external reporting.
+     * @hide
      */
     @UnsupportedAppUsage
     public void recordEntireHistory(NetworkStatsHistory input) {
@@ -402,6 +583,7 @@
      * Record given {@link NetworkStatsHistory} into this history, copying only
      * buckets that atomically occur in the inclusive time range. Doesn't
      * interpolate across partial buckets.
+     * @hide
      */
     public void recordHistory(NetworkStatsHistory input, long start, long end) {
         final NetworkStats.Entry entry = new NetworkStats.Entry(
@@ -483,6 +665,7 @@
 
     /**
      * Clear all data stored in this object.
+     * @hide
      */
     public void clear() {
         bucketStart = EmptyArray.LONG;
@@ -498,9 +681,10 @@
 
     /**
      * Remove buckets older than requested cutoff.
+     * @hide
      */
-    @Deprecated
     public void removeBucketsBefore(long cutoff) {
+        // TODO: Consider use getIndexBefore.
         int i;
         for (i = 0; i < bucketCount; i++) {
             final long curStart = bucketStart[i];
@@ -522,7 +706,9 @@
             if (operations != null) operations = Arrays.copyOfRange(operations, i, length);
             bucketCount -= i;
 
-            // TODO: subtract removed values from totalBytes
+            totalBytes = 0;
+            if (rxBytes != null) totalBytes += CollectionUtils.total(rxBytes);
+            if (txBytes != null) totalBytes += CollectionUtils.total(txBytes);
         }
     }
 
@@ -536,6 +722,7 @@
      * @param start - start of the range, timestamp in milliseconds since the epoch.
      * @param end - end of the range, timestamp in milliseconds since the epoch.
      * @param recycle - entry instance for performance, could be null.
+     * @hide
      */
     @UnsupportedAppUsage
     public Entry getValues(long start, long end, Entry recycle) {
@@ -550,6 +737,7 @@
      * @param end - end of the range, timestamp in milliseconds since the epoch.
      * @param now - current timestamp in milliseconds since the epoch (wall clock).
      * @param recycle - entry instance for performance, could be null.
+     * @hide
      */
     @UnsupportedAppUsage
     public Entry getValues(long start, long end, long now, Entry recycle) {
@@ -613,6 +801,7 @@
 
     /**
      * @deprecated only for temporary testing
+     * @hide
      */
     @Deprecated
     public void generateRandom(long start, long end, long bytes) {
@@ -631,6 +820,7 @@
 
     /**
      * @deprecated only for temporary testing
+     * @hide
      */
     @Deprecated
     public void generateRandom(long start, long end, long rxBytes, long rxPackets, long txBytes,
@@ -660,12 +850,14 @@
         }
     }
 
+    /** @hide */
     public static long randomLong(Random r, long start, long end) {
         return (long) (start + (r.nextFloat() * (end - start)));
     }
 
     /**
      * Quickly determine if this history intersects with given window.
+     * @hide
      */
     public boolean intersects(long start, long end) {
         final long dataStart = getStart();
@@ -677,6 +869,7 @@
         return false;
     }
 
+    /** @hide */
     public void dump(IndentingPrintWriter pw, boolean fullHistory) {
         pw.print("NetworkStatsHistory: bucketDuration=");
         pw.println(bucketDuration / SECOND_IN_MILLIS);
@@ -700,6 +893,7 @@
         pw.decreaseIndent();
     }
 
+    /** @hide */
     public void dumpCheckin(PrintWriter pw) {
         pw.print("d,");
         pw.print(bucketDuration / SECOND_IN_MILLIS);
@@ -717,6 +911,7 @@
         }
     }
 
+    /** @hide */
     public void dumpDebug(ProtoOutputStream proto, long tag) {
         final long start = proto.start(tag);
 
@@ -776,6 +971,7 @@
         if (array != null) array[i] += value;
     }
 
+    /** @hide */
     public int estimateResizeBuckets(long newBucketDuration) {
         return (int) (size() * getBucketDuration() / newBucketDuration);
     }
@@ -783,6 +979,7 @@
     /**
      * Utility methods for interacting with {@link DataInputStream} and
      * {@link DataOutputStream}, mostly dealing with writing partial arrays.
+     * @hide
      */
     public static class DataStreamUtils {
         @Deprecated
@@ -857,6 +1054,7 @@
     /**
      * Utility methods for interacting with {@link Parcel} structures, mostly
      * dealing with writing partial arrays.
+     * @hide
      */
     public static class ParcelUtils {
         public static long[] readLongArray(Parcel in) {
@@ -884,4 +1082,80 @@
         }
     }
 
+    /**
+     * Builder class for {@link NetworkStatsHistory}.
+     */
+    public static final class Builder {
+        private final long mBucketDuration;
+        private final List<Long> mBucketStart;
+        private final List<Long> mActiveTime;
+        private final List<Long> mRxBytes;
+        private final List<Long> mRxPackets;
+        private final List<Long> mTxBytes;
+        private final List<Long> mTxPackets;
+        private final List<Long> mOperations;
+
+        /**
+         * Creates a new Builder with given bucket duration and initial capacity to construct
+         * {@link NetworkStatsHistory} objects.
+         *
+         * @param bucketDuration Duration of the buckets of the object, in milliseconds.
+         * @param initialCapacity Estimated number of records.
+         */
+        public Builder(long bucketDuration, int initialCapacity) {
+            mBucketDuration = bucketDuration;
+            mBucketStart = new ArrayList<>(initialCapacity);
+            mActiveTime = new ArrayList<>(initialCapacity);
+            mRxBytes = new ArrayList<>(initialCapacity);
+            mRxPackets = new ArrayList<>(initialCapacity);
+            mTxBytes = new ArrayList<>(initialCapacity);
+            mTxPackets = new ArrayList<>(initialCapacity);
+            mOperations = new ArrayList<>(initialCapacity);
+        }
+
+        /**
+         * Add an {@link Entry} into the {@link NetworkStatsHistory} instance.
+         *
+         * @param entry The target {@link Entry} object.
+         * @return The builder object.
+         */
+        @NonNull
+        public Builder addEntry(@NonNull Entry entry) {
+            mBucketStart.add(entry.bucketStart);
+            mActiveTime.add(entry.activeTime);
+            mRxBytes.add(entry.rxBytes);
+            mRxPackets.add(entry.rxPackets);
+            mTxBytes.add(entry.txBytes);
+            mTxPackets.add(entry.txPackets);
+            mOperations.add(entry.operations);
+            return this;
+        }
+
+        private static long sum(@NonNull List<Long> list) {
+            long sum = 0;
+            for (long entry : list) {
+                sum += entry;
+            }
+            return sum;
+        }
+
+        /**
+         * Builds the instance of the {@link NetworkStatsHistory}.
+         *
+         * @return the built instance of {@link NetworkStatsHistory}.
+         */
+        @NonNull
+        public NetworkStatsHistory build() {
+            return new NetworkStatsHistory(mBucketDuration,
+                    CollectionUtils.toLongArray(mBucketStart),
+                    CollectionUtils.toLongArray(mActiveTime),
+                    CollectionUtils.toLongArray(mRxBytes),
+                    CollectionUtils.toLongArray(mRxPackets),
+                    CollectionUtils.toLongArray(mTxBytes),
+                    CollectionUtils.toLongArray(mTxPackets),
+                    CollectionUtils.toLongArray(mOperations),
+                    mBucketStart.size(),
+                    sum(mRxBytes) + sum(mTxBytes));
+        }
+    }
 }
diff --git a/packages/ConnectivityT/framework-t/src/android/net/NetworkTemplate.java b/packages/ConnectivityT/framework-t/src/android/net/NetworkTemplate.java
index e9084b0..dba3991 100644
--- a/packages/ConnectivityT/framework-t/src/android/net/NetworkTemplate.java
+++ b/packages/ConnectivityT/framework-t/src/android/net/NetworkTemplate.java
@@ -263,7 +263,7 @@
      * Template to match {@link ConnectivityManager#TYPE_WIFI} networks with the
      * given key of the wifi network.
      *
-     * @param wifiNetworkKey key of the wifi network. see {@link WifiInfo#getCurrentNetworkKey()}
+     * @param wifiNetworkKey key of the wifi network. see {@link WifiInfo#getNetworkKey()}
      *                  to know details about the key.
      * @hide
      */
@@ -283,7 +283,7 @@
      * Call with {@link #WIFI_NETWORK_KEY_ALL} for {@code wifiNetworkKey} to get result regardless
      * of key of the wifi network.
      *
-     * @param wifiNetworkKey key of the wifi network. see {@link WifiInfo#getCurrentNetworkKey()}
+     * @param wifiNetworkKey key of the wifi network. see {@link WifiInfo#getNetworkKey()}
      *                  to know details about the key.
      * @param subscriberId the IMSI associated to this wifi network.
      *
@@ -364,7 +364,7 @@
     private final int mMetered;
     private final int mRoaming;
     private final int mDefaultNetwork;
-    private final int mSubType;
+    private final int mRatType;
     /**
      * The subscriber Id match rule defines how the template should match networks with
      * specific subscriberId(s). See NetworkTemplate#SUBSCRIBER_ID_MATCH_RULE_* for more detail.
@@ -413,18 +413,18 @@
     /** @hide */
     // TODO: Remove it after updating all of the caller.
     public NetworkTemplate(int matchRule, String subscriberId, String[] matchSubscriberIds,
-            String wifiNetworkKey, int metered, int roaming, int defaultNetwork, int subType,
+            String wifiNetworkKey, int metered, int roaming, int defaultNetwork, int ratType,
             int oemManaged) {
         this(matchRule, subscriberId, matchSubscriberIds,
                 wifiNetworkKey != null ? new String[] { wifiNetworkKey } : new String[0],
-                metered, roaming, defaultNetwork, subType, oemManaged,
+                metered, roaming, defaultNetwork, ratType, oemManaged,
                 NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_EXACT);
     }
 
     /** @hide */
     public NetworkTemplate(int matchRule, String subscriberId, String[] matchSubscriberIds,
             String[] matchWifiNetworkKeys, int metered, int roaming,
-            int defaultNetwork, int subType, int oemManaged, int subscriberIdMatchRule) {
+            int defaultNetwork, int ratType, int oemManaged, int subscriberIdMatchRule) {
         Objects.requireNonNull(matchWifiNetworkKeys);
         mMatchRule = matchRule;
         mSubscriberId = subscriberId;
@@ -435,7 +435,7 @@
         mMetered = metered;
         mRoaming = roaming;
         mDefaultNetwork = defaultNetwork;
-        mSubType = subType;
+        mRatType = ratType;
         mOemManaged = oemManaged;
         mSubscriberIdMatchRule = subscriberIdMatchRule;
         checkValidSubscriberIdMatchRule(matchRule, subscriberIdMatchRule);
@@ -453,7 +453,7 @@
         mMetered = in.readInt();
         mRoaming = in.readInt();
         mDefaultNetwork = in.readInt();
-        mSubType = in.readInt();
+        mRatType = in.readInt();
         mOemManaged = in.readInt();
         mSubscriberIdMatchRule = in.readInt();
     }
@@ -467,7 +467,7 @@
         dest.writeInt(mMetered);
         dest.writeInt(mRoaming);
         dest.writeInt(mDefaultNetwork);
-        dest.writeInt(mSubType);
+        dest.writeInt(mRatType);
         dest.writeInt(mOemManaged);
         dest.writeInt(mSubscriberIdMatchRule);
     }
@@ -500,8 +500,8 @@
             builder.append(", defaultNetwork=").append(NetworkStats.defaultNetworkToString(
                     mDefaultNetwork));
         }
-        if (mSubType != NETWORK_TYPE_ALL) {
-            builder.append(", subType=").append(mSubType);
+        if (mRatType != NETWORK_TYPE_ALL) {
+            builder.append(", ratType=").append(mRatType);
         }
         if (mOemManaged != OEM_MANAGED_ALL) {
             builder.append(", oemManaged=").append(getOemManagedNames(mOemManaged));
@@ -514,7 +514,7 @@
     @Override
     public int hashCode() {
         return Objects.hash(mMatchRule, mSubscriberId, Arrays.hashCode(mMatchWifiNetworkKeys),
-                mMetered, mRoaming, mDefaultNetwork, mSubType, mOemManaged, mSubscriberIdMatchRule);
+                mMetered, mRoaming, mDefaultNetwork, mRatType, mOemManaged, mSubscriberIdMatchRule);
     }
 
     @Override
@@ -526,7 +526,7 @@
                     && mMetered == other.mMetered
                     && mRoaming == other.mRoaming
                     && mDefaultNetwork == other.mDefaultNetwork
-                    && mSubType == other.mSubType
+                    && mRatType == other.mRatType
                     && mOemManaged == other.mOemManaged
                     && mSubscriberIdMatchRule == other.mSubscriberIdMatchRule
                     && Arrays.equals(mMatchWifiNetworkKeys, other.mMatchWifiNetworkKeys);
@@ -593,7 +593,7 @@
 
     /**
      * Get the set of Wifi Network Keys of the template.
-     * See {@link WifiInfo#getCurrentNetworkKey()}.
+     * See {@link WifiInfo#getNetworkKey()}.
      */
     @NonNull
     public Set<String> getWifiNetworkKeys() {
@@ -635,7 +635,7 @@
      * Get the Radio Access Technology(RAT) type filter of the template.
      */
     public int getRatType() {
-        return mSubType;
+        return mRatType;
     }
 
     /**
@@ -652,7 +652,9 @@
      *
      * @hide
      */
-    public boolean matches(NetworkIdentity ident) {
+    @SystemApi(client = MODULE_LIBRARIES)
+    public boolean matches(@NonNull NetworkIdentity ident) {
+        Objects.requireNonNull(ident);
         if (!matchesMetered(ident)) return false;
         if (!matchesRoaming(ident)) return false;
         if (!matchesDefaultNetwork(ident)) return false;
@@ -708,8 +710,8 @@
     }
 
     private boolean matchesCollapsedRatType(NetworkIdentity ident) {
-        return mSubType == NETWORK_TYPE_ALL
-                || getCollapsedRatType(mSubType) == getCollapsedRatType(ident.mSubType);
+        return mRatType == NETWORK_TYPE_ALL
+                || getCollapsedRatType(mRatType) == getCollapsedRatType(ident.mRatType);
     }
 
     /**
@@ -729,7 +731,7 @@
      * Returns true when the key matches, or when {@code mMatchWifiNetworkKeys} is
      * empty.
      *
-     * @param wifiNetworkKey key of the wifi network. see {@link WifiInfo#getCurrentNetworkKey()}
+     * @param wifiNetworkKey key of the wifi network. see {@link WifiInfo#getNetworkKey()}
      *                  to know details about the key.
      */
     private boolean matchesWifiNetworkKey(@NonNull String wifiNetworkKey) {
@@ -837,7 +839,7 @@
         switch (ident.mType) {
             case TYPE_WIFI:
                 return matchesSubscriberId(ident.mSubscriberId)
-                        && matchesWifiNetworkKey(ident.mNetworkId);
+                        && matchesWifiNetworkKey(ident.mWifiNetworkKey);
             default:
                 return false;
         }
@@ -1059,9 +1061,9 @@
          * the intention of matching any Wifi Network Key.
          *
          * @param wifiNetworkKeys the list of Wifi Network Key,
-         *                        see {@link WifiInfo#getCurrentNetworkKey()}.
+         *                        see {@link WifiInfo#getNetworkKey()}.
          *                        Or an empty list to match all networks.
-         *                        Note that {@code getCurrentNetworkKey()} might get null key
+         *                        Note that {@code getNetworkKey()} might get null key
          *                        when wifi disconnects. However, the caller should never invoke
          *                        this function with a null Wifi Network Key since such statistics
          *                        never exists.
diff --git a/packages/ConnectivityT/framework-t/src/android/net/TrafficStats.java b/packages/ConnectivityT/framework-t/src/android/net/TrafficStats.java
index d8feb88..c2f0cdf 100644
--- a/packages/ConnectivityT/framework-t/src/android/net/TrafficStats.java
+++ b/packages/ConnectivityT/framework-t/src/android/net/TrafficStats.java
@@ -16,6 +16,8 @@
 
 package android.net;
 
+import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
+
 import android.annotation.NonNull;
 import android.annotation.SuppressLint;
 import android.annotation.SystemApi;
@@ -26,9 +28,10 @@
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.media.MediaPlayer;
+import android.os.Binder;
 import android.os.Build;
 import android.os.RemoteException;
-import android.os.ServiceManager;
+import android.util.Log;
 
 import com.android.server.NetworkManagementSocketTagger;
 
@@ -53,6 +56,7 @@
  * use {@link NetworkStatsManager} instead.
  */
 public class TrafficStats {
+    private static final String TAG = TrafficStats.class.getSimpleName();
     /**
      * The return value to indicate that the device does not support the statistic.
      */
@@ -173,8 +177,8 @@
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 130143562)
     private synchronized static INetworkStatsService getStatsService() {
         if (sStatsService == null) {
-            sStatsService = INetworkStatsService.Stub.asInterface(
-                    ServiceManager.getService(Context.NETWORK_STATS_SERVICE));
+            throw new IllegalStateException("TrafficStats not initialized, uid="
+                    + Binder.getCallingUid());
         }
         return sStatsService;
     }
@@ -193,6 +197,45 @@
     private static final String LOOPBACK_IFACE = "lo";
 
     /**
+     * Initialization {@link TrafficStats} with the context, to
+     * allow {@link TrafficStats} to fetch the needed binder.
+     *
+     * @param context a long-lived context, such as the application context or system
+     *                server context.
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    @SuppressLint("VisiblySynchronized")
+    public static synchronized void init(@NonNull final Context context) {
+        if (sStatsService != null) {
+            throw new IllegalStateException("TrafficStats is already initialized, uid="
+                    + Binder.getCallingUid());
+        }
+        final NetworkStatsManager statsManager =
+                context.getSystemService(NetworkStatsManager.class);
+        if (statsManager == null) {
+            // TODO: Currently Process.isSupplemental is not working yet, because it depends on
+            //  process to run in a certain UID range, which is not true for now. Change this
+            //  to Log.wtf once Process.isSupplemental is ready.
+            Log.e(TAG, "TrafficStats not initialized, uid=" + Binder.getCallingUid());
+            return;
+        }
+        sStatsService = statsManager.getBinder();
+    }
+
+    /**
+     * Attach the socket tagger implementation to the current process, to
+     * get notified when a socket's {@link FileDescriptor} is assigned to
+     * a thread. See {@link SocketTagger#set(SocketTagger)}.
+     *
+     * @hide
+     */
+    @SystemApi(client = MODULE_LIBRARIES)
+    public static void attachSocketTagger() {
+        NetworkManagementSocketTagger.install();
+    }
+
+    /**
      * Set active tag to use when accounting {@link Socket} traffic originating
      * from the current thread. Only one active tag per thread is supported.
      * <p>
@@ -265,6 +308,18 @@
     }
 
     /**
+     * Set active tag to use when accounting {@link Socket} traffic originating
+     * from the current thread. The tag used internally is well-defined to
+     * distinguish all download provider traffic.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static void setThreadStatsTagDownload() {
+        setThreadStatsTag(TAG_SYSTEM_DOWNLOAD);
+    }
+
+    /**
      * Get the active tag used when accounting {@link Socket} traffic originating
      * from the current thread. Only one active tag per thread is supported.
      * {@link #tagSocket(Socket)}.
diff --git a/packages/ConnectivityT/framework-t/src/android/net/netstats/IUsageCallback.aidl b/packages/ConnectivityT/framework-t/src/android/net/netstats/IUsageCallback.aidl
new file mode 100644
index 0000000..4e8a5b2
--- /dev/null
+++ b/packages/ConnectivityT/framework-t/src/android/net/netstats/IUsageCallback.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.netstats;
+
+import android.net.DataUsageRequest;
+
+/**
+ * Interface for NetworkStatsService to notify events to the callers of registerUsageCallback.
+ *
+ * @hide
+ */
+oneway interface IUsageCallback {
+    void onThresholdReached(in DataUsageRequest request);
+    void onCallbackReleased(in DataUsageRequest request);
+}
diff --git a/packages/ConnectivityT/framework-t/src/com/android/server/NetworkManagementSocketTagger.java b/packages/ConnectivityT/framework-t/src/com/android/server/NetworkManagementSocketTagger.java
index e35f6a6..1eb52fb 100644
--- a/packages/ConnectivityT/framework-t/src/com/android/server/NetworkManagementSocketTagger.java
+++ b/packages/ConnectivityT/framework-t/src/com/android/server/NetworkManagementSocketTagger.java
@@ -26,6 +26,7 @@
 
 /**
  * Assigns tags to sockets for traffic stats.
+ * @hide
  */
 public final class NetworkManagementSocketTagger extends SocketTagger {
     private static final String TAG = "NetworkManagementSocketTagger";
diff --git a/packages/ConnectivityT/service/Android.bp b/packages/ConnectivityT/service/Android.bp
index 97dfb64..24bc91d 100644
--- a/packages/ConnectivityT/service/Android.bp
+++ b/packages/ConnectivityT/service/Android.bp
@@ -26,6 +26,8 @@
     srcs: [
         "src/com/android/server/net/NetworkIdentity*.java",
         "src/com/android/server/net/NetworkStats*.java",
+        "src/com/android/server/net/BpfInterfaceMapUpdater.java",
+        "src/com/android/server/net/InterfaceMapValue.java",
     ],
     path: "src",
     visibility: [
@@ -66,6 +68,7 @@
 filegroup {
     name: "services.connectivity-ethernet-sources",
     srcs: [
+        "src/com/android/server/net/DelayedDiskWrite.java",
         "src/com/android/server/net/IpConfigStore.java",
     ],
     path: "src",
@@ -82,8 +85,43 @@
         ":services.connectivity-ethernet-sources",
         ":services.connectivity-ipsec-sources",
         ":services.connectivity-netstats-sources",
-        ":services.connectivity-nsd-sources",
     ],
     path: "src",
     visibility: ["//frameworks/base/services/core"],
 }
+
+filegroup {
+    name: "services.connectivity-tiramisu-updatable-sources",
+    srcs: [
+        ":services.connectivity-nsd-sources",
+    ],
+    path: "src",
+    visibility: [
+        "//packages/modules/Connectivity:__subpackages__",
+    ],
+}
+
+cc_library_shared {
+    name: "libcom_android_net_module_util_jni",
+    min_sdk_version: "30",
+    cflags: [
+        "-Wall",
+        "-Werror",
+        "-Wno-unused-parameter",
+        "-Wthread-safety",
+    ],
+    srcs: [
+        "jni/onload.cpp",
+    ],
+    stl: "libc++_static",
+    static_libs: [
+        "libnet_utils_device_common_bpfjni",
+    ],
+    shared_libs: [
+        "liblog",
+        "libnativehelper",
+    ],
+    apex_available: [
+        "//apex_available:platform",
+    ],
+}
diff --git a/packages/ConnectivityT/service/jni/onload.cpp b/packages/ConnectivityT/service/jni/onload.cpp
new file mode 100644
index 0000000..bca4697
--- /dev/null
+++ b/packages/ConnectivityT/service/jni/onload.cpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <nativehelper/JNIHelp.h>
+#include <log/log.h>
+
+namespace android {
+
+int register_com_android_net_module_util_BpfMap(JNIEnv* env, char const* class_name);
+
+extern "C" jint JNI_OnLoad(JavaVM* vm, void*) {
+    JNIEnv *env;
+    if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
+        ALOGE("GetEnv failed");
+        return JNI_ERR;
+    }
+
+    if (register_com_android_net_module_util_BpfMap(env,
+            "com/android/net/module/util/BpfMap") < 0) return JNI_ERR;
+
+    return JNI_VERSION_1_6;
+}
+
+};
+
diff --git a/packages/ConnectivityT/service/src/com/android/server/net/BpfInterfaceMapUpdater.java b/packages/ConnectivityT/service/src/com/android/server/net/BpfInterfaceMapUpdater.java
new file mode 100644
index 0000000..25c88eb
--- /dev/null
+++ b/packages/ConnectivityT/service/src/com/android/server/net/BpfInterfaceMapUpdater.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.net;
+
+import android.content.Context;
+import android.net.INetd;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ServiceSpecificException;
+import android.system.ErrnoException;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.net.module.util.BaseNetdUnsolicitedEventListener;
+import com.android.net.module.util.BpfMap;
+import com.android.net.module.util.IBpfMap;
+import com.android.net.module.util.InterfaceParams;
+import com.android.net.module.util.Struct.U32;
+
+/**
+ * Monitor interface added (without removed) and right interface name and its index to bpf map.
+ */
+public class BpfInterfaceMapUpdater {
+    private static final String TAG = BpfInterfaceMapUpdater.class.getSimpleName();
+    // This is current path but may be changed soon.
+    private static final String IFACE_INDEX_NAME_MAP_PATH =
+            "/sys/fs/bpf/map_netd_iface_index_name_map";
+    private final IBpfMap<U32, InterfaceMapValue> mBpfMap;
+    private final INetd mNetd;
+    private final Handler mHandler;
+    private final Dependencies mDeps;
+
+    public BpfInterfaceMapUpdater(Context ctx, Handler handler) {
+        this(ctx, handler, new Dependencies());
+    }
+
+    @VisibleForTesting
+    public BpfInterfaceMapUpdater(Context ctx, Handler handler, Dependencies deps) {
+        mDeps = deps;
+        mBpfMap = deps.getInterfaceMap();
+        mNetd = deps.getINetd(ctx);
+        mHandler = handler;
+    }
+
+    /**
+     * Dependencies of BpfInerfaceMapUpdater, for injection in tests.
+     */
+    @VisibleForTesting
+    public static class Dependencies {
+        /** Create BpfMap for updating interface and index mapping. */
+        public IBpfMap<U32, InterfaceMapValue> getInterfaceMap() {
+            try {
+                return new BpfMap<>(IFACE_INDEX_NAME_MAP_PATH, BpfMap.BPF_F_RDWR,
+                    U32.class, InterfaceMapValue.class);
+            } catch (ErrnoException e) {
+                Log.e(TAG, "Cannot create interface map: " + e);
+                return null;
+            }
+        }
+
+        /** Get InterfaceParams for giving interface name. */
+        public InterfaceParams getInterfaceParams(String ifaceName) {
+            return InterfaceParams.getByName(ifaceName);
+        }
+
+        /** Get INetd binder object. */
+        public INetd getINetd(Context ctx) {
+            return INetd.Stub.asInterface((IBinder) ctx.getSystemService(Context.NETD_SERVICE));
+        }
+    }
+
+    /**
+     * Start listening interface update event.
+     * Query current interface names before listening.
+     */
+    public void start() {
+        mHandler.post(() -> {
+            if (mBpfMap == null) {
+                Log.wtf(TAG, "Fail to start: Null bpf map");
+                return;
+            }
+
+            try {
+                // TODO: use a NetlinkMonitor and listen for RTM_NEWLINK messages instead.
+                mNetd.registerUnsolicitedEventListener(new InterfaceChangeObserver());
+            } catch (RemoteException e) {
+                Log.wtf(TAG, "Unable to register netd UnsolicitedEventListener, " + e);
+            }
+
+            final String[] ifaces;
+            try {
+                // TODO: use a netlink dump to get the current interface list.
+                ifaces = mNetd.interfaceGetList();
+            } catch (RemoteException | ServiceSpecificException e) {
+                Log.wtf(TAG, "Unable to query interface names by netd, " + e);
+                return;
+            }
+
+            for (String ifaceName : ifaces) {
+                addInterface(ifaceName);
+            }
+        });
+    }
+
+    private void addInterface(String ifaceName) {
+        final InterfaceParams iface = mDeps.getInterfaceParams(ifaceName);
+        if (iface == null) {
+            Log.e(TAG, "Unable to get InterfaceParams for " + ifaceName);
+            return;
+        }
+
+        try {
+            mBpfMap.updateEntry(new U32(iface.index), new InterfaceMapValue(ifaceName));
+        } catch (ErrnoException e) {
+            Log.e(TAG, "Unable to update entry for " + ifaceName + ", " + e);
+        }
+    }
+
+    private class InterfaceChangeObserver extends BaseNetdUnsolicitedEventListener {
+        @Override
+        public void onInterfaceAdded(String ifName) {
+            mHandler.post(() -> addInterface(ifName));
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/net/DelayedDiskWrite.java b/packages/ConnectivityT/service/src/com/android/server/net/DelayedDiskWrite.java
similarity index 82%
rename from services/core/java/com/android/server/net/DelayedDiskWrite.java
rename to packages/ConnectivityT/service/src/com/android/server/net/DelayedDiskWrite.java
index 8f09eb7..35dc455 100644
--- a/services/core/java/com/android/server/net/DelayedDiskWrite.java
+++ b/packages/ConnectivityT/service/src/com/android/server/net/DelayedDiskWrite.java
@@ -26,21 +26,37 @@
 import java.io.FileOutputStream;
 import java.io.IOException;
 
+/**
+ * This class provides APIs to do a delayed data write to a given {@link OutputStream}.
+ */
 public class DelayedDiskWrite {
+    private static final String TAG = "DelayedDiskWrite";
+
     private HandlerThread mDiskWriteHandlerThread;
     private Handler mDiskWriteHandler;
     /* Tracks multiple writes on the same thread */
     private int mWriteSequence = 0;
-    private final String TAG = "DelayedDiskWrite";
 
+    /**
+     * Used to do a delayed data write to a given {@link OutputStream}.
+     */
     public interface Writer {
-        public void onWriteCalled(DataOutputStream out) throws IOException;
+        /**
+         * write data to a given {@link OutputStream}.
+         */
+        void onWriteCalled(DataOutputStream out) throws IOException;
     }
 
+    /**
+     * Do a delayed data write to a given output stream opened from filePath.
+     */
     public void write(final String filePath, final Writer w) {
         write(filePath, w, true);
     }
 
+    /**
+     * Do a delayed data write to a given output stream opened from filePath.
+     */
     public void write(final String filePath, final Writer w, final boolean open) {
         if (TextUtils.isEmpty(filePath)) {
             throw new IllegalArgumentException("empty file path");
@@ -77,7 +93,7 @@
             if (out != null) {
                 try {
                     out.close();
-                } catch (Exception e) {}
+                } catch (Exception e) { }
             }
 
             // Quit if no more writes sent
diff --git a/packages/ConnectivityT/service/src/com/android/server/net/InterfaceMapValue.java b/packages/ConnectivityT/service/src/com/android/server/net/InterfaceMapValue.java
new file mode 100644
index 0000000..061f323
--- /dev/null
+++ b/packages/ConnectivityT/service/src/com/android/server/net/InterfaceMapValue.java
@@ -0,0 +1,35 @@
+/*
+ * 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 com.android.server.net;
+
+import com.android.net.module.util.Struct;
+import com.android.net.module.util.Struct.Field;
+import com.android.net.module.util.Struct.Type;
+
+/**
+ * The value of bpf interface index map which is used for NetworkStatsService.
+ */
+public class InterfaceMapValue extends Struct {
+    @Field(order = 0, type = Type.ByteArray, arraysize = 16)
+    public final byte[] interfaceName;
+
+    public InterfaceMapValue(String iface) {
+        final byte[] ifaceArray = iface.getBytes();
+        interfaceName = new byte[16];
+        // All array bytes after the interface name, if any, must be 0.
+        System.arraycopy(ifaceArray, 0, interfaceName, 0, ifaceArray.length);
+    }
+}
diff --git a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsFactory.java b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsFactory.java
index bb123a3..17f3455 100644
--- a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsFactory.java
+++ b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsFactory.java
@@ -26,10 +26,10 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.net.INetd;
+import android.content.Context;
+import android.net.ConnectivityManager;
 import android.net.NetworkStats;
 import android.net.UnderlyingNetworkInfo;
-import android.os.RemoteException;
 import android.os.StrictMode;
 import android.os.SystemClock;
 
@@ -70,7 +70,7 @@
 
     private final boolean mUseBpfStats;
 
-    private final INetd mNetd;
+    private final Context mContext;
 
     /**
      * Guards persistent data access in this class
@@ -158,12 +158,12 @@
         NetworkStats.apply464xlatAdjustments(baseTraffic, stackedTraffic, mStackedIfaces);
     }
 
-    public NetworkStatsFactory(@NonNull INetd netd) {
-        this(new File("/proc/"), true, netd);
+    public NetworkStatsFactory(@NonNull Context ctx) {
+        this(ctx, new File("/proc/"), true);
     }
 
     @VisibleForTesting
-    public NetworkStatsFactory(File procRoot, boolean useBpfStats, @NonNull INetd netd) {
+    public NetworkStatsFactory(@NonNull Context ctx, File procRoot, boolean useBpfStats) {
         mStatsXtIfaceAll = new File(procRoot, "net/xt_qtaguid/iface_stat_all");
         mStatsXtIfaceFmt = new File(procRoot, "net/xt_qtaguid/iface_stat_fmt");
         mStatsXtUid = new File(procRoot, "net/xt_qtaguid/stats");
@@ -172,7 +172,7 @@
             mPersistSnapshot = new NetworkStats(SystemClock.elapsedRealtime(), -1);
             mTunAnd464xlatAdjustedStats = new NetworkStats(SystemClock.elapsedRealtime(), -1);
         }
-        mNetd = netd;
+        mContext = ctx;
     }
 
     public NetworkStats readBpfNetworkStatsDev() throws IOException {
@@ -295,11 +295,12 @@
     }
 
     @GuardedBy("mPersistentDataLock")
-    private void requestSwapActiveStatsMapLocked() throws RemoteException {
-        // Ask netd to do a active map stats swap. When the binder call successfully returns,
+    private void requestSwapActiveStatsMapLocked() {
+        // Do a active map stats swap. When the binder call successfully returns,
         // the system server should be able to safely read and clean the inactive map
         // without race problem.
-        mNetd.trafficSwapActiveStatsMap();
+        final ConnectivityManager cm = mContext.getSystemService(ConnectivityManager.class);
+        cm.swapActiveStatsMap();
     }
 
     /**
@@ -327,7 +328,7 @@
                 if (mUseBpfStats) {
                     try {
                         requestSwapActiveStatsMapLocked();
-                    } catch (RemoteException e) {
+                    } catch (RuntimeException e) {
                         throw new IOException(e);
                     }
                     // Stats are always read from the inactive map, so they must be read after the
diff --git a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsManagerInternal.java b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsManagerInternal.java
deleted file mode 100644
index 0e9a9da..0000000
--- a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsManagerInternal.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.net;
-
-import android.annotation.NonNull;
-import android.net.NetworkStats;
-import android.net.NetworkTemplate;
-
-public abstract class NetworkStatsManagerInternal {
-    /** Return network layer usage total for traffic that matches template. */
-    public abstract long getNetworkTotalBytes(NetworkTemplate template, long start, long end);
-
-    /** Return network layer usage per-UID for traffic that matches template. */
-    public abstract NetworkStats getNetworkUidBytes(NetworkTemplate template, long start, long end);
-
-    /** Mark given UID as being in foreground for stats purposes. */
-    public abstract void setUidForeground(int uid, boolean uidForeground);
-
-    /** Advise persistance threshold; may be overridden internally. */
-    public abstract void advisePersistThreshold(long thresholdBytes);
-
-    /** Force update of statistics. */
-    public abstract void forceUpdate();
-
-    /**
-     * Set the warning and limit to all registered custom network stats providers.
-     * Note that invocation of any interface will be sent to all providers.
-     */
-    public abstract void setStatsProviderWarningAndLimitAsync(@NonNull String iface, long warning,
-            long limit);
-}
diff --git a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsObservers.java b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsObservers.java
index b57a4f9..1953624 100644
--- a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsObservers.java
+++ b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsObservers.java
@@ -26,13 +26,12 @@
 import android.net.NetworkStatsCollection;
 import android.net.NetworkStatsHistory;
 import android.net.NetworkTemplate;
-import android.os.Bundle;
+import android.net.netstats.IUsageCallback;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
-import android.os.Messenger;
 import android.os.Process;
 import android.os.RemoteException;
 import android.util.ArrayMap;
@@ -75,10 +74,10 @@
      *
      * @return the normalized request wrapped within {@link RequestInfo}.
      */
-    public DataUsageRequest register(DataUsageRequest inputRequest, Messenger messenger,
-                IBinder binder, int callingUid, @NetworkStatsAccess.Level int accessLevel) {
-        DataUsageRequest request = buildRequest(inputRequest);
-        RequestInfo requestInfo = buildRequestInfo(request, messenger, binder, callingUid,
+    public DataUsageRequest register(DataUsageRequest inputRequest, IUsageCallback callback,
+            int callingUid, @NetworkStatsAccess.Level int accessLevel) {
+        DataUsageRequest request = buildRequest(inputRequest, callingUid);
+        RequestInfo requestInfo = buildRequestInfo(request, callback, callingUid,
                 accessLevel);
 
         if (LOGV) Log.v(TAG, "Registering observer for " + request);
@@ -195,10 +194,12 @@
         }
     }
 
-    private DataUsageRequest buildRequest(DataUsageRequest request) {
-        // Cap the minimum threshold to a safe default to avoid too many callbacks
-        long thresholdInBytes = Math.max(MIN_THRESHOLD_BYTES, request.thresholdInBytes);
-        if (thresholdInBytes < request.thresholdInBytes) {
+    private DataUsageRequest buildRequest(DataUsageRequest request, int callingUid) {
+        // For non-system uid, cap the minimum threshold to a safe default to avoid too
+        // many callbacks.
+        long thresholdInBytes = (callingUid == Process.SYSTEM_UID ? request.thresholdInBytes
+                : Math.max(MIN_THRESHOLD_BYTES, request.thresholdInBytes));
+        if (thresholdInBytes > request.thresholdInBytes) {
             Log.w(TAG, "Threshold was too low for " + request
                     + ". Overriding to a safer default of " + thresholdInBytes + " bytes");
         }
@@ -206,11 +207,10 @@
                 request.template, thresholdInBytes);
     }
 
-    private RequestInfo buildRequestInfo(DataUsageRequest request,
-                Messenger messenger, IBinder binder, int callingUid,
-                @NetworkStatsAccess.Level int accessLevel) {
+    private RequestInfo buildRequestInfo(DataUsageRequest request, IUsageCallback callback,
+            int callingUid, @NetworkStatsAccess.Level int accessLevel) {
         if (accessLevel <= NetworkStatsAccess.Level.USER) {
-            return new UserUsageRequestInfo(this, request, messenger, binder, callingUid,
+            return new UserUsageRequestInfo(this, request, callback, callingUid,
                     accessLevel);
         } else {
             // Safety check in case a new access level is added and we forgot to update this
@@ -218,7 +218,7 @@
                 throw new IllegalArgumentException(
                         "accessLevel " + accessLevel + " is less than DEVICESUMMARY.");
             }
-            return new NetworkUsageRequestInfo(this, request, messenger, binder, callingUid,
+            return new NetworkUsageRequestInfo(this, request, callback, callingUid,
                     accessLevel);
         }
     }
@@ -230,25 +230,23 @@
     private abstract static class RequestInfo implements IBinder.DeathRecipient {
         private final NetworkStatsObservers mStatsObserver;
         protected final DataUsageRequest mRequest;
-        private final Messenger mMessenger;
-        private final IBinder mBinder;
+        private final IUsageCallback mCallback;
         protected final int mCallingUid;
         protected final @NetworkStatsAccess.Level int mAccessLevel;
         protected NetworkStatsRecorder mRecorder;
         protected NetworkStatsCollection mCollection;
 
         RequestInfo(NetworkStatsObservers statsObserver, DataUsageRequest request,
-                    Messenger messenger, IBinder binder, int callingUid,
+                IUsageCallback callback, int callingUid,
                     @NetworkStatsAccess.Level int accessLevel) {
             mStatsObserver = statsObserver;
             mRequest = request;
-            mMessenger = messenger;
-            mBinder = binder;
+            mCallback = callback;
             mCallingUid = callingUid;
             mAccessLevel = accessLevel;
 
             try {
-                mBinder.linkToDeath(this, 0);
+                mCallback.asBinder().linkToDeath(this, 0);
             } catch (RemoteException e) {
                 binderDied();
             }
@@ -257,7 +255,7 @@
         @Override
         public void binderDied() {
             if (LOGV) {
-                Log.v(TAG, "RequestInfo binderDied(" + mRequest + ", " + mBinder + ")");
+                Log.v(TAG, "RequestInfo binderDied(" + mRequest + ", " + mCallback + ")");
             }
             mStatsObserver.unregister(mRequest, Process.SYSTEM_UID);
             callCallback(NetworkStatsManager.CALLBACK_RELEASED);
@@ -270,9 +268,7 @@
         }
 
         private void unlinkDeathRecipient() {
-            if (mBinder != null) {
-                mBinder.unlinkToDeath(this, 0);
-            }
+            mCallback.asBinder().unlinkToDeath(this, 0);
         }
 
         /**
@@ -294,17 +290,19 @@
         }
 
         private void callCallback(int callbackType) {
-            Bundle bundle = new Bundle();
-            bundle.putParcelable(DataUsageRequest.PARCELABLE_KEY, mRequest);
-            Message msg = Message.obtain();
-            msg.what = callbackType;
-            msg.setData(bundle);
             try {
                 if (LOGV) {
                     Log.v(TAG, "sending notification " + callbackTypeToName(callbackType)
                             + " for " + mRequest);
                 }
-                mMessenger.send(msg);
+                switch (callbackType) {
+                    case NetworkStatsManager.CALLBACK_LIMIT_REACHED:
+                        mCallback.onThresholdReached(mRequest);
+                        break;
+                    case NetworkStatsManager.CALLBACK_RELEASED:
+                        mCallback.onCallbackReleased(mRequest);
+                        break;
+                }
             } catch (RemoteException e) {
                 // May occur naturally in the race of binder death.
                 Log.w(TAG, "RemoteException caught trying to send a callback msg for " + mRequest);
@@ -334,9 +332,9 @@
 
     private static class NetworkUsageRequestInfo extends RequestInfo {
         NetworkUsageRequestInfo(NetworkStatsObservers statsObserver, DataUsageRequest request,
-                    Messenger messenger, IBinder binder, int callingUid,
+                IUsageCallback callback, int callingUid,
                     @NetworkStatsAccess.Level int accessLevel) {
-            super(statsObserver, request, messenger, binder, callingUid, accessLevel);
+            super(statsObserver, request, callback, callingUid, accessLevel);
         }
 
         @Override
@@ -376,9 +374,9 @@
 
     private static class UserUsageRequestInfo extends RequestInfo {
         UserUsageRequestInfo(NetworkStatsObservers statsObserver, DataUsageRequest request,
-                    Messenger messenger, IBinder binder, int callingUid,
+                    IUsageCallback callback, int callingUid,
                     @NetworkStatsAccess.Level int accessLevel) {
-            super(statsObserver, request, messenger, binder, callingUid, accessLevel);
+            super(statsObserver, request, callback, callingUid, accessLevel);
         }
 
         @Override
diff --git a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsService.java b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsService.java
index 4db90c1..243d621 100644
--- a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsService.java
+++ b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsService.java
@@ -19,12 +19,16 @@
 import static android.Manifest.permission.NETWORK_STATS_PROVIDER;
 import static android.Manifest.permission.READ_NETWORK_USAGE_HISTORY;
 import static android.Manifest.permission.UPDATE_DEVICE_STATS;
+import static android.app.usage.NetworkStatsManager.PREFIX_DEV;
+import static android.app.usage.NetworkStatsManager.PREFIX_UID;
+import static android.app.usage.NetworkStatsManager.PREFIX_UID_TAG;
+import static android.app.usage.NetworkStatsManager.PREFIX_XT;
 import static android.content.Intent.ACTION_SHUTDOWN;
 import static android.content.Intent.ACTION_UID_REMOVED;
 import static android.content.Intent.ACTION_USER_REMOVED;
 import static android.content.Intent.EXTRA_UID;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
-import static android.net.NetworkIdentity.SUBTYPE_COMBINED;
+import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
 import static android.net.NetworkStats.DEFAULT_NETWORK_ALL;
 import static android.net.NetworkStats.IFACE_ALL;
 import static android.net.NetworkStats.IFACE_VT;
@@ -44,25 +48,9 @@
 import static android.net.NetworkTemplate.buildTemplateWifiWildcard;
 import static android.net.TrafficStats.KB_IN_BYTES;
 import static android.net.TrafficStats.MB_IN_BYTES;
+import static android.net.TrafficStats.UID_TETHERING;
 import static android.net.TrafficStats.UNSUPPORTED;
 import static android.os.Trace.TRACE_TAG_NETWORK;
-import static android.provider.Settings.Global.NETSTATS_AUGMENT_ENABLED;
-import static android.provider.Settings.Global.NETSTATS_COMBINE_SUBTYPE_ENABLED;
-import static android.provider.Settings.Global.NETSTATS_DEV_BUCKET_DURATION;
-import static android.provider.Settings.Global.NETSTATS_DEV_DELETE_AGE;
-import static android.provider.Settings.Global.NETSTATS_DEV_PERSIST_BYTES;
-import static android.provider.Settings.Global.NETSTATS_DEV_ROTATE_AGE;
-import static android.provider.Settings.Global.NETSTATS_GLOBAL_ALERT_BYTES;
-import static android.provider.Settings.Global.NETSTATS_POLL_INTERVAL;
-import static android.provider.Settings.Global.NETSTATS_SAMPLE_ENABLED;
-import static android.provider.Settings.Global.NETSTATS_UID_BUCKET_DURATION;
-import static android.provider.Settings.Global.NETSTATS_UID_DELETE_AGE;
-import static android.provider.Settings.Global.NETSTATS_UID_PERSIST_BYTES;
-import static android.provider.Settings.Global.NETSTATS_UID_ROTATE_AGE;
-import static android.provider.Settings.Global.NETSTATS_UID_TAG_BUCKET_DURATION;
-import static android.provider.Settings.Global.NETSTATS_UID_TAG_DELETE_AGE;
-import static android.provider.Settings.Global.NETSTATS_UID_TAG_PERSIST_BYTES;
-import static android.provider.Settings.Global.NETSTATS_UID_TAG_ROTATE_AGE;
 import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
 import static android.text.format.DateUtils.DAY_IN_MILLIS;
 import static android.text.format.DateUtils.HOUR_IN_MILLIS;
@@ -70,7 +58,7 @@
 import static android.text.format.DateUtils.SECOND_IN_MILLIS;
 
 import static com.android.net.module.util.NetworkCapabilitiesUtils.getDisplayTransport;
-import static com.android.server.NetworkManagementService.LIMIT_GLOBAL_ALERT;
+import static com.android.net.module.util.NetworkStatsUtils.LIMIT_GLOBAL_ALERT;
 import static com.android.server.NetworkManagementSocketTagger.resetKernelUidStats;
 import static com.android.server.NetworkManagementSocketTagger.setKernelCounterSet;
 
@@ -89,13 +77,13 @@
 import android.database.ContentObserver;
 import android.net.DataUsageRequest;
 import android.net.INetd;
-import android.net.INetworkManagementEventObserver;
 import android.net.INetworkStatsService;
 import android.net.INetworkStatsSession;
 import android.net.Network;
 import android.net.NetworkCapabilities;
 import android.net.NetworkIdentity;
 import android.net.NetworkIdentitySet;
+import android.net.NetworkPolicyManager;
 import android.net.NetworkSpecifier;
 import android.net.NetworkStack;
 import android.net.NetworkStateSnapshot;
@@ -106,10 +94,12 @@
 import android.net.NetworkStatsHistory;
 import android.net.NetworkTemplate;
 import android.net.TelephonyNetworkSpecifier;
+import android.net.TetherStatsParcel;
 import android.net.TetheringManager;
 import android.net.TrafficStats;
 import android.net.UnderlyingNetworkInfo;
 import android.net.Uri;
+import android.net.netstats.IUsageCallback;
 import android.net.netstats.provider.INetworkStatsProvider;
 import android.net.netstats.provider.INetworkStatsProviderCallback;
 import android.net.netstats.provider.NetworkStatsProvider;
@@ -117,15 +107,13 @@
 import android.os.DropBoxManager;
 import android.os.Environment;
 import android.os.Handler;
-import android.os.HandlerExecutor;
 import android.os.HandlerThread;
 import android.os.IBinder;
-import android.os.INetworkManagementService;
 import android.os.Looper;
 import android.os.Message;
-import android.os.Messenger;
 import android.os.PowerManager;
 import android.os.RemoteException;
+import android.os.ServiceSpecificException;
 import android.os.SystemClock;
 import android.os.Trace;
 import android.os.UserHandle;
@@ -148,13 +136,13 @@
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.FileRotator;
+import com.android.net.module.util.BaseNetdUnsolicitedEventListener;
 import com.android.net.module.util.BestClock;
 import com.android.net.module.util.BinderUtils;
 import com.android.net.module.util.CollectionUtils;
+import com.android.net.module.util.LocationPermissionChecker;
 import com.android.net.module.util.NetworkStatsUtils;
 import com.android.net.module.util.PermissionUtils;
-import com.android.server.EventLogTags;
-import com.android.server.LocalServices;
 
 import java.io.File;
 import java.io.FileDescriptor;
@@ -207,8 +195,19 @@
 
     private static final String TAG_NETSTATS_ERROR = "netstats_error";
 
+    /**
+     * EventLog tags used when logging into the event log. Note the values must be sync with
+     * frameworks/base/services/core/java/com/android/server/EventLogTags.logtags to get correct
+     * name translation.
+      */
+    private static final int LOG_TAG_NETSTATS_MOBILE_SAMPLE = 51100;
+    private static final int LOG_TAG_NETSTATS_WIFI_SAMPLE = 51101;
+
+    // TODO: Replace the hardcoded string and move it into ConnectivitySettingsManager.
+    private static final String NETSTATS_COMBINE_SUBTYPE_ENABLED =
+            "netstats_combine_subtype_enabled";
+
     private final Context mContext;
-    private final INetworkManagementService mNetworkManager;
     private final NetworkStatsFactory mStatsFactory;
     private final AlarmManager mAlarmManager;
     private final Clock mClock;
@@ -223,6 +222,9 @@
     private final ContentObserver mContentObserver;
     private final ContentResolver mContentResolver;
 
+    protected INetd mNetd;
+    private final AlertObserver mAlertObserver = new AlertObserver();
+
     @VisibleForTesting
     public static final String ACTION_NETWORK_STATS_POLL =
             "com.android.server.action.NETWORK_STATS_POLL";
@@ -231,11 +233,6 @@
 
     private PendingIntent mPollIntent;
 
-    private static final String PREFIX_DEV = "dev";
-    private static final String PREFIX_XT = "xt";
-    private static final String PREFIX_UID = "uid";
-    private static final String PREFIX_UID_TAG = "uid_tag";
-
     /**
      * Settings that can be changed externally.
      */
@@ -245,9 +242,9 @@
         boolean getSampleEnabled();
         boolean getAugmentEnabled();
         /**
-         * When enabled, all mobile data is reported under {@link NetworkIdentity#SUBTYPE_COMBINED}.
-         * When disabled, mobile data is broken down by a granular subtype representative of the
-         * actual subtype. {@see NetworkTemplate#getCollapsedRatType}.
+         * When enabled, all mobile data is reported under {@link NetworkTemplate#NETWORK_TYPE_ALL}.
+         * When disabled, mobile data is broken down by a granular ratType representative of the
+         * actual ratType. {@see NetworkTemplate#getCollapsedRatType}.
          * Enabling this decreases the level of detail but saves performance, disk space and
          * amount of data logged.
          */
@@ -294,6 +291,9 @@
     /** Set of any ifaces associated with mobile networks since boot. */
     private volatile String[] mMobileIfaces = new String[0];
 
+    /** Set of any ifaces associated with wifi networks since boot. */
+    private volatile String[] mWifiIfaces = new String[0];
+
     /** Set of all ifaces currently used by traffic that does not explicitly specify a Network. */
     @GuardedBy("mStatsLock")
     private Network[] mDefaultNetworks = new Network[0];
@@ -354,6 +354,12 @@
     @NonNull
     private final NetworkStatsSubscriptionsMonitor mNetworkStatsSubscriptionsMonitor;
 
+    @NonNull
+    private final LocationPermissionChecker mLocationPermissionChecker;
+
+    @NonNull
+    private final BpfInterfaceMapUpdater mInterfaceMapUpdater;
+
     private static @NonNull File getDefaultSystemDir() {
         return new File(Environment.getDataDirectory(), "system");
     }
@@ -405,20 +411,20 @@
         }
     }
 
-    public static NetworkStatsService create(Context context,
-                INetworkManagementService networkManager) {
+    /** Creates a new NetworkStatsService */
+    public static NetworkStatsService create(Context context) {
         AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
         PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
         PowerManager.WakeLock wakeLock =
                 powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
         final INetd netd = INetd.Stub.asInterface(
                 (IBinder) context.getSystemService(Context.NETD_SERVICE));
-        final NetworkStatsService service = new NetworkStatsService(context, networkManager,
+        final NetworkStatsService service = new NetworkStatsService(context,
+                INetd.Stub.asInterface((IBinder) context.getSystemService(Context.NETD_SERVICE)),
                 alarmManager, wakeLock, getDefaultClock(),
-                new DefaultNetworkStatsSettings(context), new NetworkStatsFactory(netd),
+                new DefaultNetworkStatsSettings(), new NetworkStatsFactory(context),
                 new NetworkStatsObservers(), getDefaultSystemDir(), getDefaultBaseDir(),
                 new Dependencies());
-        service.registerLocalService();
 
         return service;
     }
@@ -426,14 +432,12 @@
     // This must not be called outside of tests, even within the same package, as this constructor
     // does not register the local service. Use the create() helper above.
     @VisibleForTesting
-    NetworkStatsService(Context context, INetworkManagementService networkManager,
-            AlarmManager alarmManager, PowerManager.WakeLock wakeLock, Clock clock,
-            NetworkStatsSettings settings, NetworkStatsFactory factory,
-            NetworkStatsObservers statsObservers, File systemDir, File baseDir,
-            @NonNull Dependencies deps) {
+    NetworkStatsService(Context context, INetd netd, AlarmManager alarmManager,
+            PowerManager.WakeLock wakeLock, Clock clock, NetworkStatsSettings settings,
+            NetworkStatsFactory factory, NetworkStatsObservers statsObservers, File systemDir,
+            File baseDir, @NonNull Dependencies deps) {
         mContext = Objects.requireNonNull(context, "missing Context");
-        mNetworkManager = Objects.requireNonNull(networkManager,
-                "missing INetworkManagementService");
+        mNetd = Objects.requireNonNull(netd, "missing Netd");
         mAlarmManager = Objects.requireNonNull(alarmManager, "missing AlarmManager");
         mClock = Objects.requireNonNull(clock, "missing Clock");
         mSettings = Objects.requireNonNull(settings, "missing NetworkStatsSettings");
@@ -448,10 +452,13 @@
         handlerThread.start();
         mHandler = new NetworkStatsHandler(handlerThread.getLooper());
         mNetworkStatsSubscriptionsMonitor = deps.makeSubscriptionsMonitor(mContext,
-                new HandlerExecutor(mHandler), this);
+                (command) -> mHandler.post(command) , this);
         mContentResolver = mContext.getContentResolver();
         mContentObserver = mDeps.makeContentObserver(mHandler, mSettings,
                 mNetworkStatsSubscriptionsMonitor);
+        mLocationPermissionChecker = mDeps.makeLocationPermissionChecker(mContext);
+        mInterfaceMapUpdater = mDeps.makeBpfInterfaceMapUpdater(mContext, mHandler);
+        mInterfaceMapUpdater.start();
     }
 
     /**
@@ -499,11 +506,40 @@
                 }
             };
         }
+
+        /**
+         * @see LocationPermissionChecker
+         */
+        public LocationPermissionChecker makeLocationPermissionChecker(final Context context) {
+            return new LocationPermissionChecker(context);
+        }
+
+        /** Create BpfInterfaceMapUpdater to update bpf interface map. */
+        @NonNull
+        public BpfInterfaceMapUpdater makeBpfInterfaceMapUpdater(
+                @NonNull Context ctx, @NonNull Handler handler) {
+            return new BpfInterfaceMapUpdater(ctx, handler);
+        }
     }
 
-    private void registerLocalService() {
-        LocalServices.addService(NetworkStatsManagerInternal.class,
-                new NetworkStatsManagerInternalImpl());
+    /**
+     * Observer that watches for {@link INetdUnsolicitedEventListener} alerts.
+     */
+    @VisibleForTesting
+    public class AlertObserver extends BaseNetdUnsolicitedEventListener {
+        @Override
+        public void onQuotaLimitReached(@NonNull String alertName, @NonNull String ifName) {
+            PermissionUtils.enforceNetworkStackPermission(mContext);
+
+            if (LIMIT_GLOBAL_ALERT.equals(alertName)) {
+                // kick off background poll to collect network stats unless there is already
+                // such a call pending; UID stats are handled during normal polling interval.
+                if (!mHandler.hasMessages(MSG_PERFORM_POLL_REGISTER_ALERT)) {
+                    mHandler.sendEmptyMessageDelayed(MSG_PERFORM_POLL_REGISTER_ALERT,
+                            mSettings.getPollDelay());
+                }
+            }
+        }
     }
 
     public void systemReady() {
@@ -532,7 +568,7 @@
         // watch for tethering changes
         final TetheringManager tetheringManager = mContext.getSystemService(TetheringManager.class);
         tetheringManager.registerTetheringEventCallback(
-                new HandlerExecutor(mHandler), mTetherListener);
+                (command) -> mHandler.post(command), mTetherListener);
 
         // listen for periodic polling events
         final IntentFilter pollFilter = new IntentFilter(ACTION_NETWORK_STATS_POLL);
@@ -551,9 +587,9 @@
         mContext.registerReceiver(mShutdownReceiver, shutdownFilter);
 
         try {
-            mNetworkManager.registerObserver(mAlertObserver);
-        } catch (RemoteException e) {
-            // ignored; service lives in system_server
+            mNetd.registerUnsolicitedEventListener(mAlertObserver);
+        } catch (RemoteException | ServiceSpecificException e) {
+            Log.wtf(TAG, "Error registering event listener :", e);
         }
 
         //  schedule periodic pall alarm based on {@link NetworkStatsSettings#getPollInterval()}.
@@ -566,13 +602,13 @@
                 mSettings.getPollInterval(), pollIntent);
 
         mContentResolver.registerContentObserver(Settings.Global
-                .getUriFor(Settings.Global.NETSTATS_COMBINE_SUBTYPE_ENABLED),
+                .getUriFor(NETSTATS_COMBINE_SUBTYPE_ENABLED),
                         false /* notifyForDescendants */, mContentObserver);
 
         // Post a runnable on handler thread to call onChange(). It's for getting current value of
         // NETSTATS_COMBINE_SUBTYPE_ENABLED to decide start or stop monitoring RAT type changes.
         mHandler.post(() -> mContentObserver.onChange(false, Settings.Global
-                .getUriFor(Settings.Global.NETSTATS_COMBINE_SUBTYPE_ENABLED)));
+                .getUriFor(NETSTATS_COMBINE_SUBTYPE_ENABLED)));
 
         registerGlobalAlert();
     }
@@ -641,13 +677,13 @@
     }
 
     /**
-     * Register for a global alert that is delivered through {@link INetworkManagementEventObserver}
+     * Register for a global alert that is delivered through {@link AlertObserver}
      * or {@link NetworkStatsProviderCallback#onAlertReached()} once a threshold amount of data has
      * been transferred.
      */
     private void registerGlobalAlert() {
         try {
-            mNetworkManager.setGlobalAlert(mGlobalAlertBytes);
+            mNetd.bandwidthSetGlobalAlert(mGlobalAlertBytes);
         } catch (IllegalStateException e) {
             Log.w(TAG, "problem registering for global alert: " + e);
         } catch (RemoteException e) {
@@ -683,12 +719,25 @@
         return now - lastCallTime < POLL_RATE_LIMIT_MS;
     }
 
-    private INetworkStatsSession openSessionInternal(final int flags, final String callingPackage) {
+    private int restrictFlagsForCaller(int flags) {
+        // All non-privileged callers are not allowed to turn off POLL_ON_OPEN.
+        final boolean isPrivileged = PermissionUtils.checkAnyPermissionOf(mContext,
+                NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
+                android.Manifest.permission.NETWORK_STACK);
+        if (!isPrivileged) {
+            flags |= NetworkStatsManager.FLAG_POLL_ON_OPEN;
+        }
+        // Non-system uids are rate limited for POLL_ON_OPEN.
         final int callingUid = Binder.getCallingUid();
-        final int usedFlags = isRateLimitedForPoll(callingUid)
+        flags = isRateLimitedForPoll(callingUid)
                 ? flags & (~NetworkStatsManager.FLAG_POLL_ON_OPEN)
                 : flags;
-        if ((usedFlags & (NetworkStatsManager.FLAG_POLL_ON_OPEN
+        return flags;
+    }
+
+    private INetworkStatsSession openSessionInternal(final int flags, final String callingPackage) {
+        final int restrictedFlags = restrictFlagsForCaller(flags);
+        if ((restrictedFlags & (NetworkStatsManager.FLAG_POLL_ON_OPEN
                 | NetworkStatsManager.FLAG_POLL_FORCE)) != 0) {
             final long ident = Binder.clearCallingIdentity();
             try {
@@ -702,7 +751,7 @@
         // for its lifetime; when caller closes only weak references remain.
 
         return new INetworkStatsSession.Stub() {
-            private final int mCallingUid = callingUid;
+            private final int mCallingUid = Binder.getCallingUid();
             private final String mCallingPackage = callingPackage;
             private final @NetworkStatsAccess.Level int mAccessLevel = checkAccessLevel(
                     callingPackage);
@@ -736,26 +785,41 @@
             @Override
             public NetworkStats getDeviceSummaryForNetwork(
                     NetworkTemplate template, long start, long end) {
-                return internalGetSummaryForNetwork(template, usedFlags, start, end, mAccessLevel,
-                        mCallingUid);
+                enforceTemplatePermissions(template, callingPackage);
+                return internalGetSummaryForNetwork(template, restrictedFlags, start, end,
+                        mAccessLevel, mCallingUid);
             }
 
             @Override
             public NetworkStats getSummaryForNetwork(
                     NetworkTemplate template, long start, long end) {
-                return internalGetSummaryForNetwork(template, usedFlags, start, end, mAccessLevel,
-                        mCallingUid);
+                enforceTemplatePermissions(template, callingPackage);
+                return internalGetSummaryForNetwork(template, restrictedFlags, start, end,
+                        mAccessLevel, mCallingUid);
+            }
+
+            // TODO: Remove this after all callers are removed.
+            @Override
+            public NetworkStatsHistory getHistoryForNetwork(NetworkTemplate template, int fields) {
+                enforceTemplatePermissions(template, callingPackage);
+                return internalGetHistoryForNetwork(template, restrictedFlags, fields,
+                        mAccessLevel, mCallingUid, Long.MIN_VALUE, Long.MAX_VALUE);
             }
 
             @Override
-            public NetworkStatsHistory getHistoryForNetwork(NetworkTemplate template, int fields) {
-                return internalGetHistoryForNetwork(template, usedFlags, fields, mAccessLevel,
-                        mCallingUid);
+            public NetworkStatsHistory getHistoryIntervalForNetwork(NetworkTemplate template,
+                    int fields, long start, long end) {
+                enforceTemplatePermissions(template, callingPackage);
+                // TODO(b/200768422): Redact returned history if the template is location
+                //  sensitive but the caller is not privileged.
+                return internalGetHistoryForNetwork(template, restrictedFlags, fields,
+                        mAccessLevel, mCallingUid, start, end);
             }
 
             @Override
             public NetworkStats getSummaryForAllUid(
                     NetworkTemplate template, long start, long end, boolean includeTags) {
+                enforceTemplatePermissions(template, callingPackage);
                 try {
                     final NetworkStats stats = getUidComplete()
                             .getSummary(template, start, end, mAccessLevel, mCallingUid);
@@ -766,8 +830,19 @@
                     }
                     return stats;
                 } catch (NullPointerException e) {
-                    // TODO: Track down and fix the cause of this crash and remove this catch block.
-                    Log.wtf(TAG, "NullPointerException in getSummaryForAllUid", e);
+                    throw e;
+                }
+            }
+
+            @Override
+            public NetworkStats getTaggedSummaryForAllUid(
+                    NetworkTemplate template, long start, long end) {
+                enforceTemplatePermissions(template, callingPackage);
+                try {
+                    final NetworkStats tagStats = getUidTagComplete()
+                            .getSummary(template, start, end, mAccessLevel, mCallingUid);
+                    return tagStats;
+                } catch (NullPointerException e) {
                     throw e;
                 }
             }
@@ -775,6 +850,7 @@
             @Override
             public NetworkStatsHistory getHistoryForUid(
                     NetworkTemplate template, int uid, int set, int tag, int fields) {
+                enforceTemplatePermissions(template, callingPackage);
                 // NOTE: We don't augment UID-level statistics
                 if (tag == TAG_NONE) {
                     return getUidComplete().getHistory(template, null, uid, set, tag, fields,
@@ -789,6 +865,9 @@
             public NetworkStatsHistory getHistoryIntervalForUid(
                     NetworkTemplate template, int uid, int set, int tag, int fields,
                     long start, long end) {
+                enforceTemplatePermissions(template, callingPackage);
+                // TODO(b/200768422): Redact returned history if the template is location
+                //  sensitive but the caller is not privileged.
                 // NOTE: We don't augment UID-level statistics
                 if (tag == TAG_NONE) {
                     return getUidComplete().getHistory(template, null, uid, set, tag, fields,
@@ -810,6 +889,26 @@
         };
     }
 
+    private void enforceTemplatePermissions(@NonNull NetworkTemplate template,
+            @NonNull String callingPackage) {
+        // For a template with wifi network keys, it is possible for a malicious
+        // client to track the user locations via querying data usage. Thus, enforce
+        // fine location permission check.
+        if (!template.getWifiNetworkKeys().isEmpty()) {
+            final boolean canAccessFineLocation = mLocationPermissionChecker
+                    .checkCallersLocationPermission(callingPackage,
+                    null /* featureId */,
+                            Binder.getCallingUid(),
+                            false /* coarseForTargetSdkLessThanQ */,
+                            null /* message */);
+            if (!canAccessFineLocation) {
+                throw new SecurityException("Access fine location is required when querying"
+                        + " with wifi network keys, make sure the app has the necessary"
+                        + "permissions and the location toggle is on.");
+            }
+        }
+    }
+
     private @NetworkStatsAccess.Level int checkAccessLevel(String callingPackage) {
         return NetworkStatsAccess.checkAccessLevel(
                 mContext, Binder.getCallingPid(), Binder.getCallingUid(), callingPackage);
@@ -827,7 +926,7 @@
             if (LOGD) Log.d(TAG, "Resolving plan for " + template);
             final long token = Binder.clearCallingIdentity();
             try {
-                plan = LocalServices.getService(NetworkPolicyManagerInternal.class)
+                plan = mContext.getSystemService(NetworkPolicyManager.class)
                         .getSubscriptionPlan(template);
             } finally {
                 Binder.restoreCallingIdentity(token);
@@ -846,7 +945,7 @@
         // We've been using pure XT stats long enough that we no longer need to
         // splice DEV and XT together.
         final NetworkStatsHistory history = internalGetHistoryForNetwork(template, flags, FIELD_ALL,
-                accessLevel, callingUid);
+                accessLevel, callingUid, start, end);
 
         final long now = System.currentTimeMillis();
         final NetworkStatsHistory.Entry entry = history.getValues(start, end, now, null);
@@ -863,14 +962,14 @@
      * appropriate.
      */
     private NetworkStatsHistory internalGetHistoryForNetwork(NetworkTemplate template,
-            int flags, int fields, @NetworkStatsAccess.Level int accessLevel, int callingUid) {
+            int flags, int fields, @NetworkStatsAccess.Level int accessLevel, int callingUid,
+            long start, long end) {
         // We've been using pure XT stats long enough that we no longer need to
         // splice DEV and XT together.
         final SubscriptionPlan augmentPlan = resolveSubscriptionPlan(template, flags);
         synchronized (mStatsLock) {
             return mXtStatsCached.getHistory(template, augmentPlan,
-                    UID_ALL, SET_ALL, TAG_NONE, fields, Long.MIN_VALUE, Long.MAX_VALUE,
-                    accessLevel, callingUid);
+                    UID_ALL, SET_ALL, TAG_NONE, fields, start, end, accessLevel, callingUid);
         }
     }
 
@@ -901,8 +1000,17 @@
         }
 
         // TODO: switch to data layer stats once kernel exports
-        // for now, read network layer stats and flatten across all ifaces
-        final NetworkStats networkLayer = readNetworkStatsUidDetail(uid, INTERFACES_ALL, TAG_ALL);
+        // for now, read network layer stats and flatten across all ifaces.
+        // This function is used to query NeworkStats for calle's uid. The only caller method
+        // TrafficStats#getDataLayerSnapshotForUid alrady claim no special permission to query
+        // its own NetworkStats.
+        final long ident = Binder.clearCallingIdentity();
+        final NetworkStats networkLayer;
+        try {
+            networkLayer = readNetworkStatsUidDetail(uid, INTERFACES_ALL, TAG_ALL);
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
 
         // splice in operation counts
         networkLayer.spliceOperationsFrom(mUidOperations);
@@ -921,11 +1029,15 @@
     }
 
     @Override
-    public NetworkStats getDetailedUidStats(String[] requiredIfaces) {
+    public NetworkStats getUidStatsForTransport(int transport) {
         enforceAnyPermissionOf(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
         try {
+            final String[] relevantIfaces =
+                    transport == TRANSPORT_WIFI ? mWifiIfaces : mMobileIfaces;
+            // TODO(b/215633405) : mMobileIfaces and mWifiIfaces already contain the stacked
+            // interfaces, so this is not useful, remove it.
             final String[] ifacesToQuery =
-                    mStatsFactory.augmentWithStackedInterfaces(requiredIfaces);
+                    mStatsFactory.augmentWithStackedInterfaces(relevantIfaces);
             return getNetworkStatsUidDetail(ifacesToQuery);
         } catch (RemoteException e) {
             Log.wtf(TAG, "Error compiling UID stats", e);
@@ -966,7 +1078,8 @@
     }
 
     @VisibleForTesting
-    void setUidForeground(int uid, boolean uidForeground) {
+    public void setUidForeground(int uid, boolean uidForeground) {
+        PermissionUtils.enforceNetworkStackPermission(mContext);
         synchronized (mStatsLock) {
             final int set = uidForeground ? SET_FOREGROUND : SET_DEFAULT;
             final int oldSet = mActiveUidCounterSet.get(uid, SET_DEFAULT);
@@ -1002,7 +1115,7 @@
 
     @Override
     public void forceUpdate() {
-        mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
+        PermissionUtils.enforceNetworkStackPermission(mContext);
 
         final long token = Binder.clearCallingIdentity();
         try {
@@ -1012,7 +1125,9 @@
         }
     }
 
-    private void advisePersistThreshold(long thresholdBytes) {
+    /** Advise persistence threshold; may be overridden internally. */
+    public void advisePersistThreshold(long thresholdBytes) {
+        PermissionUtils.enforceNetworkStackPermission(mContext);
         // clamp threshold into safe range
         mPersistThreshold = NetworkStatsUtils.constrain(thresholdBytes,
                 128 * KB_IN_BYTES, 2 * MB_IN_BYTES);
@@ -1042,21 +1157,20 @@
     }
 
     @Override
-    public DataUsageRequest registerUsageCallback(String callingPackage,
-                DataUsageRequest request, Messenger messenger, IBinder binder) {
+    public DataUsageRequest registerUsageCallback(@NonNull String callingPackage,
+                @NonNull DataUsageRequest request, @NonNull IUsageCallback callback) {
         Objects.requireNonNull(callingPackage, "calling package is null");
         Objects.requireNonNull(request, "DataUsageRequest is null");
         Objects.requireNonNull(request.template, "NetworkTemplate is null");
-        Objects.requireNonNull(messenger, "messenger is null");
-        Objects.requireNonNull(binder, "binder is null");
+        Objects.requireNonNull(callback, "callback is null");
 
         int callingUid = Binder.getCallingUid();
         @NetworkStatsAccess.Level int accessLevel = checkAccessLevel(callingPackage);
         DataUsageRequest normalizedRequest;
         final long token = Binder.clearCallingIdentity();
         try {
-            normalizedRequest = mStatsObservers.register(request, messenger, binder,
-                    callingUid, accessLevel);
+            normalizedRequest = mStatsObservers.register(
+                    request, callback, callingUid, accessLevel);
         } finally {
             Binder.restoreCallingIdentity(token);
         }
@@ -1227,26 +1341,6 @@
     };
 
     /**
-     * Observer that watches for {@link INetworkManagementService} alerts.
-     */
-    private final INetworkManagementEventObserver mAlertObserver = new BaseNetworkObserver() {
-        @Override
-        public void limitReached(String limitName, String iface) {
-            // only someone like NMS should be calling us
-            PermissionUtils.enforceNetworkStackPermission(mContext);
-
-            if (LIMIT_GLOBAL_ALERT.equals(limitName)) {
-                // kick off background poll to collect network stats unless there is already
-                // such a call pending; UID stats are handled during normal polling interval.
-                if (!mHandler.hasMessages(MSG_PERFORM_POLL_REGISTER_ALERT)) {
-                    mHandler.sendEmptyMessageDelayed(MSG_PERFORM_POLL_REGISTER_ALERT,
-                            mSettings.getPollDelay());
-                }
-            }
-        }
-    };
-
-    /**
      * Handle collapsed RAT type changed event.
      */
     @VisibleForTesting
@@ -1301,16 +1395,18 @@
 
         final boolean combineSubtypeEnabled = mSettings.getCombineSubtypeEnabled();
         final ArraySet<String> mobileIfaces = new ArraySet<>();
+        final ArraySet<String> wifiIfaces = new ArraySet<>();
         for (NetworkStateSnapshot snapshot : snapshots) {
             final int displayTransport =
                     getDisplayTransport(snapshot.getNetworkCapabilities().getTransportTypes());
             final boolean isMobile = (NetworkCapabilities.TRANSPORT_CELLULAR == displayTransport);
+            final boolean isWifi = (NetworkCapabilities.TRANSPORT_WIFI == displayTransport);
             final boolean isDefault = CollectionUtils.contains(
                     mDefaultNetworks, snapshot.getNetwork());
-            final int subType = combineSubtypeEnabled ? SUBTYPE_COMBINED
-                    : getSubTypeForStateSnapshot(snapshot);
+            final int ratType = combineSubtypeEnabled ? NetworkTemplate.NETWORK_TYPE_ALL
+                    : getRatTypeForStateSnapshot(snapshot);
             final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, snapshot,
-                    isDefault, subType);
+                    isDefault, ratType);
 
             // Traffic occurring on the base interface is always counted for
             // both total usage and UID details.
@@ -1325,12 +1421,12 @@
                 // VT is considered always metered in framework's layer. If VT is not metered
                 // per carrier's policy, modem will report 0 usage for VT calls.
                 if (snapshot.getNetworkCapabilities().hasCapability(
-                        NetworkCapabilities.NET_CAPABILITY_IMS) && !ident.getMetered()) {
+                        NetworkCapabilities.NET_CAPABILITY_IMS) && !ident.isMetered()) {
 
                     // Copy the identify from IMS one but mark it as metered.
                     NetworkIdentity vtIdent = new NetworkIdentity(ident.getType(),
-                            ident.getSubType(), ident.getSubscriberId(), ident.getNetworkId(),
-                            ident.getRoaming(), true /* metered */,
+                            ident.getRatType(), ident.getSubscriberId(), ident.getWifiNetworkKey(),
+                            ident.isRoaming(), true /* metered */,
                             true /* onDefaultNetwork */, ident.getOemManaged());
                     final String ifaceVt = IFACE_VT + getSubIdForMobile(snapshot);
                     findOrCreateNetworkIdentitySet(mActiveIfaces, ifaceVt).add(vtIdent);
@@ -1340,6 +1436,9 @@
                 if (isMobile) {
                     mobileIfaces.add(baseIface);
                 }
+                if (isWifi) {
+                    wifiIfaces.add(baseIface);
+                }
             }
 
             // Traffic occurring on stacked interfaces is usually clatd.
@@ -1381,6 +1480,9 @@
                     if (isMobile) {
                         mobileIfaces.add(iface);
                     }
+                    if (isWifi) {
+                        wifiIfaces.add(iface);
+                    }
 
                     mStatsFactory.noteStackedIface(iface, baseIface);
                 }
@@ -1388,11 +1490,16 @@
         }
 
         mMobileIfaces = mobileIfaces.toArray(new String[0]);
+        mWifiIfaces = wifiIfaces.toArray(new String[0]);
         // TODO (b/192758557): Remove debug log.
         if (CollectionUtils.contains(mMobileIfaces, null)) {
             throw new NullPointerException(
                     "null element in mMobileIfaces: " + Arrays.toString(mMobileIfaces));
         }
+        if (CollectionUtils.contains(mWifiIfaces, null)) {
+            throw new NullPointerException(
+                    "null element in mWifiIfaces: " + Arrays.toString(mWifiIfaces));
+        }
     }
 
     private static int getSubIdForMobile(@NonNull NetworkStateSnapshot state) {
@@ -1410,11 +1517,11 @@
     }
 
     /**
-     * For networks with {@code TRANSPORT_CELLULAR}, get subType that was obtained through
+     * For networks with {@code TRANSPORT_CELLULAR}, get ratType that was obtained through
      * {@link PhoneStateListener}. Otherwise, return 0 given that other networks with different
      * transport types do not actually fill this value.
      */
-    private int getSubTypeForStateSnapshot(@NonNull NetworkStateSnapshot state) {
+    private int getRatTypeForStateSnapshot(@NonNull NetworkStateSnapshot state) {
         if (!state.getNetworkCapabilities().hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
             return 0;
         }
@@ -1611,7 +1718,7 @@
         xtTotal = mXtRecorder.getTotalSinceBootLocked(template);
         uidTotal = mUidRecorder.getTotalSinceBootLocked(template);
 
-        EventLogTags.writeNetstatsMobileSample(
+        EventLog.writeEvent(LOG_TAG_NETSTATS_MOBILE_SAMPLE,
                 devTotal.rxBytes, devTotal.rxPackets, devTotal.txBytes, devTotal.txPackets,
                 xtTotal.rxBytes, xtTotal.rxPackets, xtTotal.txBytes, xtTotal.txPackets,
                 uidTotal.rxBytes, uidTotal.rxPackets, uidTotal.txBytes, uidTotal.txPackets,
@@ -1623,7 +1730,7 @@
         xtTotal = mXtRecorder.getTotalSinceBootLocked(template);
         uidTotal = mUidRecorder.getTotalSinceBootLocked(template);
 
-        EventLogTags.writeNetstatsWifiSample(
+        EventLog.writeEvent(LOG_TAG_NETSTATS_WIFI_SAMPLE,
                 devTotal.rxBytes, devTotal.rxPackets, devTotal.txBytes, devTotal.txPackets,
                 xtTotal.rxBytes, xtTotal.rxPackets, xtTotal.txBytes, xtTotal.txPackets,
                 uidTotal.rxBytes, uidTotal.rxPackets, uidTotal.txBytes, uidTotal.txPackets,
@@ -1669,52 +1776,19 @@
         removeUidsLocked(CollectionUtils.toIntArray(uids));
     }
 
-    private class NetworkStatsManagerInternalImpl extends NetworkStatsManagerInternal {
-        @Override
-        public long getNetworkTotalBytes(NetworkTemplate template, long start, long end) {
-            Trace.traceBegin(TRACE_TAG_NETWORK, "getNetworkTotalBytes");
-            try {
-                return NetworkStatsService.this.getNetworkTotalBytes(template, start, end);
-            } finally {
-                Trace.traceEnd(TRACE_TAG_NETWORK);
-            }
+    /**
+     * Set the warning and limit to all registered custom network stats providers.
+     * Note that invocation of any interface will be sent to all providers.
+     */
+    public void setStatsProviderWarningAndLimitAsync(
+            @NonNull String iface, long warning, long limit) {
+        PermissionUtils.enforceNetworkStackPermission(mContext);
+        if (LOGV) {
+            Log.v(TAG, "setStatsProviderWarningAndLimitAsync("
+                    + iface + "," + warning + "," + limit + ")");
         }
-
-        @Override
-        public NetworkStats getNetworkUidBytes(NetworkTemplate template, long start, long end) {
-            Trace.traceBegin(TRACE_TAG_NETWORK, "getNetworkUidBytes");
-            try {
-                return NetworkStatsService.this.getNetworkUidBytes(template, start, end);
-            } finally {
-                Trace.traceEnd(TRACE_TAG_NETWORK);
-            }
-        }
-
-        @Override
-        public void setUidForeground(int uid, boolean uidForeground) {
-            NetworkStatsService.this.setUidForeground(uid, uidForeground);
-        }
-
-        @Override
-        public void advisePersistThreshold(long thresholdBytes) {
-            NetworkStatsService.this.advisePersistThreshold(thresholdBytes);
-        }
-
-        @Override
-        public void forceUpdate() {
-            NetworkStatsService.this.forceUpdate();
-        }
-
-        @Override
-        public void setStatsProviderWarningAndLimitAsync(
-                @NonNull String iface, long warning, long limit) {
-            if (LOGV) {
-                Log.v(TAG, "setStatsProviderWarningAndLimitAsync("
-                        + iface + "," + warning + "," + limit + ")");
-            }
-            invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.onSetWarningAndLimit(iface,
-                    warning, limit));
-        }
+        invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.onSetWarningAndLimit(iface,
+                warning, limit));
     }
 
     @Override
@@ -1957,13 +2031,29 @@
      */
     // TODO: Remove this by implementing {@link NetworkStatsProvider} for non-offloaded
     //  tethering stats.
-    private NetworkStats getNetworkStatsTethering(int how) throws RemoteException {
+    private @NonNull NetworkStats getNetworkStatsTethering(int how) throws RemoteException {
+         // We only need to return per-UID stats. Per-device stats are already counted by
+        // interface counters.
+        if (how != STATS_PER_UID) {
+            return new NetworkStats(SystemClock.elapsedRealtime(), 0);
+        }
+
+        final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 1);
         try {
-            return mNetworkManager.getNetworkStatsTethering(how);
+            final TetherStatsParcel[] tetherStatsParcels = mNetd.tetherGetStats();
+            for (TetherStatsParcel tetherStats : tetherStatsParcels) {
+                try {
+                    stats.combineValues(new NetworkStats.Entry(tetherStats.iface, UID_TETHERING,
+                            SET_DEFAULT, TAG_NONE, tetherStats.rxBytes, tetherStats.rxPackets,
+                            tetherStats.txBytes, tetherStats.txPackets, 0L));
+                } catch (ArrayIndexOutOfBoundsException e) {
+                    throw new IllegalStateException("invalid tethering stats " + e);
+                }
+            }
         } catch (IllegalStateException e) {
             Log.wtf(TAG, "problem reading network stats", e);
-            return new NetworkStats(0L, 10);
         }
+        return stats;
     }
 
     // TODO: It is copied from ConnectivityService, consider refactor these check permission
@@ -2002,10 +2092,12 @@
                 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
         Objects.requireNonNull(provider, "provider is null");
         Objects.requireNonNull(tag, "tag is null");
+        final NetworkPolicyManager netPolicyManager = mContext
+                .getSystemService(NetworkPolicyManager.class);
         try {
             NetworkStatsProviderCallbackImpl callback = new NetworkStatsProviderCallbackImpl(
                     tag, provider, mStatsProviderSem, mAlertObserver,
-                    mStatsProviderCbList);
+                    mStatsProviderCbList, netPolicyManager);
             mStatsProviderCbList.add(callback);
             Log.d(TAG, "registerNetworkStatsProvider from " + callback.mTag + " uid/pid="
                     + getCallingUid() + "/" + getCallingPid());
@@ -2045,8 +2137,9 @@
 
         @NonNull final INetworkStatsProvider mProvider;
         @NonNull private final Semaphore mSemaphore;
-        @NonNull final INetworkManagementEventObserver mAlertObserver;
+        @NonNull final AlertObserver mAlertObserver;
         @NonNull final CopyOnWriteArrayList<NetworkStatsProviderCallbackImpl> mStatsProviderCbList;
+        @NonNull final NetworkPolicyManager mNetworkPolicyManager;
 
         @NonNull private final Object mProviderStatsLock = new Object();
 
@@ -2059,8 +2152,9 @@
         NetworkStatsProviderCallbackImpl(
                 @NonNull String tag, @NonNull INetworkStatsProvider provider,
                 @NonNull Semaphore semaphore,
-                @NonNull INetworkManagementEventObserver alertObserver,
-                @NonNull CopyOnWriteArrayList<NetworkStatsProviderCallbackImpl> cbList)
+                @NonNull AlertObserver alertObserver,
+                @NonNull CopyOnWriteArrayList<NetworkStatsProviderCallbackImpl> cbList,
+                @NonNull NetworkPolicyManager networkPolicyManager)
                 throws RemoteException {
             mTag = tag;
             mProvider = provider;
@@ -2068,6 +2162,7 @@
             mSemaphore = semaphore;
             mAlertObserver = alertObserver;
             mStatsProviderCbList = cbList;
+            mNetworkPolicyManager = networkPolicyManager;
         }
 
         @NonNull
@@ -2107,15 +2202,14 @@
             // This binder object can only have been obtained by a process that holds
             // NETWORK_STATS_PROVIDER. Thus, no additional permission check is required.
             BinderUtils.withCleanCallingIdentity(() ->
-                    mAlertObserver.limitReached(LIMIT_GLOBAL_ALERT, null /* unused */));
+                    mAlertObserver.onQuotaLimitReached(LIMIT_GLOBAL_ALERT, null /* unused */));
         }
 
         @Override
         public void notifyWarningOrLimitReached() {
             Log.d(TAG, mTag + ": notifyWarningOrLimitReached");
             BinderUtils.withCleanCallingIdentity(() ->
-                    LocalServices.getService(NetworkPolicyManagerInternal.class)
-                            .onStatsProviderWarningOrLimitReached(mTag));
+                    mNetworkPolicyManager.notifyStatsProviderWarningOrLimitReached());
         }
 
         @Override
@@ -2174,24 +2268,11 @@
      * {@link android.provider.Settings.Global}.
      */
     private static class DefaultNetworkStatsSettings implements NetworkStatsSettings {
-        private final ContentResolver mResolver;
-
-        public DefaultNetworkStatsSettings(Context context) {
-            mResolver = Objects.requireNonNull(context.getContentResolver());
-            // TODO: adjust these timings for production builds
-        }
-
-        private long getGlobalLong(String name, long def) {
-            return Settings.Global.getLong(mResolver, name, def);
-        }
-        private boolean getGlobalBoolean(String name, boolean def) {
-            final int defInt = def ? 1 : 0;
-            return Settings.Global.getInt(mResolver, name, defInt) != 0;
-        }
+        DefaultNetworkStatsSettings() {}
 
         @Override
         public long getPollInterval() {
-            return getGlobalLong(NETSTATS_POLL_INTERVAL, 30 * MINUTE_IN_MILLIS);
+            return 30 * MINUTE_IN_MILLIS;
         }
         @Override
         public long getPollDelay() {
@@ -2199,25 +2280,23 @@
         }
         @Override
         public long getGlobalAlertBytes(long def) {
-            return getGlobalLong(NETSTATS_GLOBAL_ALERT_BYTES, def);
+            return def;
         }
         @Override
         public boolean getSampleEnabled() {
-            return getGlobalBoolean(NETSTATS_SAMPLE_ENABLED, true);
+            return true;
         }
         @Override
         public boolean getAugmentEnabled() {
-            return getGlobalBoolean(NETSTATS_AUGMENT_ENABLED, true);
+            return true;
         }
         @Override
         public boolean getCombineSubtypeEnabled() {
-            return getGlobalBoolean(NETSTATS_COMBINE_SUBTYPE_ENABLED, false);
+            return false;
         }
         @Override
         public Config getDevConfig() {
-            return new Config(getGlobalLong(NETSTATS_DEV_BUCKET_DURATION, HOUR_IN_MILLIS),
-                    getGlobalLong(NETSTATS_DEV_ROTATE_AGE, 15 * DAY_IN_MILLIS),
-                    getGlobalLong(NETSTATS_DEV_DELETE_AGE, 90 * DAY_IN_MILLIS));
+            return new Config(HOUR_IN_MILLIS, 15 * DAY_IN_MILLIS, 90 * DAY_IN_MILLIS);
         }
         @Override
         public Config getXtConfig() {
@@ -2225,31 +2304,27 @@
         }
         @Override
         public Config getUidConfig() {
-            return new Config(getGlobalLong(NETSTATS_UID_BUCKET_DURATION, 2 * HOUR_IN_MILLIS),
-                    getGlobalLong(NETSTATS_UID_ROTATE_AGE, 15 * DAY_IN_MILLIS),
-                    getGlobalLong(NETSTATS_UID_DELETE_AGE, 90 * DAY_IN_MILLIS));
+            return new Config(2 * HOUR_IN_MILLIS, 15 * DAY_IN_MILLIS, 90 * DAY_IN_MILLIS);
         }
         @Override
         public Config getUidTagConfig() {
-            return new Config(getGlobalLong(NETSTATS_UID_TAG_BUCKET_DURATION, 2 * HOUR_IN_MILLIS),
-                    getGlobalLong(NETSTATS_UID_TAG_ROTATE_AGE, 5 * DAY_IN_MILLIS),
-                    getGlobalLong(NETSTATS_UID_TAG_DELETE_AGE, 15 * DAY_IN_MILLIS));
+            return new Config(2 * HOUR_IN_MILLIS, 5 * DAY_IN_MILLIS, 15 * DAY_IN_MILLIS);
         }
         @Override
         public long getDevPersistBytes(long def) {
-            return getGlobalLong(NETSTATS_DEV_PERSIST_BYTES, def);
+            return def;
         }
         @Override
         public long getXtPersistBytes(long def) {
-            return getDevPersistBytes(def);
+            return def;
         }
         @Override
         public long getUidPersistBytes(long def) {
-            return getGlobalLong(NETSTATS_UID_PERSIST_BYTES, def);
+            return def;
         }
         @Override
         public long getUidTagPersistBytes(long def) {
-            return getGlobalLong(NETSTATS_UID_TAG_PERSIST_BYTES, def);
+            return def;
         }
     }
 
diff --git a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
index a3eb0ecc..ce58ff6 100644
--- a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
+++ b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
@@ -236,7 +236,8 @@
                 root.flags |= Root.FLAG_REMOVABLE_USB;
             }
 
-            if (volume.getType() != VolumeInfo.TYPE_EMULATED) {
+            if (volume.getType() != VolumeInfo.TYPE_EMULATED
+                    && volume.getType() != VolumeInfo.TYPE_STUB) {
                 root.flags |= Root.FLAG_SUPPORTS_EJECT;
             }
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/NetworkPolicyEditor.java b/packages/SettingsLib/src/com/android/settingslib/NetworkPolicyEditor.java
index f5aa652..b4e84dd 100644
--- a/packages/SettingsLib/src/com/android/settingslib/NetworkPolicyEditor.java
+++ b/packages/SettingsLib/src/com/android/settingslib/NetworkPolicyEditor.java
@@ -27,9 +27,7 @@
 import android.net.NetworkPolicy;
 import android.net.NetworkPolicyManager;
 import android.net.NetworkTemplate;
-import android.net.wifi.WifiInfo;
 import android.os.AsyncTask;
-import android.text.TextUtils;
 import android.util.RecurrenceRule;
 
 import com.google.android.collect.Lists;
@@ -124,7 +122,7 @@
         if (policy != null) {
             return policy;
         } else {
-            return getPolicy(buildUnquotedNetworkTemplate(template));
+            return getPolicy(template);
         }
     }
 
@@ -207,21 +205,4 @@
         policy.clearSnooze();
         writeAsync();
     }
-
-    /**
-     * Build a revised {@link NetworkTemplate} that matches the same rule, but
-     * with an unquoted {@link NetworkTemplate#getNetworkId()}. Used to work
-     * around legacy bugs.
-     */
-    private static NetworkTemplate buildUnquotedNetworkTemplate(NetworkTemplate template) {
-        if (template == null) return null;
-        final String networkId = template.getNetworkId();
-        final String strippedNetworkId = WifiInfo.sanitizeSsid(networkId);
-        if (!TextUtils.equals(strippedNetworkId, networkId)) {
-            return new NetworkTemplate(
-                    template.getMatchRule(), template.getSubscriberId(), strippedNetworkId);
-        } else {
-            return null;
-        }
-    }
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/mobile/OWNERS b/packages/SettingsLib/src/com/android/settingslib/mobile/OWNERS
new file mode 100644
index 0000000..ab9b5dc
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/mobile/OWNERS
@@ -0,0 +1,4 @@
+# Default reviewers for this and subdirectories.
+bonianchen@google.com
+
+# Emergency approvers in case the above are not available
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java
index cff45c6..30c6645 100644
--- a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java
+++ b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java
@@ -16,7 +16,6 @@
 
 package com.android.settingslib.net;
 
-import static android.net.TrafficStats.MB_IN_BYTES;
 import static android.telephony.TelephonyManager.SIM_STATE_READY;
 import static android.text.format.DateUtils.FORMAT_ABBREV_MONTH;
 import static android.text.format.DateUtils.FORMAT_SHOW_DATE;
@@ -49,6 +48,7 @@
     private static final StringBuilder PERIOD_BUILDER = new StringBuilder(50);
     private static final java.util.Formatter PERIOD_FORMATTER = new java.util.Formatter(
             PERIOD_BUILDER, Locale.getDefault());
+    private static final long MB_IN_BYTES = 1024 * 1024;
 
     private final Context mContext;
     private final NetworkPolicyManager mPolicyManager;
@@ -237,10 +237,8 @@
         final int matchRule = networkTemplate.getMatchRule();
         switch (matchRule) {
             case NetworkTemplate.MATCH_MOBILE:
-            case NetworkTemplate.MATCH_MOBILE_WILDCARD:
                 return ConnectivityManager.TYPE_MOBILE;
             case NetworkTemplate.MATCH_WIFI:
-            case NetworkTemplate.MATCH_WIFI_WILDCARD:
                 return  ConnectivityManager.TYPE_WIFI;
             case NetworkTemplate.MATCH_ETHERNET:
                 return  ConnectivityManager.TYPE_ETHERNET;
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageUtils.java b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageUtils.java
index afd44d5..386a47a 100644
--- a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageUtils.java
@@ -63,14 +63,32 @@
     private static NetworkTemplate getNormalizedMobileTemplate(
             TelephonyManager telephonyManager, int subId) {
         final NetworkTemplate mobileTemplate = getMobileTemplateForSubId(telephonyManager, subId);
-        final String[] mergedSubscriberIds = telephonyManager
-                .createForSubscriptionId(subId).getMergedImsisFromGroup();
+        final Set<String> mergedSubscriberIds = Set.of(telephonyManager
+                .createForSubscriptionId(subId).getMergedImsisFromGroup());
         if (ArrayUtils.isEmpty(mergedSubscriberIds)) {
             Log.i(TAG, "mergedSubscriberIds is null.");
             return mobileTemplate;
         }
 
-        return NetworkTemplate.normalize(mobileTemplate, mergedSubscriberIds);
+        return normalizeMobileTemplate(mobileTemplate, mergedSubscriberIds);
+    }
+
+    private static NetworkTemplate normalizeMobileTemplate(
+            NetworkTemplate template, Set<String> mergedSet) {
+        if (template.getSubscriberIds().isEmpty()) return template;
+        // The input template should have at most 1 subscriberId.
+        final String subscriberId = template.getSubscriberIds().iterator().next();
+
+        if (mergedSet.contains(subscriberId)) {
+            // Requested template subscriber is part of the merge group; return
+            // a template that matches all merged subscribers.
+            return new NetworkTemplate.Builder(template.getMatchRule())
+                    .setSubscriberIds(mergedSet)
+                    .setWifiNetworkKeys(template.getWifiNetworkKeys())
+                    .setMeteredness(NetworkStats.METERED_YES).build();
+        }
+
+        return template;
     }
 
     private static NetworkTemplate getMobileTemplateForSubId(
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataForUidLoader.java b/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataForUidLoader.java
index 43c05b8..504390c 100644
--- a/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataForUidLoader.java
+++ b/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataForUidLoader.java
@@ -53,8 +53,9 @@
             long totalUsage = 0L;
             long totalForeground = 0L;
             for (int uid : mUids) {
-                final NetworkStats stats = mNetworkStatsManager.queryDetailsForUid(
-                        mNetworkTemplate, start, end, uid);
+                final NetworkStats stats = mNetworkStatsManager.queryDetailsForUidTagState(
+                        mNetworkTemplate, start, end, uid, NetworkStats.Bucket.TAG_NONE,
+                        NetworkStats.Bucket.STATE_ALL);
                 final long usage = getTotalUsage(stats);
                 if (usage > 0L) {
                     totalUsage += usage;
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataLoader.java b/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataLoader.java
index 3e95b01..5e9ac5a 100644
--- a/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataLoader.java
+++ b/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataLoader.java
@@ -16,23 +16,16 @@
 
 package com.android.settingslib.net;
 
-import static android.net.NetworkStatsHistory.FIELD_RX_BYTES;
-import static android.net.NetworkStatsHistory.FIELD_TX_BYTES;
-
+import android.annotation.NonNull;
 import android.app.usage.NetworkStats;
 import android.app.usage.NetworkStatsManager;
 import android.content.Context;
-import android.net.INetworkStatsService;
-import android.net.INetworkStatsSession;
 import android.net.NetworkPolicy;
 import android.net.NetworkPolicyManager;
-import android.net.NetworkStatsHistory;
 import android.net.NetworkTemplate;
-import android.net.TrafficStats;
-import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.text.format.DateUtils;
 import android.util.Pair;
+import android.util.Range;
 
 import androidx.annotation.VisibleForTesting;
 import androidx.loader.content.AsyncTaskLoader;
@@ -52,8 +45,6 @@
     protected final NetworkTemplate mNetworkTemplate;
     private final NetworkPolicy mPolicy;
     private final ArrayList<Long> mCycles;
-    @VisibleForTesting
-    final INetworkStatsService mNetworkStatsService;
 
     protected NetworkCycleDataLoader(Builder<?> builder) {
         super(builder.mContext);
@@ -61,8 +52,6 @@
         mCycles = builder.mCycles;
         mNetworkStatsManager = (NetworkStatsManager)
             builder.mContext.getSystemService(Context.NETWORK_STATS_SERVICE);
-        mNetworkStatsService = INetworkStatsService.Stub.asInterface(
-            ServiceManager.getService(Context.NETWORK_STATS_SERVICE));
         final NetworkPolicyEditor policyEditor =
             new NetworkPolicyEditor(NetworkPolicyManager.from(builder.mContext));
         policyEditor.read();
@@ -112,23 +101,20 @@
 
     @VisibleForTesting
     void loadFourWeeksData() {
+        if (mNetworkTemplate == null) return;
+        final NetworkStats stats = mNetworkStatsManager.queryDetailsForDevice(
+                mNetworkTemplate, Long.MIN_VALUE, Long.MAX_VALUE);
         try {
-            final INetworkStatsSession networkSession = mNetworkStatsService.openSession();
-            final NetworkStatsHistory networkHistory = networkSession.getHistoryForNetwork(
-                mNetworkTemplate, FIELD_RX_BYTES | FIELD_TX_BYTES);
-            final long historyStart = networkHistory.getStart();
-            final long historyEnd = networkHistory.getEnd();
+            final Range<Long> historyTimeRange = getTimeRangeOf(stats);
 
-            long cycleEnd = historyEnd;
-            while (cycleEnd > historyStart) {
+            long cycleEnd = historyTimeRange.getUpper();
+            while (cycleEnd > historyTimeRange.getLower()) {
                 final long cycleStart = cycleEnd - (DateUtils.WEEK_IN_MILLIS * 4);
                 recordUsage(cycleStart, cycleEnd);
                 cycleEnd = cycleStart;
             }
-
-            TrafficStats.closeQuietly(networkSession);
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
+        } catch (IllegalArgumentException e) {
+            // Empty history, ignore.
         }
     }
 
@@ -169,6 +155,32 @@
         return bytes;
     }
 
+    @NonNull
+    @VisibleForTesting
+    Range getTimeRangeOf(@NonNull NetworkStats stats) {
+        long start = Long.MAX_VALUE;
+        long end = Long.MIN_VALUE;
+        while (hasNextBucket(stats)) {
+            final NetworkStats.Bucket bucket = getNextBucket(stats);
+            start = Math.min(start, bucket.getStartTimeStamp());
+            end = Math.max(end, bucket.getEndTimeStamp());
+        }
+        return new Range(start, end);
+    }
+
+    @VisibleForTesting
+    boolean hasNextBucket(@NonNull NetworkStats stats) {
+        return stats.hasNextBucket();
+    }
+
+    @NonNull
+    @VisibleForTesting
+    NetworkStats.Bucket getNextBucket(@NonNull NetworkStats stats) {
+        NetworkStats.Bucket bucket = new NetworkStats.Bucket();
+        stats.getNextBucket(bucket);
+        return bucket;
+    }
+
     @VisibleForTesting(otherwise = VisibleForTesting.NONE)
     public ArrayList<Long> getCycles() {
         return mCycles;
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/OWNERS b/packages/SettingsLib/src/com/android/settingslib/net/OWNERS
new file mode 100644
index 0000000..ab9b5dc
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/net/OWNERS
@@ -0,0 +1,4 @@
+# Default reviewers for this and subdirectories.
+bonianchen@google.com
+
+# Emergency approvers in case the above are not available
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/UidDetailProvider.java b/packages/SettingsLib/src/com/android/settingslib/net/UidDetailProvider.java
index 02326ea..623eb33 100644
--- a/packages/SettingsLib/src/com/android/settingslib/net/UidDetailProvider.java
+++ b/packages/SettingsLib/src/com/android/settingslib/net/UidDetailProvider.java
@@ -17,6 +17,7 @@
 package com.android.settingslib.net;
 
 import android.app.AppGlobals;
+import android.app.usage.NetworkStats;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageManager;
@@ -116,13 +117,13 @@
                 detail.label = res.getString(R.string.process_kernel_label);
                 detail.icon = pm.getDefaultActivityIcon();
                 return detail;
-            case TrafficStats.UID_REMOVED:
+            case NetworkStats.Bucket.UID_REMOVED:
                 detail.label = res.getString(UserManager.supportsMultipleUsers()
                         ? R.string.data_usage_uninstalled_apps_users
                         : R.string.data_usage_uninstalled_apps);
                 detail.icon = pm.getDefaultActivityIcon();
                 return detail;
-            case TrafficStats.UID_TETHERING:
+            case NetworkStats.Bucket.UID_TETHERING:
                 final TetheringManager tm = mContext.getSystemService(TetheringManager.class);
                 detail.label = res.getString(Utils.getTetheringLabel(tm));
                 detail.icon = pm.getDefaultActivityIcon();
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/NetworkCycleDataLoaderTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/NetworkCycleDataLoaderTest.java
index 74b9151..c79440e 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/NetworkCycleDataLoaderTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/NetworkCycleDataLoaderTest.java
@@ -16,24 +16,24 @@
 
 package com.android.settingslib.net;
 
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.nullable;
+import static android.app.usage.NetworkStats.Bucket.UID_ALL;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThrows;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.annotation.NonNull;
+import android.app.usage.NetworkStats;
 import android.app.usage.NetworkStatsManager;
 import android.content.Context;
 import android.net.ConnectivityManager;
-import android.net.INetworkStatsService;
-import android.net.INetworkStatsSession;
 import android.net.NetworkPolicy;
 import android.net.NetworkPolicyManager;
-import android.net.NetworkStatsHistory;
 import android.net.NetworkTemplate;
-import android.os.RemoteException;
 import android.text.format.DateUtils;
 import android.util.Range;
 
@@ -49,6 +49,8 @@
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Queue;
+import java.util.concurrent.LinkedBlockingQueue;
 
 @RunWith(RobolectricTestRunner.class)
 public class NetworkCycleDataLoaderTest {
@@ -63,8 +65,6 @@
     private NetworkPolicy mPolicy;
     @Mock
     private Iterator<Range<ZonedDateTime>> mIterator;
-    @Mock
-    private INetworkStatsService mNetworkStatsService;
 
     private NetworkCycleDataTestLoader mLoader;
 
@@ -132,20 +132,24 @@
         verify(mLoader).recordUsage(nowInMs, nowInMs);
     }
 
+    private NetworkStats.Bucket makeMockBucket(int uid, long rxBytes, long txBytes,
+            long start, long end) {
+        NetworkStats.Bucket ret = mock(NetworkStats.Bucket.class);
+        when(ret.getUid()).thenReturn(uid);
+        when(ret.getRxBytes()).thenReturn(rxBytes);
+        when(ret.getTxBytes()).thenReturn(txBytes);
+        when(ret.getStartTimeStamp()).thenReturn(start);
+        when(ret.getEndTimeStamp()).thenReturn(end);
+        return ret;
+    }
+
     @Test
-    public void loadFourWeeksData_shouldRecordUsageForLast4Weeks() throws RemoteException {
+    public void loadFourWeeksData_shouldRecordUsageForLast4Weeks() {
         mLoader = spy(new NetworkCycleDataTestLoader(mContext));
-        ReflectionHelpers.setField(mLoader, "mNetworkStatsService", mNetworkStatsService);
-        final INetworkStatsSession networkSession = mock(INetworkStatsSession.class);
-        when(mNetworkStatsService.openSession()).thenReturn(networkSession);
-        final NetworkStatsHistory networkHistory = mock(NetworkStatsHistory.class);
-        when(networkSession.getHistoryForNetwork(nullable(NetworkTemplate.class), anyInt()))
-            .thenReturn(networkHistory);
         final long now = System.currentTimeMillis();
         final long fourWeeksAgo = now - (DateUtils.WEEK_IN_MILLIS * 4);
         final long twoDaysAgo = now - (DateUtils.DAY_IN_MILLIS * 2);
-        when(networkHistory.getStart()).thenReturn(twoDaysAgo);
-        when(networkHistory.getEnd()).thenReturn(now);
+        mLoader.addBucket(makeMockBucket(UID_ALL, 123, 456, twoDaysAgo, now));
 
         mLoader.loadFourWeeksData();
 
@@ -173,10 +177,31 @@
         verify(mLoader).recordUsage(thirtyDaysAgo, twentyDaysAgo);
     }
 
+    @Test
+    public void getTimeRangeOf() {
+        mLoader = spy(new NetworkCycleDataTestLoader(mContext));
+        // If empty, new Range(MAX_VALUE, MIN_VALUE) will be constructed. Hence, the function
+        // should throw.
+        assertThrows(IllegalArgumentException.class,
+                () -> mLoader.getTimeRangeOf(mock(NetworkStats.class)));
+
+        mLoader.addBucket(makeMockBucket(UID_ALL, 123, 456, 0, 10));
+        // Feed the function with unused NetworkStats. The actual data injection is
+        // done by addBucket.
+        assertEquals(new Range(0L, 10L), mLoader.getTimeRangeOf(mock(NetworkStats.class)));
+
+        mLoader.addBucket(makeMockBucket(UID_ALL, 123, 456, 0, 10));
+        mLoader.addBucket(makeMockBucket(UID_ALL, 123, 456, 30, 40));
+        mLoader.addBucket(makeMockBucket(UID_ALL, 123, 456, 10, 25));
+        assertEquals(new Range(0L, 40L), mLoader.getTimeRangeOf(mock(NetworkStats.class)));
+    }
+
     public class NetworkCycleDataTestLoader extends NetworkCycleDataLoader<List<NetworkCycleData>> {
+        private final Queue<NetworkStats.Bucket> mMockedBuckets = new LinkedBlockingQueue<>();
 
         private NetworkCycleDataTestLoader(Context context) {
-            super(NetworkCycleDataLoader.builder(mContext));
+            super(NetworkCycleDataLoader.builder(mContext)
+                    .setNetworkTemplate(mock(NetworkTemplate.class)));
             mContext = context;
         }
 
@@ -188,5 +213,19 @@
         List<NetworkCycleData> getCycleUsage() {
             return null;
         }
+
+        public void addBucket(NetworkStats.Bucket bucket) {
+            mMockedBuckets.add(bucket);
+        }
+
+        @Override
+        public boolean hasNextBucket(@NonNull NetworkStats unused) {
+            return !mMockedBuckets.isEmpty();
+        }
+
+        @Override
+        public NetworkStats.Bucket getNextBucket(@NonNull NetworkStats unused) {
+            return mMockedBuckets.remove();
+        }
     }
 }
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 618a37e..5b2e8ae 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -245,6 +245,7 @@
     <uses-permission android:name="android.permission.MANAGE_APP_PREDICTIONS" />
     <uses-permission android:name="android.permission.MANAGE_SEARCH_UI" />
     <uses-permission android:name="android.permission.MANAGE_SMARTSPACE" />
+    <uses-permission android:name="android.permission.MANAGE_WALLPAPER_EFFECTS_GENERATION" />
     <uses-permission android:name="android.permission.MANAGE_UI_TRANSLATION" />
     <uses-permission android:name="android.permission.NETWORK_SETTINGS" />
     <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
@@ -340,6 +341,9 @@
     <!-- Permission required for CTS test - CrossProfileAppsHostSideTest -->
     <uses-permission android:name="android.permission.INTERACT_ACROSS_PROFILES"/>
 
+    <!-- Permission required for CTS test - CrossProfileAppsHostSideTest -->
+    <uses-permission android:name="android.permission.START_CROSS_PROFILE_ACTIVITIES"/>
+
     <!-- permissions required for CTS test - PhoneStateListenerTest -->
     <uses-permission android:name="android.permission.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH" />
 
@@ -500,6 +504,7 @@
     <!-- Permission needed for CTS test - WifiManagerTest -->
     <uses-permission android:name="android.permission.WIFI_ACCESS_COEX_UNSAFE_CHANNELS" />
     <uses-permission android:name="android.permission.WIFI_UPDATE_COEX_UNSAFE_CHANNELS" />
+    <uses-permission android:name="android.permission.OVERRIDE_WIFI_CONFIG" />
 
     <!-- Permission required for CTS tests to enable/disable rate limiting toasts. -->
     <uses-permission android:name="android.permission.MANAGE_TOAST_RATE_LIMITING" />
@@ -524,6 +529,10 @@
     <!-- Permission required for CTS test - PeopleManagerTest -->
     <uses-permission android:name="android.permission.READ_PEOPLE_DATA" />
 
+    <!-- Permissions required for CTS test - TrustTestCases -->
+    <uses-permission android:name="android.permission.PROVIDE_TRUST_AGENT" />
+    <uses-permission android:name="android.permission.ACCESS_KEYGUARD_SECURE_STORAGE" />
+
     <!-- Permission required for CTS test - CtsGameManagerTestCases -->
     <uses-permission android:name="android.permission.MANAGE_GAME_MODE" />
 
diff --git a/packages/SystemUI/OWNERS b/packages/SystemUI/OWNERS
index e1da744..8323e32 100644
--- a/packages/SystemUI/OWNERS
+++ b/packages/SystemUI/OWNERS
@@ -11,8 +11,10 @@
 awickham@google.com
 beverlyt@google.com
 brockman@google.com
+brzezinski@google.com
 brycelee@google.com
 ccassidy@google.com
+chrisgollner@google.com
 cinek@google.com
 cwren@google.com
 dupin@google.com
@@ -43,6 +45,8 @@
 mrcasey@google.com
 mrenouf@google.com
 nesciosquid@google.com
+nickchameyev@google.com
+nicomazz@google.com
 ogunwale@google.com
 peanutbutter@google.com
 pinyaoting@google.com
@@ -67,6 +71,7 @@
 yurilin@google.com
 xuqiu@google.com
 zakcohen@google.com
+jernej@google.com
 
 #Android Auto
 hseog@google.com
diff --git a/services/Android.bp b/services/Android.bp
index 841edc7..8947393 100644
--- a/services/Android.bp
+++ b/services/Android.bp
@@ -74,6 +74,7 @@
         ":services.appwidget-sources",
         ":services.autofill-sources",
         ":services.backup-sources",
+        ":services.bluetooth-sources", // TODO(b/214988855) : Remove once apex/service-bluetooth jar is ready
         ":backuplib-sources",
         ":services.companion-sources",
         ":services.contentcapture-sources",
@@ -175,6 +176,10 @@
     name: "libandroid_servers",
     defaults: ["libservices.core-libs"],
     whole_static_libs: ["libservices.core"],
+    required: [
+        // TODO: remove after NetworkStatsService is moved to the mainline module.
+        "libcom_android_net_module_util_jni",
+    ],
 }
 
 platform_compat_config {
diff --git a/services/core/Android.bp b/services/core/Android.bp
index 7a4f1de..9d19008 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -93,6 +93,7 @@
     defaults: ["platform_service_defaults"],
     srcs: [
         ":statslog-art-java-gen",
+        ":services.bluetooth-sources", // TODO(b/214988855) : Remove once apex is ready
         ":services.core-sources",
         ":services.core.protologsrc",
         ":dumpstate_aidl",
@@ -165,6 +166,9 @@
         "overlayable_policy_aidl-java",
         "SurfaceFlingerProperties",
         "com.android.sysprop.watchdog",
+        // This is used for services.connectivity-tiramisu-sources.
+        // TODO: delete when NetworkStatsService is moved to the mainline module.
+        "net-utils-device-common-bpf",
     ],
     javac_shard_size: 50,
 }
diff --git a/services/core/java/android/app/usage/OWNERS b/services/core/java/android/app/usage/OWNERS
new file mode 100644
index 0000000..3a55514
--- /dev/null
+++ b/services/core/java/android/app/usage/OWNERS
@@ -0,0 +1 @@
+include platform/frameworks/base:/core/java/android/app/usage/OWNERS
diff --git a/services/core/java/com/android/server/BluetoothAirplaneModeListener.java b/services/core/java/com/android/server/BluetoothAirplaneModeListener.java
deleted file mode 100644
index 380b1f3..0000000
--- a/services/core/java/com/android/server/BluetoothAirplaneModeListener.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server;
-
-import android.annotation.RequiresPermission;
-import android.content.Context;
-import android.database.ContentObserver;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.provider.Settings;
-import android.util.Log;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-/**
- * The BluetoothAirplaneModeListener handles system airplane mode change callback and checks
- * whether we need to inform BluetoothManagerService on this change.
- *
- * The information of airplane mode turns on would not be passed to the BluetoothManagerService
- * when Bluetooth is on and Bluetooth is in one of the following situations:
- *   1. Bluetooth A2DP is connected.
- *   2. Bluetooth Hearing Aid profile is connected.
- *   3. Bluetooth LE Audio is connected
- */
-class BluetoothAirplaneModeListener {
-    private static final String TAG = "BluetoothAirplaneModeListener";
-    @VisibleForTesting static final String TOAST_COUNT = "bluetooth_airplane_toast_count";
-
-    private static final int MSG_AIRPLANE_MODE_CHANGED = 0;
-
-    @VisibleForTesting static final int MAX_TOAST_COUNT = 10; // 10 times
-
-    private final BluetoothManagerService mBluetoothManager;
-    private final BluetoothAirplaneModeHandler mHandler;
-    private BluetoothModeChangeHelper mAirplaneHelper;
-
-    @VisibleForTesting int mToastCount = 0;
-
-    BluetoothAirplaneModeListener(BluetoothManagerService service, Looper looper, Context context) {
-        mBluetoothManager = service;
-
-        mHandler = new BluetoothAirplaneModeHandler(looper);
-        context.getContentResolver().registerContentObserver(
-                Settings.Global.getUriFor(Settings.Global.AIRPLANE_MODE_ON), true,
-                mAirplaneModeObserver);
-    }
-
-    private final ContentObserver mAirplaneModeObserver = new ContentObserver(null) {
-        @Override
-        public void onChange(boolean unused) {
-            // Post from system main thread to android_io thread.
-            Message msg = mHandler.obtainMessage(MSG_AIRPLANE_MODE_CHANGED);
-            mHandler.sendMessage(msg);
-        }
-    };
-
-    private class BluetoothAirplaneModeHandler extends Handler {
-        BluetoothAirplaneModeHandler(Looper looper) {
-            super(looper);
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case MSG_AIRPLANE_MODE_CHANGED:
-                    handleAirplaneModeChange();
-                    break;
-                default:
-                    Log.e(TAG, "Invalid message: " + msg.what);
-                    break;
-            }
-        }
-    }
-
-    /**
-     * Call after boot complete
-     */
-    @VisibleForTesting
-    void start(BluetoothModeChangeHelper helper) {
-        Log.i(TAG, "start");
-        mAirplaneHelper = helper;
-        mToastCount = mAirplaneHelper.getSettingsInt(TOAST_COUNT);
-    }
-
-    @VisibleForTesting
-    boolean shouldPopToast() {
-        if (mToastCount >= MAX_TOAST_COUNT) {
-            return false;
-        }
-        mToastCount++;
-        mAirplaneHelper.setSettingsInt(TOAST_COUNT, mToastCount);
-        return true;
-    }
-
-    @VisibleForTesting
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)
-    void handleAirplaneModeChange() {
-        if (shouldSkipAirplaneModeChange()) {
-            Log.i(TAG, "Ignore airplane mode change");
-            // Airplane mode enabled when Bluetooth is being used for audio/headering aid.
-            // Bluetooth is not disabled in such case, only state is changed to
-            // BLUETOOTH_ON_AIRPLANE mode.
-            mAirplaneHelper.setSettingsInt(Settings.Global.BLUETOOTH_ON,
-                    BluetoothManagerService.BLUETOOTH_ON_AIRPLANE);
-            if (shouldPopToast()) {
-                mAirplaneHelper.showToastMessage();
-            }
-            return;
-        }
-        if (mAirplaneHelper != null) {
-            mAirplaneHelper.onAirplaneModeChanged(mBluetoothManager);
-        }
-    }
-
-    @VisibleForTesting
-    boolean shouldSkipAirplaneModeChange() {
-        if (mAirplaneHelper == null) {
-            return false;
-        }
-        if (!mAirplaneHelper.isBluetoothOn() || !mAirplaneHelper.isAirplaneModeOn()
-                || !mAirplaneHelper.isMediaProfileConnected()) {
-            return false;
-        }
-        return true;
-    }
-}
diff --git a/services/core/java/com/android/server/BluetoothDeviceConfigListener.java b/services/core/java/com/android/server/BluetoothDeviceConfigListener.java
deleted file mode 100644
index 611a37d..0000000
--- a/services/core/java/com/android/server/BluetoothDeviceConfigListener.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * 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 com.android.server;
-
-import android.provider.DeviceConfig;
-import android.util.Slog;
-
-import java.util.ArrayList;
-
-/**
- * The BluetoothDeviceConfigListener handles system device config change callback and checks
- * whether we need to inform BluetoothManagerService on this change.
- *
- * The information of device config change would not be passed to the BluetoothManagerService
- * when Bluetooth is on and Bluetooth is in one of the following situations:
- *   1. Bluetooth A2DP is connected.
- *   2. Bluetooth Hearing Aid profile is connected.
- */
-class BluetoothDeviceConfigListener {
-    private static final String TAG = "BluetoothDeviceConfigListener";
-
-    private final BluetoothManagerService mService;
-    private final boolean mLogDebug;
-
-    BluetoothDeviceConfigListener(BluetoothManagerService service, boolean logDebug) {
-        mService = service;
-        mLogDebug = logDebug;
-        DeviceConfig.addOnPropertiesChangedListener(
-                DeviceConfig.NAMESPACE_BLUETOOTH,
-                (Runnable r) -> r.run(),
-                mDeviceConfigChangedListener);
-    }
-
-    private final DeviceConfig.OnPropertiesChangedListener mDeviceConfigChangedListener =
-            new DeviceConfig.OnPropertiesChangedListener() {
-                @Override
-                public void onPropertiesChanged(DeviceConfig.Properties properties) {
-                    if (!properties.getNamespace().equals(DeviceConfig.NAMESPACE_BLUETOOTH)) {
-                        return;
-                    }
-                    if (mLogDebug) {
-                        ArrayList<String> flags = new ArrayList<>();
-                        for (String name : properties.getKeyset()) {
-                            flags.add(name + "='" + properties.getString(name, "") + "'");
-                        }
-                        Slog.d(TAG, "onPropertiesChanged: " + String.join(",", flags));
-                    }
-                    boolean foundInit = false;
-                    for (String name : properties.getKeyset()) {
-                        if (name.startsWith("INIT_")) {
-                            foundInit = true;
-                            break;
-                        }
-                    }
-                    if (!foundInit) {
-                        return;
-                    }
-                    mService.onInitFlagsChanged();
-                }
-            };
-
-}
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
deleted file mode 100644
index c8b4f11..0000000
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ /dev/null
@@ -1,2960 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server;
-
-import static android.Manifest.permission.BLUETOOTH_CONNECT;
-import static android.content.PermissionChecker.PERMISSION_HARD_DENIED;
-import static android.content.PermissionChecker.PID_UNKNOWN;
-import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
-import static android.content.pm.PackageManager.PERMISSION_GRANTED;
-import static android.os.PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED;
-import static android.os.UserHandle.USER_SYSTEM;
-
-import android.Manifest;
-import android.annotation.NonNull;
-import android.annotation.RequiresPermission;
-import android.annotation.SuppressLint;
-import android.app.ActivityManager;
-import android.app.AppGlobals;
-import android.app.AppOpsManager;
-import android.app.BroadcastOptions;
-import android.bluetooth.BluetoothA2dp;
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothHearingAid;
-import android.bluetooth.BluetoothLeAudio;
-import android.bluetooth.BluetoothProfile;
-import android.bluetooth.BluetoothProtoEnums;
-import android.bluetooth.IBluetooth;
-import android.bluetooth.IBluetoothCallback;
-import android.bluetooth.IBluetoothGatt;
-import android.bluetooth.IBluetoothHeadset;
-import android.bluetooth.IBluetoothManager;
-import android.bluetooth.IBluetoothManagerCallback;
-import android.bluetooth.IBluetoothProfileServiceConnection;
-import android.bluetooth.IBluetoothStateChangeCallback;
-import android.bluetooth.IBluetoothLeCallControl;
-import android.content.ActivityNotFoundException;
-import android.content.AttributionSource;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.PermissionChecker;
-import android.content.ServiceConnection;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.IPackageManager;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManagerInternal;
-import android.content.pm.UserInfo;
-import android.database.ContentObserver;
-import android.os.Binder;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.Message;
-import android.os.PowerExemptionManager;
-import android.os.Process;
-import android.os.RemoteCallbackList;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.os.SystemProperties;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.provider.Settings;
-import android.provider.Settings.SettingNotFoundException;
-import android.text.TextUtils;
-import android.util.FeatureFlagUtils;
-import android.util.Log;
-import android.util.Slog;
-import android.util.proto.ProtoOutputStream;
-
-import com.android.internal.R;
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.DumpUtils;
-import com.android.internal.util.FrameworkStatsLog;
-import com.android.server.pm.UserManagerInternal;
-import com.android.server.pm.UserManagerInternal.UserRestrictionsListener;
-import com.android.server.pm.UserRestrictionsUtils;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.Locale;
-import java.util.Map;
-import java.util.NoSuchElementException;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-
-class BluetoothManagerService extends IBluetoothManager.Stub {
-    private static final String TAG = "BluetoothManagerService";
-    private static final boolean DBG = true;
-
-    private static final String BLUETOOTH_PRIVILEGED =
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED;
-
-    private static final String SECURE_SETTINGS_BLUETOOTH_ADDR_VALID = "bluetooth_addr_valid";
-    private static final String SECURE_SETTINGS_BLUETOOTH_ADDRESS = "bluetooth_address";
-    private static final String SECURE_SETTINGS_BLUETOOTH_NAME = "bluetooth_name";
-
-    private static final int ACTIVE_LOG_MAX_SIZE = 20;
-    private static final int CRASH_LOG_MAX_SIZE = 100;
-
-    private static final int TIMEOUT_BIND_MS = 3000; //Maximum msec to wait for a bind
-    //Maximum msec to wait for service restart
-    private static final int SERVICE_RESTART_TIME_MS = 400;
-    //Maximum msec to wait for restart due to error
-    private static final int ERROR_RESTART_TIME_MS = 3000;
-    //Maximum msec to delay MESSAGE_USER_SWITCHED
-    private static final int USER_SWITCHED_TIME_MS = 200;
-    // Delay for the addProxy function in msec
-    private static final int ADD_PROXY_DELAY_MS = 100;
-    // Delay for retrying enable and disable in msec
-    private static final int ENABLE_DISABLE_DELAY_MS = 300;
-    private static final int DELAY_BEFORE_RESTART_DUE_TO_INIT_FLAGS_CHANGED_MS = 300;
-    private static final int DELAY_FOR_RETRY_INIT_FLAG_CHECK_MS = 86400;
-
-    private static final int MESSAGE_ENABLE = 1;
-    private static final int MESSAGE_DISABLE = 2;
-    private static final int MESSAGE_HANDLE_ENABLE_DELAYED = 3;
-    private static final int MESSAGE_HANDLE_DISABLE_DELAYED = 4;
-    private static final int MESSAGE_REGISTER_STATE_CHANGE_CALLBACK = 30;
-    private static final int MESSAGE_UNREGISTER_STATE_CHANGE_CALLBACK = 31;
-    private static final int MESSAGE_BLUETOOTH_SERVICE_CONNECTED = 40;
-    private static final int MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED = 41;
-    private static final int MESSAGE_RESTART_BLUETOOTH_SERVICE = 42;
-    private static final int MESSAGE_BLUETOOTH_STATE_CHANGE = 60;
-    private static final int MESSAGE_TIMEOUT_BIND = 100;
-    private static final int MESSAGE_TIMEOUT_UNBIND = 101;
-    private static final int MESSAGE_GET_NAME_AND_ADDRESS = 200;
-    private static final int MESSAGE_USER_SWITCHED = 300;
-    private static final int MESSAGE_USER_UNLOCKED = 301;
-    private static final int MESSAGE_ADD_PROXY_DELAYED = 400;
-    private static final int MESSAGE_BIND_PROFILE_SERVICE = 401;
-    private static final int MESSAGE_RESTORE_USER_SETTING = 500;
-    private static final int MESSAGE_INIT_FLAGS_CHANGED = 600;
-
-    private static final int RESTORE_SETTING_TO_ON = 1;
-    private static final int RESTORE_SETTING_TO_OFF = 0;
-
-    private static final int MAX_ERROR_RESTART_RETRIES = 6;
-    private static final int MAX_WAIT_FOR_ENABLE_DISABLE_RETRIES = 10;
-
-    // Bluetooth persisted setting is off
-    private static final int BLUETOOTH_OFF = 0;
-    // Bluetooth persisted setting is on
-    // and Airplane mode won't affect Bluetooth state at start up
-    private static final int BLUETOOTH_ON_BLUETOOTH = 1;
-    // Bluetooth persisted setting is on
-    // but Airplane mode will affect Bluetooth state at start up
-    // and Airplane mode will have higher priority.
-    @VisibleForTesting
-    static final int BLUETOOTH_ON_AIRPLANE = 2;
-
-    private static final int SERVICE_IBLUETOOTH = 1;
-    private static final int SERVICE_IBLUETOOTHGATT = 2;
-
-    private final Context mContext;
-
-    // Locks are not provided for mName and mAddress.
-    // They are accessed in handler or broadcast receiver, same thread context.
-    private String mAddress;
-    private String mName;
-    private final ContentResolver mContentResolver;
-    private final int mUserId;
-    private final RemoteCallbackList<IBluetoothManagerCallback> mCallbacks;
-    private final RemoteCallbackList<IBluetoothStateChangeCallback> mStateChangeCallbacks;
-    private IBinder mBluetoothBinder;
-    private IBluetooth mBluetooth;
-    private IBluetoothGatt mBluetoothGatt;
-    private final ReentrantReadWriteLock mBluetoothLock = new ReentrantReadWriteLock();
-    private boolean mBinding;
-    private boolean mUnbinding;
-
-    private BluetoothModeChangeHelper mBluetoothModeChangeHelper;
-
-    private BluetoothAirplaneModeListener mBluetoothAirplaneModeListener;
-
-    private BluetoothDeviceConfigListener mBluetoothDeviceConfigListener;
-
-    // used inside handler thread
-    private boolean mQuietEnable = false;
-    private boolean mEnable;
-
-    private static CharSequence timeToLog(long timestamp) {
-        return android.text.format.DateFormat.format("MM-dd HH:mm:ss", timestamp);
-    }
-
-    /**
-     * Used for tracking apps that enabled / disabled Bluetooth.
-     */
-    private class ActiveLog {
-        private int mReason;
-        private String mPackageName;
-        private boolean mEnable;
-        private long mTimestamp;
-
-        ActiveLog(int reason, String packageName, boolean enable, long timestamp) {
-            mReason = reason;
-            mPackageName = packageName;
-            mEnable = enable;
-            mTimestamp = timestamp;
-        }
-
-        public String toString() {
-            return timeToLog(mTimestamp) + (mEnable ? "  Enabled " : " Disabled ")
-                    + " due to " + getEnableDisableReasonString(mReason) + " by " + mPackageName;
-        }
-
-        void dump(ProtoOutputStream proto) {
-            proto.write(BluetoothManagerServiceDumpProto.ActiveLog.TIMESTAMP_MS, mTimestamp);
-            proto.write(BluetoothManagerServiceDumpProto.ActiveLog.ENABLE, mEnable);
-            proto.write(BluetoothManagerServiceDumpProto.ActiveLog.PACKAGE_NAME, mPackageName);
-            proto.write(BluetoothManagerServiceDumpProto.ActiveLog.REASON, mReason);
-        }
-    }
-
-    private final LinkedList<ActiveLog> mActiveLogs = new LinkedList<>();
-    private final LinkedList<Long> mCrashTimestamps = new LinkedList<>();
-    private int mCrashes;
-    private long mLastEnabledTime;
-
-    // configuration from external IBinder call which is used to
-    // synchronize with broadcast receiver.
-    private boolean mQuietEnableExternal;
-    private boolean mEnableExternal;
-
-    // Map of apps registered to keep BLE scanning on.
-    private Map<IBinder, ClientDeathRecipient> mBleApps =
-            new ConcurrentHashMap<IBinder, ClientDeathRecipient>();
-
-    private int mState;
-    private final BluetoothHandler mHandler;
-    private int mErrorRecoveryRetryCounter;
-    private final int mSystemUiUid;
-
-    private boolean mIsHearingAidProfileSupported;
-
-    private AppOpsManager mAppOps;
-
-    // Save a ProfileServiceConnections object for each of the bound
-    // bluetooth profile services
-    private final Map<Integer, ProfileServiceConnections> mProfileServices = new HashMap<>();
-
-    private final boolean mWirelessConsentRequired;
-
-    private final IBluetoothCallback mBluetoothCallback = new IBluetoothCallback.Stub() {
-        @Override
-        public void onBluetoothStateChange(int prevState, int newState) throws RemoteException {
-            Message msg =
-                    mHandler.obtainMessage(MESSAGE_BLUETOOTH_STATE_CHANGE, prevState, newState);
-            mHandler.sendMessage(msg);
-        }
-    };
-
-    private final UserRestrictionsListener mUserRestrictionsListener =
-            new UserRestrictionsListener() {
-                @Override
-                public void onUserRestrictionsChanged(int userId, Bundle newRestrictions,
-                        Bundle prevRestrictions) {
-
-                    if (UserRestrictionsUtils.restrictionsChanged(prevRestrictions, newRestrictions,
-                            UserManager.DISALLOW_BLUETOOTH_SHARING)) {
-                        updateOppLauncherComponentState(userId,
-                                newRestrictions.getBoolean(UserManager.DISALLOW_BLUETOOTH_SHARING));
-                    }
-
-                    // DISALLOW_BLUETOOTH can only be set by DO or PO on the system user.
-                    if (userId == USER_SYSTEM
-                            && UserRestrictionsUtils.restrictionsChanged(prevRestrictions,
-                            newRestrictions, UserManager.DISALLOW_BLUETOOTH)) {
-                        if (userId == USER_SYSTEM && newRestrictions.getBoolean(
-                                UserManager.DISALLOW_BLUETOOTH)) {
-                            updateOppLauncherComponentState(userId, true); // Sharing disallowed
-                            sendDisableMsg(BluetoothProtoEnums.ENABLE_DISABLE_REASON_DISALLOWED,
-                                    mContext.getPackageName());
-                        } else {
-                            updateOppLauncherComponentState(userId, newRestrictions.getBoolean(
-                                    UserManager.DISALLOW_BLUETOOTH_SHARING));
-                        }
-                    }
-                }
-            };
-
-    @VisibleForTesting
-    public void onInitFlagsChanged() {
-        mHandler.removeMessages(MESSAGE_INIT_FLAGS_CHANGED);
-        mHandler.sendEmptyMessageDelayed(
-                MESSAGE_INIT_FLAGS_CHANGED,
-                DELAY_BEFORE_RESTART_DUE_TO_INIT_FLAGS_CHANGED_MS);
-    }
-
-    public boolean onFactoryReset(AttributionSource attributionSource) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED,
-                "Need BLUETOOTH_PRIVILEGED permission");
-
-        // Wait for stable state if bluetooth is temporary state.
-        int state = getState();
-        if (state == BluetoothAdapter.STATE_BLE_TURNING_ON
-                || state == BluetoothAdapter.STATE_TURNING_ON
-                || state == BluetoothAdapter.STATE_TURNING_OFF) {
-            if (!waitForState(Set.of(BluetoothAdapter.STATE_BLE_ON, BluetoothAdapter.STATE_ON))) {
-                return false;
-            }
-        }
-
-        // Clear registered LE apps to force shut-off Bluetooth
-        clearBleApps();
-        state = getState();
-        try {
-            mBluetoothLock.readLock().lock();
-            if (mBluetooth == null) {
-                return false;
-            }
-            if (state == BluetoothAdapter.STATE_BLE_ON) {
-                addActiveLog(
-                        BluetoothProtoEnums.ENABLE_DISABLE_REASON_FACTORY_RESET,
-                        mContext.getPackageName(), false);
-                mBluetooth.onBrEdrDown(attributionSource);
-                return true;
-            } else if (state == BluetoothAdapter.STATE_ON) {
-                addActiveLog(
-                        BluetoothProtoEnums.ENABLE_DISABLE_REASON_FACTORY_RESET,
-                        mContext.getPackageName(), false);
-                mBluetooth.disable(attributionSource);
-                return true;
-            }
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Unable to shutdown Bluetooth", e);
-        } finally {
-            mBluetoothLock.readLock().unlock();
-        }
-        return false;
-    }
-
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)
-    public void onAirplaneModeChanged() {
-        synchronized (this) {
-            if (isBluetoothPersistedStateOn()) {
-                if (isAirplaneModeOn()) {
-                    persistBluetoothSetting(BLUETOOTH_ON_AIRPLANE);
-                } else {
-                    persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH);
-                }
-            }
-
-            int st = BluetoothAdapter.STATE_OFF;
-            try {
-                mBluetoothLock.readLock().lock();
-                if (mBluetooth != null) {
-                    st = mBluetooth.getState();
-                }
-            } catch (RemoteException e) {
-                Slog.e(TAG, "Unable to call getState", e);
-                return;
-            } finally {
-                mBluetoothLock.readLock().unlock();
-            }
-
-            Slog.d(TAG,
-                    "Airplane Mode change - current state:  " + BluetoothAdapter.nameForState(
-                            st) + ", isAirplaneModeOn()=" + isAirplaneModeOn());
-
-            if (isAirplaneModeOn()) {
-                // Clear registered LE apps to force shut-off
-                clearBleApps();
-
-                // If state is BLE_ON make sure we trigger disableBLE
-                if (st == BluetoothAdapter.STATE_BLE_ON) {
-                    try {
-                        mBluetoothLock.readLock().lock();
-                        if (mBluetooth != null) {
-                            addActiveLog(
-                                    BluetoothProtoEnums.ENABLE_DISABLE_REASON_AIRPLANE_MODE,
-                                    mContext.getPackageName(), false);
-                            mBluetooth.onBrEdrDown(mContext.getAttributionSource());
-                            mEnable = false;
-                            mEnableExternal = false;
-                        }
-                    } catch (RemoteException e) {
-                        Slog.e(TAG, "Unable to call onBrEdrDown", e);
-                    } finally {
-                        mBluetoothLock.readLock().unlock();
-                    }
-                } else if (st == BluetoothAdapter.STATE_ON) {
-                    sendDisableMsg(BluetoothProtoEnums.ENABLE_DISABLE_REASON_AIRPLANE_MODE,
-                            mContext.getPackageName());
-                }
-            } else if (mEnableExternal) {
-                sendEnableMsg(mQuietEnableExternal,
-                        BluetoothProtoEnums.ENABLE_DISABLE_REASON_AIRPLANE_MODE,
-                        mContext.getPackageName());
-            }
-        }
-    }
-
-    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            String action = intent.getAction();
-            if (BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED.equals(action)) {
-                String newName = intent.getStringExtra(BluetoothAdapter.EXTRA_LOCAL_NAME);
-                if (DBG) {
-                    Slog.d(TAG, "Bluetooth Adapter name changed to " + newName + " by "
-                            + mContext.getPackageName());
-                }
-                if (newName != null) {
-                    storeNameAndAddress(newName, null);
-                }
-            } else if (BluetoothAdapter.ACTION_BLUETOOTH_ADDRESS_CHANGED.equals(action)) {
-                String newAddress = intent.getStringExtra(BluetoothAdapter.EXTRA_BLUETOOTH_ADDRESS);
-                if (newAddress != null) {
-                    if (DBG) {
-                        Slog.d(TAG, "Bluetooth Adapter address changed to " + newAddress);
-                    }
-                    storeNameAndAddress(null, newAddress);
-                } else {
-                    if (DBG) {
-                        Slog.e(TAG, "No Bluetooth Adapter address parameter found");
-                    }
-                }
-            } else if (Intent.ACTION_SETTING_RESTORED.equals(action)) {
-                final String name = intent.getStringExtra(Intent.EXTRA_SETTING_NAME);
-                if (Settings.Global.BLUETOOTH_ON.equals(name)) {
-                    // The Bluetooth On state may be changed during system restore.
-                    final String prevValue =
-                            intent.getStringExtra(Intent.EXTRA_SETTING_PREVIOUS_VALUE);
-                    final String newValue = intent.getStringExtra(Intent.EXTRA_SETTING_NEW_VALUE);
-
-                    if (DBG) {
-                        Slog.d(TAG,
-                                "ACTION_SETTING_RESTORED with BLUETOOTH_ON, prevValue=" + prevValue
-                                        + ", newValue=" + newValue);
-                    }
-
-                    if ((newValue != null) && (prevValue != null) && !prevValue.equals(newValue)) {
-                        Message msg = mHandler.obtainMessage(MESSAGE_RESTORE_USER_SETTING,
-                                newValue.equals("0") ? RESTORE_SETTING_TO_OFF
-                                        : RESTORE_SETTING_TO_ON, 0);
-                        mHandler.sendMessage(msg);
-                    }
-                }
-            } else if (BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED.equals(action)
-                    || BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED.equals(action)
-                    || BluetoothLeAudio.ACTION_LE_AUDIO_CONNECTION_STATE_CHANGED.equals(action)) {
-                final int state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE,
-                        BluetoothProfile.STATE_CONNECTED);
-                if (mHandler.hasMessages(MESSAGE_INIT_FLAGS_CHANGED)
-                        && state == BluetoothProfile.STATE_DISCONNECTED
-                        && !mBluetoothModeChangeHelper.isMediaProfileConnected()) {
-                    Slog.i(TAG, "Device disconnected, reactivating pending flag changes");
-                    onInitFlagsChanged();
-                }
-            }
-        }
-    };
-
-    BluetoothManagerService(Context context) {
-        mHandler = new BluetoothHandler(IoThread.get().getLooper());
-
-        mContext = context;
-
-        mWirelessConsentRequired = context.getResources()
-                .getBoolean(com.android.internal.R.bool.config_wirelessConsentRequired);
-
-        mCrashes = 0;
-        mBluetooth = null;
-        mBluetoothBinder = null;
-        mBluetoothGatt = null;
-        mBinding = false;
-        mUnbinding = false;
-        mEnable = false;
-        mState = BluetoothAdapter.STATE_OFF;
-        mQuietEnableExternal = false;
-        mEnableExternal = false;
-        mAddress = null;
-        mName = null;
-        mErrorRecoveryRetryCounter = 0;
-        mContentResolver = context.getContentResolver();
-        mUserId = mContentResolver.getUserId();
-        // Observe BLE scan only mode settings change.
-        registerForBleScanModeChange();
-        mCallbacks = new RemoteCallbackList<IBluetoothManagerCallback>();
-        mStateChangeCallbacks = new RemoteCallbackList<IBluetoothStateChangeCallback>();
-
-        mIsHearingAidProfileSupported = context.getResources()
-                .getBoolean(com.android.internal.R.bool.config_hearing_aid_profile_supported);
-
-        // TODO: We need a more generic way to initialize the persist keys of FeatureFlagUtils
-        String value = SystemProperties.get(FeatureFlagUtils.PERSIST_PREFIX + FeatureFlagUtils.HEARING_AID_SETTINGS);
-        if (!TextUtils.isEmpty(value)) {
-            boolean isHearingAidEnabled = Boolean.parseBoolean(value);
-            Log.v(TAG, "set feature flag HEARING_AID_SETTINGS to " + isHearingAidEnabled);
-            FeatureFlagUtils.setEnabled(context, FeatureFlagUtils.HEARING_AID_SETTINGS, isHearingAidEnabled);
-            if (isHearingAidEnabled && !mIsHearingAidProfileSupported) {
-                // Overwrite to enable support by FeatureFlag
-                mIsHearingAidProfileSupported = true;
-            }
-        }
-
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED);
-        filter.addAction(BluetoothAdapter.ACTION_BLUETOOTH_ADDRESS_CHANGED);
-        filter.addAction(Intent.ACTION_SETTING_RESTORED);
-        filter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
-        filter.addAction(BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED);
-        filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
-        mContext.registerReceiver(mReceiver, filter);
-
-        loadStoredNameAndAddress();
-        if (isBluetoothPersistedStateOn()) {
-            if (DBG) {
-                Slog.d(TAG, "Startup: Bluetooth persisted state is ON.");
-            }
-            mEnableExternal = true;
-        }
-
-        String airplaneModeRadios =
-                Settings.Global.getString(mContentResolver, Settings.Global.AIRPLANE_MODE_RADIOS);
-        if (airplaneModeRadios == null || airplaneModeRadios.contains(
-                Settings.Global.RADIO_BLUETOOTH)) {
-            mBluetoothAirplaneModeListener = new BluetoothAirplaneModeListener(
-                    this, IoThread.get().getLooper(), context);
-        }
-
-        int systemUiUid = -1;
-        // Check if device is configured with no home screen, which implies no SystemUI.
-        boolean noHome = mContext.getResources().getBoolean(R.bool.config_noHomeScreen);
-        if (!noHome) {
-            PackageManagerInternal pm = LocalServices.getService(PackageManagerInternal.class);
-            systemUiUid = pm.getPackageUid(pm.getSystemUiServiceComponent().getPackageName(),
-                    MATCH_SYSTEM_ONLY, USER_SYSTEM);
-        }
-        if (systemUiUid >= 0) {
-            Slog.d(TAG, "Detected SystemUiUid: " + Integer.toString(systemUiUid));
-        } else {
-            // Some platforms, such as wearables do not have a system ui.
-            Slog.w(TAG, "Unable to resolve SystemUI's UID.");
-        }
-        mSystemUiUid = systemUiUid;
-    }
-
-    /**
-     *  Returns true if airplane mode is currently on
-     */
-    private boolean isAirplaneModeOn() {
-        return Settings.Global.getInt(mContext.getContentResolver(),
-                Settings.Global.AIRPLANE_MODE_ON, 0) == 1;
-    }
-
-    private boolean supportBluetoothPersistedState() {
-        return mContext.getResources().getBoolean(R.bool.config_supportBluetoothPersistedState);
-    }
-
-    /**
-     *  Returns true if the Bluetooth saved state is "on"
-     */
-    private boolean isBluetoothPersistedStateOn() {
-        if (!supportBluetoothPersistedState()) {
-            return false;
-        }
-        int state = Settings.Global.getInt(mContentResolver, Settings.Global.BLUETOOTH_ON, -1);
-        if (DBG) {
-            Slog.d(TAG, "Bluetooth persisted state: " + state);
-        }
-        return state != BLUETOOTH_OFF;
-    }
-
-    private boolean isBluetoothPersistedStateOnAirplane() {
-        if (!supportBluetoothPersistedState()) {
-            return false;
-        }
-        int state = Settings.Global.getInt(mContentResolver, Settings.Global.BLUETOOTH_ON, -1);
-        if (DBG) {
-            Slog.d(TAG, "Bluetooth persisted state: " + state);
-        }
-        return state == BLUETOOTH_ON_AIRPLANE;
-    }
-
-    /**
-     *  Returns true if the Bluetooth saved state is BLUETOOTH_ON_BLUETOOTH
-     */
-    private boolean isBluetoothPersistedStateOnBluetooth() {
-        if (!supportBluetoothPersistedState()) {
-            return false;
-        }
-        return Settings.Global.getInt(mContentResolver, Settings.Global.BLUETOOTH_ON,
-                BLUETOOTH_ON_BLUETOOTH) == BLUETOOTH_ON_BLUETOOTH;
-    }
-
-    /**
-     *  Save the Bluetooth on/off state
-     */
-    private void persistBluetoothSetting(int value) {
-        if (DBG) {
-            Slog.d(TAG, "Persisting Bluetooth Setting: " + value);
-        }
-        // waive WRITE_SECURE_SETTINGS permission check
-        final long callingIdentity = Binder.clearCallingIdentity();
-        try {
-            Settings.Global.putInt(mContext.getContentResolver(),
-                    Settings.Global.BLUETOOTH_ON, value);
-        } finally {
-            Binder.restoreCallingIdentity(callingIdentity);
-        }
-    }
-
-    /**
-     * Returns true if the Bluetooth Adapter's name and address is
-     * locally cached
-     * @return
-     */
-    private boolean isNameAndAddressSet() {
-        return mName != null && mAddress != null && mName.length() > 0 && mAddress.length() > 0;
-    }
-
-    /**
-     * Retrieve the Bluetooth Adapter's name and address and save it in
-     * in the local cache
-     */
-    private void loadStoredNameAndAddress() {
-        if (DBG) {
-            Slog.d(TAG, "Loading stored name and address");
-        }
-        if (mContext.getResources()
-                .getBoolean(com.android.internal.R.bool.config_bluetooth_address_validation)
-                && Settings.Secure.getIntForUser(mContentResolver,
-                SECURE_SETTINGS_BLUETOOTH_ADDR_VALID, 0, mUserId)
-                == 0) {
-            // if the valid flag is not set, don't load the address and name
-            if (DBG) {
-                Slog.d(TAG, "invalid bluetooth name and address stored");
-            }
-            return;
-        }
-        mName = Settings.Secure.getStringForUser(
-                mContentResolver, SECURE_SETTINGS_BLUETOOTH_NAME, mUserId);
-        mAddress = Settings.Secure.getStringForUser(
-                mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDRESS, mUserId);
-        if (DBG) {
-            Slog.d(TAG, "Stored bluetooth Name=" + mName + ",Address=" + mAddress);
-        }
-    }
-
-    /**
-     * Save the Bluetooth name and address in the persistent store.
-     * Only non-null values will be saved.
-     * @param name
-     * @param address
-     */
-    private void storeNameAndAddress(String name, String address) {
-        if (name != null) {
-            Settings.Secure.putStringForUser(mContentResolver, SECURE_SETTINGS_BLUETOOTH_NAME, name,
-                    mUserId);
-            mName = name;
-            if (DBG) {
-                Slog.d(TAG, "Stored Bluetooth name: " + Settings.Secure.getStringForUser(
-                        mContentResolver, SECURE_SETTINGS_BLUETOOTH_NAME,
-                        mUserId));
-            }
-        }
-
-        if (address != null) {
-            Settings.Secure.putStringForUser(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDRESS,
-                    address, mUserId);
-            mAddress = address;
-            if (DBG) {
-                Slog.d(TAG,
-                        "Stored Bluetoothaddress: " + Settings.Secure.getStringForUser(
-                                mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDRESS,
-                                mUserId));
-            }
-        }
-
-        if ((name != null) && (address != null)) {
-            Settings.Secure.putIntForUser(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDR_VALID, 1,
-                    mUserId);
-        }
-    }
-
-    public IBluetooth registerAdapter(IBluetoothManagerCallback callback) {
-        if (callback == null) {
-            Slog.w(TAG, "Callback is null in registerAdapter");
-            return null;
-        }
-        synchronized (mCallbacks) {
-            mCallbacks.register(callback);
-        }
-        return mBluetooth;
-    }
-
-    public void unregisterAdapter(IBluetoothManagerCallback callback) {
-        if (callback == null) {
-            Slog.w(TAG, "Callback is null in unregisterAdapter");
-            return;
-        }
-        synchronized (mCallbacks) {
-            mCallbacks.unregister(callback);
-        }
-    }
-
-    public void registerStateChangeCallback(IBluetoothStateChangeCallback callback) {
-        if (callback == null) {
-            Slog.w(TAG, "registerStateChangeCallback: Callback is null!");
-            return;
-        }
-        Message msg = mHandler.obtainMessage(MESSAGE_REGISTER_STATE_CHANGE_CALLBACK);
-        msg.obj = callback;
-        mHandler.sendMessage(msg);
-    }
-
-    public void unregisterStateChangeCallback(IBluetoothStateChangeCallback callback) {
-        if (callback == null) {
-            Slog.w(TAG, "unregisterStateChangeCallback: Callback is null!");
-            return;
-        }
-        Message msg = mHandler.obtainMessage(MESSAGE_UNREGISTER_STATE_CHANGE_CALLBACK);
-        msg.obj = callback;
-        mHandler.sendMessage(msg);
-    }
-
-    public boolean isEnabled() {
-        return getState() == BluetoothAdapter.STATE_ON;
-    }
-
-    public int getState() {
-        if ((Binder.getCallingUid() != Process.SYSTEM_UID) && (!checkIfCallerIsForegroundUser())) {
-            Slog.w(TAG, "getState(): report OFF for non-active and non system user");
-            return BluetoothAdapter.STATE_OFF;
-        }
-
-        try {
-            mBluetoothLock.readLock().lock();
-            if (mBluetooth != null) {
-                return mBluetooth.getState();
-            }
-        } catch (RemoteException e) {
-            Slog.e(TAG, "getState()", e);
-        } finally {
-            mBluetoothLock.readLock().unlock();
-        }
-        return BluetoothAdapter.STATE_OFF;
-    }
-
-    class ClientDeathRecipient implements IBinder.DeathRecipient {
-        private String mPackageName;
-
-        ClientDeathRecipient(String packageName) {
-            mPackageName = packageName;
-        }
-
-        public void binderDied() {
-            if (DBG) {
-                Slog.d(TAG, "Binder is dead - unregister " + mPackageName);
-            }
-
-            for (Map.Entry<IBinder, ClientDeathRecipient> entry : mBleApps.entrySet()) {
-                IBinder token = entry.getKey();
-                ClientDeathRecipient deathRec = entry.getValue();
-                if (deathRec.equals(this)) {
-                    updateBleAppCount(token, false, mPackageName);
-                    break;
-                }
-            }
-        }
-
-        public String getPackageName() {
-            return mPackageName;
-        }
-    }
-
-    @Override
-    public boolean isBleScanAlwaysAvailable() {
-        if (isAirplaneModeOn() && !mEnable) {
-            return false;
-        }
-        try {
-            return Settings.Global.getInt(mContentResolver,
-                    Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE) != 0;
-        } catch (SettingNotFoundException e) {
-        }
-        return false;
-    }
-
-    @Override
-    public boolean isHearingAidProfileSupported() {
-        return mIsHearingAidProfileSupported;
-    }
-
-    private boolean isDeviceProvisioned() {
-        return Settings.Global.getInt(mContentResolver, Settings.Global.DEVICE_PROVISIONED,
-                0) != 0;
-    }
-
-    // Monitor change of BLE scan only mode settings.
-    private void registerForProvisioningStateChange() {
-        ContentObserver contentObserver = new ContentObserver(null) {
-            @Override
-            public void onChange(boolean selfChange) {
-                if (!isDeviceProvisioned()) {
-                    if (DBG) {
-                        Slog.d(TAG, "DEVICE_PROVISIONED setting changed, but device is not "
-                                + "provisioned");
-                    }
-                    return;
-                }
-                if (mHandler.hasMessages(MESSAGE_INIT_FLAGS_CHANGED)) {
-                    Slog.i(TAG, "Device provisioned, reactivating pending flag changes");
-                    onInitFlagsChanged();
-                }
-            }
-        };
-
-        mContentResolver.registerContentObserver(
-                Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED), false,
-                contentObserver);
-    }
-
-    // Monitor change of BLE scan only mode settings.
-    private void registerForBleScanModeChange() {
-        ContentObserver contentObserver = new ContentObserver(null) {
-            @Override
-            public void onChange(boolean selfChange) {
-                if (isBleScanAlwaysAvailable()) {
-                    // Nothing to do
-                    return;
-                }
-                // BLE scan is not available.
-                disableBleScanMode();
-                clearBleApps();
-                try {
-                    mBluetoothLock.readLock().lock();
-                    if (mBluetooth != null) {
-                        addActiveLog(BluetoothProtoEnums.ENABLE_DISABLE_REASON_APPLICATION_REQUEST,
-                                mContext.getPackageName(), false);
-                        mBluetooth.onBrEdrDown(mContext.getAttributionSource());
-                    }
-                } catch (RemoteException e) {
-                    Slog.e(TAG, "error when disabling bluetooth", e);
-                } finally {
-                    mBluetoothLock.readLock().unlock();
-                }
-            }
-        };
-
-        mContentResolver.registerContentObserver(
-                Settings.Global.getUriFor(Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE), false,
-                contentObserver);
-    }
-
-    // Disable ble scan only mode.
-    private void disableBleScanMode() {
-        try {
-            mBluetoothLock.writeLock().lock();
-            if (mBluetooth != null && (mBluetooth.getState() != BluetoothAdapter.STATE_ON)) {
-                if (DBG) {
-                    Slog.d(TAG, "Reseting the mEnable flag for clean disable");
-                }
-                mEnable = false;
-            }
-        } catch (RemoteException e) {
-            Slog.e(TAG, "getState()", e);
-        } finally {
-            mBluetoothLock.writeLock().unlock();
-        }
-    }
-
-    private int updateBleAppCount(IBinder token, boolean enable, String packageName) {
-        ClientDeathRecipient r = mBleApps.get(token);
-        if (r == null && enable) {
-            ClientDeathRecipient deathRec = new ClientDeathRecipient(packageName);
-            try {
-                token.linkToDeath(deathRec, 0);
-            } catch (RemoteException ex) {
-                throw new IllegalArgumentException("BLE app (" + packageName + ") already dead!");
-            }
-            mBleApps.put(token, deathRec);
-            if (DBG) {
-                Slog.d(TAG, "Registered for death of " + packageName);
-            }
-        } else if (!enable && r != null) {
-            // Unregister death recipient as the app goes away.
-            token.unlinkToDeath(r, 0);
-            mBleApps.remove(token);
-            if (DBG) {
-                Slog.d(TAG, "Unregistered for death of " + packageName);
-            }
-        }
-        int appCount = mBleApps.size();
-        if (DBG) {
-            Slog.d(TAG, appCount + " registered Ble Apps");
-        }
-        return appCount;
-    }
-
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    private boolean checkBluetoothPermissions(AttributionSource attributionSource, String message,
-            boolean requireForeground) {
-        if (isBluetoothDisallowed()) {
-            if (DBG) {
-                Slog.d(TAG, "checkBluetoothPermissions: bluetooth disallowed");
-            }
-            return false;
-        }
-        // Check if packageName belongs to callingUid
-        final int callingUid = Binder.getCallingUid();
-        final boolean isCallerSystem = UserHandle.getAppId(callingUid) == Process.SYSTEM_UID;
-        if (!isCallerSystem) {
-            checkPackage(callingUid, attributionSource.getPackageName());
-
-            if (requireForeground && !checkIfCallerIsForegroundUser()) {
-                Slog.w(TAG, "Not allowed for non-active and non system user");
-                return false;
-            }
-
-            if (!checkConnectPermissionForDataDelivery(mContext, attributionSource, message)) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    public boolean enableBle(AttributionSource attributionSource, IBinder token)
-            throws RemoteException {
-        final String packageName = attributionSource.getPackageName();
-        if (!checkBluetoothPermissions(attributionSource, "enableBle", false)) {
-            if (DBG) {
-                Slog.d(TAG, "enableBle(): bluetooth disallowed");
-            }
-            return false;
-        }
-
-        if (DBG) {
-            Slog.d(TAG, "enableBle(" + packageName + "):  mBluetooth =" + mBluetooth
-                    + " mBinding = " + mBinding + " mState = "
-                    + BluetoothAdapter.nameForState(mState));
-        }
-        updateBleAppCount(token, true, packageName);
-
-        if (mState == BluetoothAdapter.STATE_ON
-                || mState == BluetoothAdapter.STATE_BLE_ON
-                || mState == BluetoothAdapter.STATE_TURNING_ON
-                || mState == BluetoothAdapter.STATE_TURNING_OFF
-                || mState == BluetoothAdapter.STATE_BLE_TURNING_ON) {
-            Log.d(TAG, "enableBLE(): Bluetooth is already enabled or is turning on");
-            return true;
-        }
-        synchronized (mReceiver) {
-            // waive WRITE_SECURE_SETTINGS permission check
-            sendEnableMsg(false, BluetoothProtoEnums.ENABLE_DISABLE_REASON_APPLICATION_REQUEST,
-                    packageName, true);
-        }
-        return true;
-    }
-
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)
-    public boolean disableBle(AttributionSource attributionSource, IBinder token)
-            throws RemoteException {
-        final String packageName = attributionSource.getPackageName();
-        if (!checkBluetoothPermissions(attributionSource, "disableBle", false)) {
-            if (DBG) {
-                Slog.d(TAG, "disableBLE(): bluetooth disallowed");
-            }
-            return false;
-        }
-
-        if (DBG) {
-            Slog.d(TAG, "disableBle(" + packageName + "):  mBluetooth =" + mBluetooth
-                    + " mBinding = " + mBinding + " mState = "
-                    + BluetoothAdapter.nameForState(mState));
-        }
-
-        if (mState == BluetoothAdapter.STATE_OFF) {
-            Slog.d(TAG, "disableBLE(): Already disabled");
-            return false;
-        }
-        updateBleAppCount(token, false, packageName);
-
-        if (mState == BluetoothAdapter.STATE_BLE_ON && !isBleAppPresent()) {
-            if (mEnable) {
-                disableBleScanMode();
-            }
-            if (!mEnableExternal) {
-                addActiveLog(BluetoothProtoEnums.ENABLE_DISABLE_REASON_APPLICATION_REQUEST,
-                        packageName, false);
-                sendBrEdrDownCallback(attributionSource);
-            }
-        }
-        return true;
-    }
-
-    // Clear all apps using BLE scan only mode.
-    private void clearBleApps() {
-        mBleApps.clear();
-    }
-
-    /** @hide */
-    public boolean isBleAppPresent() {
-        if (DBG) {
-            Slog.d(TAG, "isBleAppPresent() count: " + mBleApps.size());
-        }
-        return mBleApps.size() > 0;
-    }
-
-    /**
-     * Call IBluetooth.onLeServiceUp() to continue if Bluetooth should be on,
-     * call IBluetooth.onBrEdrDown() to disable if Bluetooth should be off.
-     */
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)
-    private void continueFromBleOnState() {
-        if (DBG) {
-            Slog.d(TAG, "continueFromBleOnState()");
-        }
-        try {
-            mBluetoothLock.readLock().lock();
-            if (mBluetooth == null) {
-                Slog.e(TAG, "onBluetoothServiceUp: mBluetooth is null!");
-                return;
-            }
-            if (!mEnableExternal && !isBleAppPresent()) {
-                Slog.i(TAG, "Bluetooth was disabled while enabling BLE, disable BLE now");
-                mEnable = false;
-                mBluetooth.onBrEdrDown(mContext.getAttributionSource());
-                return;
-            }
-            if (isBluetoothPersistedStateOnBluetooth() || !isBleAppPresent()) {
-                // This triggers transition to STATE_ON
-                mBluetooth.onLeServiceUp(mContext.getAttributionSource());
-                persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH);
-            }
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Unable to call onServiceUp", e);
-        } finally {
-            mBluetoothLock.readLock().unlock();
-        }
-    }
-
-    /**
-     * Inform BluetoothAdapter instances that BREDR part is down
-     * and turn off all service and stack if no LE app needs it
-     */
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    private void sendBrEdrDownCallback(AttributionSource attributionSource) {
-        if (DBG) {
-            Slog.d(TAG, "Calling sendBrEdrDownCallback callbacks");
-        }
-
-        if (mBluetooth == null) {
-            Slog.w(TAG, "Bluetooth handle is null");
-            return;
-        }
-
-        if (isBleAppPresent()) {
-            // Need to stay at BLE ON. Disconnect all Gatt connections
-            try {
-                mBluetoothGatt.unregAll(attributionSource);
-            } catch (RemoteException e) {
-                Slog.e(TAG, "Unable to disconnect all apps.", e);
-            }
-        } else {
-            try {
-                mBluetoothLock.readLock().lock();
-                if (mBluetooth != null) {
-                    mBluetooth.onBrEdrDown(attributionSource);
-                }
-            } catch (RemoteException e) {
-                Slog.e(TAG, "Call to onBrEdrDown() failed.", e);
-            } finally {
-                mBluetoothLock.readLock().unlock();
-            }
-        }
-
-    }
-
-    public boolean enableNoAutoConnect(AttributionSource attributionSource) {
-        final String packageName = attributionSource.getPackageName();
-        if (!checkBluetoothPermissions(attributionSource, "enableNoAutoConnect", false)) {
-            if (DBG) {
-                Slog.d(TAG, "enableNoAutoConnect(): not enabling - bluetooth disallowed");
-            }
-            return false;
-        }
-
-        if (DBG) {
-            Slog.d(TAG, "enableNoAutoConnect():  mBluetooth =" + mBluetooth + " mBinding = "
-                    + mBinding);
-        }
-
-        int callingAppId = UserHandle.getAppId(Binder.getCallingUid());
-        if (callingAppId != Process.NFC_UID) {
-            throw new SecurityException("no permission to enable Bluetooth quietly");
-        }
-
-        synchronized (mReceiver) {
-            mQuietEnableExternal = true;
-            mEnableExternal = true;
-            sendEnableMsg(true,
-                    BluetoothProtoEnums.ENABLE_DISABLE_REASON_APPLICATION_REQUEST, packageName);
-        }
-        return true;
-    }
-
-    public boolean enable(AttributionSource attributionSource) throws RemoteException {
-        final String packageName = attributionSource.getPackageName();
-        if (!checkBluetoothPermissions(attributionSource, "enable", true)) {
-            if (DBG) {
-                Slog.d(TAG, "enable(): not enabling - bluetooth disallowed");
-            }
-            return false;
-        }
-
-        final int callingUid = Binder.getCallingUid();
-        final boolean callerSystem = UserHandle.getAppId(callingUid) == Process.SYSTEM_UID;
-        if (!callerSystem && !isEnabled() && mWirelessConsentRequired
-                && startConsentUiIfNeeded(packageName,
-                callingUid, BluetoothAdapter.ACTION_REQUEST_ENABLE)) {
-            return false;
-        }
-
-        if (DBG) {
-            Slog.d(TAG, "enable(" + packageName + "):  mBluetooth =" + mBluetooth + " mBinding = "
-                    + mBinding + " mState = " + BluetoothAdapter.nameForState(mState));
-        }
-
-        synchronized (mReceiver) {
-            mQuietEnableExternal = false;
-            mEnableExternal = true;
-            // waive WRITE_SECURE_SETTINGS permission check
-            sendEnableMsg(false,
-                    BluetoothProtoEnums.ENABLE_DISABLE_REASON_APPLICATION_REQUEST, packageName);
-        }
-        if (DBG) {
-            Slog.d(TAG, "enable returning");
-        }
-        return true;
-    }
-
-    public boolean disable(AttributionSource attributionSource, boolean persist)
-            throws RemoteException {
-        if (!persist) {
-            mContext.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED,
-                    "Need BLUETOOTH_PRIVILEGED permission");
-        }
-
-        final String packageName = attributionSource.getPackageName();
-        if (!checkBluetoothPermissions(attributionSource, "disable", true)) {
-            if (DBG) {
-                Slog.d(TAG, "disable(): not disabling - bluetooth disallowed");
-            }
-            return false;
-        }
-
-        final int callingUid = Binder.getCallingUid();
-        final boolean callerSystem = UserHandle.getAppId(callingUid) == Process.SYSTEM_UID;
-        if (!callerSystem && isEnabled() && mWirelessConsentRequired
-                && startConsentUiIfNeeded(packageName,
-                callingUid, BluetoothAdapter.ACTION_REQUEST_DISABLE)) {
-            return false;
-        }
-
-        if (DBG) {
-            Slog.d(TAG, "disable(): mBluetooth = " + mBluetooth + " mBinding = " + mBinding);
-        }
-
-        synchronized (mReceiver) {
-            if (!isBluetoothPersistedStateOnAirplane()) {
-                if (persist) {
-                    persistBluetoothSetting(BLUETOOTH_OFF);
-                }
-                mEnableExternal = false;
-            }
-            sendDisableMsg(BluetoothProtoEnums.ENABLE_DISABLE_REASON_APPLICATION_REQUEST,
-                    packageName);
-        }
-        return true;
-    }
-
-    private boolean startConsentUiIfNeeded(String packageName,
-            int callingUid, String intentAction) throws RemoteException {
-        if (checkBluetoothPermissionWhenWirelessConsentRequired()) {
-            return false;
-        }
-        try {
-            // Validate the package only if we are going to use it
-            ApplicationInfo applicationInfo = mContext.getPackageManager()
-                    .getApplicationInfoAsUser(packageName,
-                            PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
-                            UserHandle.getUserId(callingUid));
-            if (applicationInfo.uid != callingUid) {
-                throw new SecurityException("Package " + packageName
-                        + " not in uid " + callingUid);
-            }
-
-            Intent intent = new Intent(intentAction);
-            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
-            intent.setFlags(
-                    Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
-            try {
-                mContext.startActivity(intent);
-            } catch (ActivityNotFoundException e) {
-                // Shouldn't happen
-                Slog.e(TAG, "Intent to handle action " + intentAction + " missing");
-                return false;
-            }
-            return true;
-        } catch (PackageManager.NameNotFoundException e) {
-            throw new RemoteException(e.getMessage());
-        }
-    }
-
-    /**
-     * Check if AppOpsManager is available and the packageName belongs to uid
-     *
-     * A null package belongs to any uid
-     */
-    private void checkPackage(int uid, String packageName) {
-        if (mAppOps == null) {
-            Slog.w(TAG, "checkPackage(): called before system boot up, uid "
-                    + uid + ", packageName " + packageName);
-            throw new IllegalStateException("System has not boot yet");
-        }
-        if (packageName == null) {
-            Slog.w(TAG, "checkPackage(): called with null packageName from " + uid);
-            return;
-        }
-        try {
-            mAppOps.checkPackage(uid, packageName);
-        } catch (SecurityException e) {
-            Slog.w(TAG, "checkPackage(): " + packageName + " does not belong to uid " + uid);
-            throw new SecurityException(e.getMessage());
-        }
-    }
-
-    /**
-     * Check if the caller must still pass permission check or if the caller is exempted
-     * from the consent UI via the MANAGE_BLUETOOTH_WHEN_WIRELESS_CONSENT_REQUIRED check.
-     *
-     * Commands from some callers may be exempted from triggering the consent UI when
-     * enabling bluetooth. This exemption is checked via the
-     * MANAGE_BLUETOOTH_WHEN_WIRELESS_CONSENT_REQUIRED and allows calls to skip
-     * the consent UI where it may otherwise be required.
-     *
-     * @hide
-     */
-    @SuppressLint("AndroidFrameworkRequiresPermission")
-    private boolean checkBluetoothPermissionWhenWirelessConsentRequired() {
-        int result = mContext.checkCallingPermission(
-                android.Manifest.permission.MANAGE_BLUETOOTH_WHEN_WIRELESS_CONSENT_REQUIRED);
-        return result == PackageManager.PERMISSION_GRANTED;
-    }
-
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)
-    public void unbindAndFinish() {
-        if (DBG) {
-            Slog.d(TAG, "unbindAndFinish(): " + mBluetooth + " mBinding = " + mBinding
-                    + " mUnbinding = " + mUnbinding);
-        }
-
-        try {
-            mBluetoothLock.writeLock().lock();
-            if (mUnbinding) {
-                return;
-            }
-            mUnbinding = true;
-            mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE);
-            mHandler.removeMessages(MESSAGE_BIND_PROFILE_SERVICE);
-            if (mBluetooth != null) {
-                //Unregister callback object
-                try {
-                    mBluetooth.unregisterCallback(mBluetoothCallback,
-                            mContext.getAttributionSource());
-                } catch (RemoteException re) {
-                    Slog.e(TAG, "Unable to unregister BluetoothCallback", re);
-                }
-                mBluetoothBinder = null;
-                mBluetooth = null;
-                mContext.unbindService(mConnection);
-                mUnbinding = false;
-                mBinding = false;
-            } else {
-                mUnbinding = false;
-            }
-            mBluetoothGatt = null;
-        } finally {
-            mBluetoothLock.writeLock().unlock();
-        }
-    }
-
-    public IBluetoothGatt getBluetoothGatt() {
-        // sync protection
-        return mBluetoothGatt;
-    }
-
-    @Override
-    public boolean bindBluetoothProfileService(int bluetoothProfile,
-            IBluetoothProfileServiceConnection proxy) {
-        if (mState != BluetoothAdapter.STATE_ON) {
-            if (DBG) {
-                Slog.d(TAG, "Trying to bind to profile: " + bluetoothProfile
-                        + ", while Bluetooth was disabled");
-            }
-            return false;
-        }
-        synchronized (mProfileServices) {
-            ProfileServiceConnections psc = mProfileServices.get(new Integer(bluetoothProfile));
-            if (psc == null) {
-                if (DBG) {
-                    Slog.d(TAG, "Creating new ProfileServiceConnections object for" + " profile: "
-                            + bluetoothProfile);
-                }
-
-                Intent intent;
-                if (bluetoothProfile == BluetoothProfile.HEADSET) {
-                    intent = new Intent(IBluetoothHeadset.class.getName());
-                } else if (bluetoothProfile== BluetoothProfile.LE_CALL_CONTROL) {
-                    intent = new Intent(IBluetoothLeCallControl.class.getName());
-                } else {
-                    return false;
-                }
-
-                psc = new ProfileServiceConnections(intent);
-                if (!psc.bindService()) {
-                    return false;
-                }
-
-                mProfileServices.put(new Integer(bluetoothProfile), psc);
-            }
-        }
-
-        // Introducing a delay to give the client app time to prepare
-        Message addProxyMsg = mHandler.obtainMessage(MESSAGE_ADD_PROXY_DELAYED);
-        addProxyMsg.arg1 = bluetoothProfile;
-        addProxyMsg.obj = proxy;
-        mHandler.sendMessageDelayed(addProxyMsg, ADD_PROXY_DELAY_MS);
-        return true;
-    }
-
-    @Override
-    public void unbindBluetoothProfileService(int bluetoothProfile,
-            IBluetoothProfileServiceConnection proxy) {
-        synchronized (mProfileServices) {
-            Integer profile = new Integer(bluetoothProfile);
-            ProfileServiceConnections psc = mProfileServices.get(profile);
-            if (psc == null) {
-                return;
-            }
-            psc.removeProxy(proxy);
-            if (psc.isEmpty()) {
-                // All prxoies are disconnected, unbind with the service.
-                try {
-                    mContext.unbindService(psc);
-                } catch (IllegalArgumentException e) {
-                    Slog.e(TAG, "Unable to unbind service with intent: " + psc.mIntent, e);
-                }
-                mProfileServices.remove(profile);
-            }
-        }
-    }
-
-    private void unbindAllBluetoothProfileServices() {
-        synchronized (mProfileServices) {
-            for (Integer i : mProfileServices.keySet()) {
-                ProfileServiceConnections psc = mProfileServices.get(i);
-                try {
-                    mContext.unbindService(psc);
-                } catch (IllegalArgumentException e) {
-                    Slog.e(TAG, "Unable to unbind service with intent: " + psc.mIntent, e);
-                }
-                psc.removeAllProxies();
-            }
-            mProfileServices.clear();
-        }
-    }
-
-    /**
-     * Send enable message and set adapter name and address. Called when the boot phase becomes
-     * PHASE_SYSTEM_SERVICES_READY.
-     */
-    public void handleOnBootPhase() {
-        if (DBG) {
-            Slog.d(TAG, "Bluetooth boot completed");
-        }
-        mAppOps = mContext.getSystemService(AppOpsManager.class);
-        UserManagerInternal userManagerInternal =
-                LocalServices.getService(UserManagerInternal.class);
-        userManagerInternal.addUserRestrictionsListener(mUserRestrictionsListener);
-        final boolean isBluetoothDisallowed = isBluetoothDisallowed();
-        if (isBluetoothDisallowed) {
-            return;
-        }
-        final boolean isSafeMode = mContext.getPackageManager().isSafeMode();
-        if (mEnableExternal && isBluetoothPersistedStateOnBluetooth() && !isSafeMode) {
-            if (DBG) {
-                Slog.d(TAG, "Auto-enabling Bluetooth.");
-            }
-            sendEnableMsg(mQuietEnableExternal,
-                    BluetoothProtoEnums.ENABLE_DISABLE_REASON_SYSTEM_BOOT,
-                    mContext.getPackageName());
-        } else if (!isNameAndAddressSet()) {
-            if (DBG) {
-                Slog.d(TAG, "Getting adapter name and address");
-            }
-            Message getMsg = mHandler.obtainMessage(MESSAGE_GET_NAME_AND_ADDRESS);
-            mHandler.sendMessage(getMsg);
-        }
-
-        mBluetoothModeChangeHelper = new BluetoothModeChangeHelper(mContext);
-        if (mBluetoothAirplaneModeListener != null) {
-            mBluetoothAirplaneModeListener.start(mBluetoothModeChangeHelper);
-        }
-        registerForProvisioningStateChange();
-        mBluetoothDeviceConfigListener = new BluetoothDeviceConfigListener(this, DBG);
-    }
-
-    /**
-     * Called when switching to a different foreground user.
-     */
-    public void handleOnSwitchUser(int userHandle) {
-        if (DBG) {
-            Slog.d(TAG, "User " + userHandle + " switched");
-        }
-        mHandler.obtainMessage(MESSAGE_USER_SWITCHED, userHandle, 0).sendToTarget();
-    }
-
-    /**
-     * Called when user is unlocked.
-     */
-    public void handleOnUnlockUser(int userHandle) {
-        if (DBG) {
-            Slog.d(TAG, "User " + userHandle + " unlocked");
-        }
-        mHandler.obtainMessage(MESSAGE_USER_UNLOCKED, userHandle, 0).sendToTarget();
-    }
-
-    /**
-     * This class manages the clients connected to a given ProfileService
-     * and maintains the connection with that service.
-     */
-    private final class ProfileServiceConnections
-            implements ServiceConnection, IBinder.DeathRecipient {
-        final RemoteCallbackList<IBluetoothProfileServiceConnection> mProxies =
-                new RemoteCallbackList<IBluetoothProfileServiceConnection>();
-        IBinder mService;
-        ComponentName mClassName;
-        Intent mIntent;
-        boolean mInvokingProxyCallbacks = false;
-
-        ProfileServiceConnections(Intent intent) {
-            mService = null;
-            mClassName = null;
-            mIntent = intent;
-        }
-
-        private boolean bindService() {
-            int state = BluetoothAdapter.STATE_OFF;
-            try {
-                mBluetoothLock.readLock().lock();
-                if (mBluetooth != null) {
-                    state = mBluetooth.getState();
-                }
-            } catch (RemoteException e) {
-                Slog.e(TAG, "Unable to call getState", e);
-                return false;
-            } finally {
-                mBluetoothLock.readLock().unlock();
-            }
-
-            if (state != BluetoothAdapter.STATE_ON) {
-                if (DBG) {
-                    Slog.d(TAG, "Unable to bindService while Bluetooth is disabled");
-                }
-                return false;
-            }
-
-            if (mIntent != null && mService == null && doBind(mIntent, this, 0,
-                    UserHandle.CURRENT_OR_SELF)) {
-                Message msg = mHandler.obtainMessage(MESSAGE_BIND_PROFILE_SERVICE);
-                msg.obj = this;
-                mHandler.sendMessageDelayed(msg, TIMEOUT_BIND_MS);
-                return true;
-            }
-            Slog.w(TAG, "Unable to bind with intent: " + mIntent);
-            return false;
-        }
-
-        private void addProxy(IBluetoothProfileServiceConnection proxy) {
-            mProxies.register(proxy);
-            if (mService != null) {
-                try {
-                    proxy.onServiceConnected(mClassName, mService);
-                } catch (RemoteException e) {
-                    Slog.e(TAG, "Unable to connect to proxy", e);
-                }
-            } else {
-                if (!mHandler.hasMessages(MESSAGE_BIND_PROFILE_SERVICE, this)) {
-                    Message msg = mHandler.obtainMessage(MESSAGE_BIND_PROFILE_SERVICE);
-                    msg.obj = this;
-                    mHandler.sendMessage(msg);
-                }
-            }
-        }
-
-        private void removeProxy(IBluetoothProfileServiceConnection proxy) {
-            if (proxy != null) {
-                if (mProxies.unregister(proxy)) {
-                    try {
-                        proxy.onServiceDisconnected(mClassName);
-                    } catch (RemoteException e) {
-                        Slog.e(TAG, "Unable to disconnect proxy", e);
-                    }
-                }
-            } else {
-                Slog.w(TAG, "Trying to remove a null proxy");
-            }
-        }
-
-        private void removeAllProxies() {
-            onServiceDisconnected(mClassName);
-            mProxies.kill();
-        }
-
-        private boolean isEmpty() {
-            return mProxies.getRegisteredCallbackCount() == 0;
-        }
-
-        @Override
-        public void onServiceConnected(ComponentName className, IBinder service) {
-            // remove timeout message
-            mHandler.removeMessages(MESSAGE_BIND_PROFILE_SERVICE, this);
-            mService = service;
-            mClassName = className;
-            try {
-                mService.linkToDeath(this, 0);
-            } catch (RemoteException e) {
-                Slog.e(TAG, "Unable to linkToDeath", e);
-            }
-
-            if (mInvokingProxyCallbacks) {
-                Slog.e(TAG, "Proxy callbacks already in progress.");
-                return;
-            }
-            mInvokingProxyCallbacks = true;
-
-            final int n = mProxies.beginBroadcast();
-            try {
-                for (int i = 0; i < n; i++) {
-                    try {
-                        mProxies.getBroadcastItem(i).onServiceConnected(className, service);
-                    } catch (RemoteException e) {
-                        Slog.e(TAG, "Unable to connect to proxy", e);
-                    }
-                }
-            } finally {
-                mProxies.finishBroadcast();
-                mInvokingProxyCallbacks = false;
-            }
-        }
-
-        @Override
-        public void onServiceDisconnected(ComponentName className) {
-            if (mService == null) {
-                return;
-            }
-            try {
-                mService.unlinkToDeath(this, 0);
-            } catch (NoSuchElementException e) {
-                Log.e(TAG, "error unlinking to death", e);
-            }
-            mService = null;
-            mClassName = null;
-
-            if (mInvokingProxyCallbacks) {
-                Slog.e(TAG, "Proxy callbacks already in progress.");
-                return;
-            }
-            mInvokingProxyCallbacks = true;
-
-            final int n = mProxies.beginBroadcast();
-            try {
-                for (int i = 0; i < n; i++) {
-                    try {
-                        mProxies.getBroadcastItem(i).onServiceDisconnected(className);
-                    } catch (RemoteException e) {
-                        Slog.e(TAG, "Unable to disconnect from proxy", e);
-                    }
-                }
-            } finally {
-                mProxies.finishBroadcast();
-                mInvokingProxyCallbacks = false;
-            }
-        }
-
-        @Override
-        public void binderDied() {
-            if (DBG) {
-                Slog.w(TAG, "Profile service for profile: " + mClassName + " died.");
-            }
-            onServiceDisconnected(mClassName);
-            // Trigger rebind
-            Message msg = mHandler.obtainMessage(MESSAGE_BIND_PROFILE_SERVICE);
-            msg.obj = this;
-            mHandler.sendMessageDelayed(msg, TIMEOUT_BIND_MS);
-        }
-    }
-
-    private void sendBluetoothStateCallback(boolean isUp) {
-        try {
-            int n = mStateChangeCallbacks.beginBroadcast();
-            if (DBG) {
-                Slog.d(TAG, "Broadcasting onBluetoothStateChange(" + isUp + ") to " + n
-                        + " receivers.");
-            }
-            for (int i = 0; i < n; i++) {
-                try {
-                    mStateChangeCallbacks.getBroadcastItem(i).onBluetoothStateChange(isUp);
-                } catch (RemoteException e) {
-                    Slog.e(TAG, "Unable to call onBluetoothStateChange() on callback #" + i, e);
-                }
-            }
-        } finally {
-            mStateChangeCallbacks.finishBroadcast();
-        }
-    }
-
-    /**
-     * Inform BluetoothAdapter instances that Adapter service is up
-     */
-    private void sendBluetoothServiceUpCallback() {
-        synchronized (mCallbacks) {
-            try {
-                int n = mCallbacks.beginBroadcast();
-                Slog.d(TAG, "Broadcasting onBluetoothServiceUp() to " + n + " receivers.");
-                for (int i = 0; i < n; i++) {
-                    try {
-                        mCallbacks.getBroadcastItem(i).onBluetoothServiceUp(mBluetooth);
-                    } catch (RemoteException e) {
-                        Slog.e(TAG, "Unable to call onBluetoothServiceUp() on callback #" + i, e);
-                    }
-                }
-            } finally {
-                mCallbacks.finishBroadcast();
-            }
-        }
-    }
-
-    /**
-     * Inform BluetoothAdapter instances that Adapter service is down
-     */
-    private void sendBluetoothServiceDownCallback() {
-        synchronized (mCallbacks) {
-            try {
-                int n = mCallbacks.beginBroadcast();
-                Slog.d(TAG, "Broadcasting onBluetoothServiceDown() to " + n + " receivers.");
-                for (int i = 0; i < n; i++) {
-                    try {
-                        mCallbacks.getBroadcastItem(i).onBluetoothServiceDown();
-                    } catch (RemoteException e) {
-                        Slog.e(TAG, "Unable to call onBluetoothServiceDown() on callback #" + i, e);
-                    }
-                }
-            } finally {
-                mCallbacks.finishBroadcast();
-            }
-        }
-    }
-
-    public String getAddress(AttributionSource attributionSource) {
-        if (!checkConnectPermissionForDataDelivery(mContext, attributionSource, "getAddress")) {
-            return null;
-        }
-
-        if ((Binder.getCallingUid() != Process.SYSTEM_UID) && (!checkIfCallerIsForegroundUser())) {
-            Slog.w(TAG, "getAddress(): not allowed for non-active and non system user");
-            return null;
-        }
-
-        if (mContext.checkCallingOrSelfPermission(Manifest.permission.LOCAL_MAC_ADDRESS)
-                != PackageManager.PERMISSION_GRANTED) {
-            return BluetoothAdapter.DEFAULT_MAC_ADDRESS;
-        }
-
-        try {
-            mBluetoothLock.readLock().lock();
-            if (mBluetooth != null) {
-                return mBluetooth.getAddressWithAttribution(attributionSource);
-            }
-        } catch (RemoteException e) {
-            Slog.e(TAG,
-                    "getAddress(): Unable to retrieve address remotely. Returning cached address",
-                    e);
-        } finally {
-            mBluetoothLock.readLock().unlock();
-        }
-
-        // mAddress is accessed from outside.
-        // It is alright without a lock. Here, bluetooth is off, no other thread is
-        // changing mAddress
-        return mAddress;
-    }
-
-    public String getName(AttributionSource attributionSource) {
-        if (!checkConnectPermissionForDataDelivery(mContext, attributionSource, "getName")) {
-            return null;
-        }
-
-        if ((Binder.getCallingUid() != Process.SYSTEM_UID) && (!checkIfCallerIsForegroundUser())) {
-            Slog.w(TAG, "getName(): not allowed for non-active and non system user");
-            return null;
-        }
-
-        try {
-            mBluetoothLock.readLock().lock();
-            if (mBluetooth != null) {
-                return mBluetooth.getName(attributionSource);
-            }
-        } catch (RemoteException e) {
-            Slog.e(TAG, "getName(): Unable to retrieve name remotely. Returning cached name", e);
-        } finally {
-            mBluetoothLock.readLock().unlock();
-        }
-
-        // mName is accessed from outside.
-        // It alright without a lock. Here, bluetooth is off, no other thread is
-        // changing mName
-        return mName;
-    }
-
-    private class BluetoothServiceConnection implements ServiceConnection {
-        public void onServiceConnected(ComponentName componentName, IBinder service) {
-            String name = componentName.getClassName();
-            if (DBG) {
-                Slog.d(TAG, "BluetoothServiceConnection: " + name);
-            }
-            Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_CONNECTED);
-            if (name.equals("com.android.bluetooth.btservice.AdapterService")) {
-                msg.arg1 = SERVICE_IBLUETOOTH;
-            } else if (name.equals("com.android.bluetooth.gatt.GattService")) {
-                msg.arg1 = SERVICE_IBLUETOOTHGATT;
-            } else {
-                Slog.e(TAG, "Unknown service connected: " + name);
-                return;
-            }
-            msg.obj = service;
-            mHandler.sendMessage(msg);
-        }
-
-        public void onServiceDisconnected(ComponentName componentName) {
-            // Called if we unexpectedly disconnect.
-            String name = componentName.getClassName();
-            if (DBG) {
-                Slog.d(TAG, "BluetoothServiceConnection, disconnected: " + name);
-            }
-            Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED);
-            if (name.equals("com.android.bluetooth.btservice.AdapterService")) {
-                msg.arg1 = SERVICE_IBLUETOOTH;
-            } else if (name.equals("com.android.bluetooth.gatt.GattService")) {
-                msg.arg1 = SERVICE_IBLUETOOTHGATT;
-            } else {
-                Slog.e(TAG, "Unknown service disconnected: " + name);
-                return;
-            }
-            mHandler.sendMessage(msg);
-        }
-    }
-
-    private BluetoothServiceConnection mConnection = new BluetoothServiceConnection();
-
-    private class BluetoothHandler extends Handler {
-        boolean mGetNameAddressOnly = false;
-        private int mWaitForEnableRetry;
-        private int mWaitForDisableRetry;
-
-        BluetoothHandler(Looper looper) {
-            super(looper);
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case MESSAGE_GET_NAME_AND_ADDRESS:
-                    if (DBG) {
-                        Slog.d(TAG, "MESSAGE_GET_NAME_AND_ADDRESS");
-                    }
-                    try {
-                        mBluetoothLock.writeLock().lock();
-                        if ((mBluetooth == null) && (!mBinding)) {
-                            if (DBG) {
-                                Slog.d(TAG, "Binding to service to get name and address");
-                            }
-                            mGetNameAddressOnly = true;
-                            Message timeoutMsg = mHandler.obtainMessage(MESSAGE_TIMEOUT_BIND);
-                            mHandler.sendMessageDelayed(timeoutMsg, TIMEOUT_BIND_MS);
-                            Intent i = new Intent(IBluetooth.class.getName());
-                            if (!doBind(i, mConnection,
-                                    Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
-                                    UserHandle.CURRENT)) {
-                                mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
-                            } else {
-                                mBinding = true;
-                            }
-                        } else if (mBluetooth != null) {
-                            try {
-                                storeNameAndAddress(
-                                        mBluetooth.getName(mContext.getAttributionSource()),
-                                        mBluetooth.getAddressWithAttribution(
-                                                mContext.getAttributionSource()));
-                            } catch (RemoteException re) {
-                                Slog.e(TAG, "Unable to grab names", re);
-                            }
-                            if (mGetNameAddressOnly && !mEnable) {
-                                unbindAndFinish();
-                            }
-                            mGetNameAddressOnly = false;
-                        }
-                    } finally {
-                        mBluetoothLock.writeLock().unlock();
-                    }
-                    break;
-
-                case MESSAGE_ENABLE:
-                    int quietEnable = msg.arg1;
-                    int isBle  = msg.arg2;
-                    if (mHandler.hasMessages(MESSAGE_HANDLE_DISABLE_DELAYED)
-                            || mHandler.hasMessages(MESSAGE_HANDLE_ENABLE_DELAYED)) {
-                        // We are handling enable or disable right now, wait for it.
-                        mHandler.sendMessageDelayed(mHandler.obtainMessage(MESSAGE_ENABLE,
-                                quietEnable, isBle), ENABLE_DISABLE_DELAY_MS);
-                        break;
-                    }
-
-                    if (DBG) {
-                        Slog.d(TAG, "MESSAGE_ENABLE(" + quietEnable + "): mBluetooth = "
-                                + mBluetooth);
-                    }
-                    mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE);
-                    mEnable = true;
-
-                    if (isBle == 0) {
-                        persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH);
-                    }
-
-                    // Use service interface to get the exact state
-                    try {
-                        mBluetoothLock.readLock().lock();
-                        if (mBluetooth != null) {
-                            boolean isHandled = true;
-                            int state = mBluetooth.getState();
-                            switch (state) {
-                                case BluetoothAdapter.STATE_BLE_ON:
-                                    if (isBle == 1) {
-                                        Slog.i(TAG, "Already at BLE_ON State");
-                                    } else {
-                                        Slog.w(TAG, "BT Enable in BLE_ON State, going to ON");
-                                        mBluetooth.onLeServiceUp(mContext.getAttributionSource());
-                                    }
-                                    break;
-                                case BluetoothAdapter.STATE_BLE_TURNING_ON:
-                                case BluetoothAdapter.STATE_TURNING_ON:
-                                case BluetoothAdapter.STATE_ON:
-                                    Slog.i(TAG, "MESSAGE_ENABLE: already enabled");
-                                    break;
-                                default:
-                                    isHandled = false;
-                                    break;
-                            }
-                            if (isHandled) break;
-                        }
-                    } catch (RemoteException e) {
-                        Slog.e(TAG, "", e);
-                    } finally {
-                        mBluetoothLock.readLock().unlock();
-                    }
-
-                    mQuietEnable = (quietEnable == 1);
-                    if (mBluetooth == null) {
-                        handleEnable(mQuietEnable);
-                    } else {
-                        //
-                        // We need to wait until transitioned to STATE_OFF and
-                        // the previous Bluetooth process has exited. The
-                        // waiting period has three components:
-                        // (a) Wait until the local state is STATE_OFF. This
-                        //     is accomplished by sending delay a message
-                        //     MESSAGE_HANDLE_ENABLE_DELAYED
-                        // (b) Wait until the STATE_OFF state is updated to
-                        //     all components.
-                        // (c) Wait until the Bluetooth process exits, and
-                        //     ActivityManager detects it.
-                        // The waiting for (b) and (c) is accomplished by
-                        // delaying the MESSAGE_RESTART_BLUETOOTH_SERVICE
-                        // message. The delay time is backed off if Bluetooth
-                        // continuously failed to turn on itself.
-                        //
-                        mWaitForEnableRetry = 0;
-                        Message enableDelayedMsg =
-                                mHandler.obtainMessage(MESSAGE_HANDLE_ENABLE_DELAYED);
-                        mHandler.sendMessageDelayed(enableDelayedMsg, ENABLE_DISABLE_DELAY_MS);
-                    }
-                    break;
-
-                case MESSAGE_DISABLE:
-                    if (mHandler.hasMessages(MESSAGE_HANDLE_DISABLE_DELAYED) || mBinding
-                            || mHandler.hasMessages(MESSAGE_HANDLE_ENABLE_DELAYED)) {
-                        // We are handling enable or disable right now, wait for it.
-                        mHandler.sendMessageDelayed(mHandler.obtainMessage(MESSAGE_DISABLE),
-                                ENABLE_DISABLE_DELAY_MS);
-                        break;
-                    }
-
-                    if (DBG) {
-                        Slog.d(TAG, "MESSAGE_DISABLE: mBluetooth = " + mBluetooth
-                                + ", mBinding = " + mBinding);
-                    }
-                    mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE);
-
-                    if (mEnable && mBluetooth != null) {
-                        mWaitForDisableRetry = 0;
-                        Message disableDelayedMsg =
-                                mHandler.obtainMessage(MESSAGE_HANDLE_DISABLE_DELAYED, 0, 0);
-                        mHandler.sendMessageDelayed(disableDelayedMsg, ENABLE_DISABLE_DELAY_MS);
-                    } else {
-                        mEnable = false;
-                        handleDisable();
-                    }
-                    break;
-
-                case MESSAGE_HANDLE_ENABLE_DELAYED: {
-                    // The Bluetooth is turning off, wait for STATE_OFF
-                    if (mState != BluetoothAdapter.STATE_OFF) {
-                        if (mWaitForEnableRetry < MAX_WAIT_FOR_ENABLE_DISABLE_RETRIES) {
-                            mWaitForEnableRetry++;
-                            Message enableDelayedMsg =
-                                    mHandler.obtainMessage(MESSAGE_HANDLE_ENABLE_DELAYED);
-                            mHandler.sendMessageDelayed(enableDelayedMsg, ENABLE_DISABLE_DELAY_MS);
-                            break;
-                        } else {
-                            Slog.e(TAG, "Wait for STATE_OFF timeout");
-                        }
-                    }
-                    // Either state is changed to STATE_OFF or reaches the maximum retry, we
-                    // should move forward to the next step.
-                    mWaitForEnableRetry = 0;
-                    Message restartMsg =
-                            mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE);
-                    mHandler.sendMessageDelayed(restartMsg, getServiceRestartMs());
-                    Slog.d(TAG, "Handle enable is finished");
-                    break;
-                }
-
-                case MESSAGE_HANDLE_DISABLE_DELAYED: {
-                    boolean disabling = (msg.arg1 == 1);
-                    Slog.d(TAG, "MESSAGE_HANDLE_DISABLE_DELAYED: disabling:" + disabling);
-                    if (!disabling) {
-                        // The Bluetooth is turning on, wait for STATE_ON
-                        if (mState != BluetoothAdapter.STATE_ON) {
-                            if (mWaitForDisableRetry < MAX_WAIT_FOR_ENABLE_DISABLE_RETRIES) {
-                                mWaitForDisableRetry++;
-                                Message disableDelayedMsg = mHandler.obtainMessage(
-                                        MESSAGE_HANDLE_DISABLE_DELAYED, 0, 0);
-                                mHandler.sendMessageDelayed(disableDelayedMsg,
-                                        ENABLE_DISABLE_DELAY_MS);
-                                break;
-                            } else {
-                                Slog.e(TAG, "Wait for STATE_ON timeout");
-                            }
-                        }
-                        // Either state is changed to STATE_ON or reaches the maximum retry, we
-                        // should move forward to the next step.
-                        mWaitForDisableRetry = 0;
-                        mEnable = false;
-                        handleDisable();
-                        // Wait for state exiting STATE_ON
-                        Message disableDelayedMsg =
-                                mHandler.obtainMessage(MESSAGE_HANDLE_DISABLE_DELAYED, 1, 0);
-                        mHandler.sendMessageDelayed(disableDelayedMsg, ENABLE_DISABLE_DELAY_MS);
-                    } else {
-                        // The Bluetooth is turning off, wait for exiting STATE_ON
-                        if (mState == BluetoothAdapter.STATE_ON) {
-                            if (mWaitForDisableRetry < MAX_WAIT_FOR_ENABLE_DISABLE_RETRIES) {
-                                mWaitForDisableRetry++;
-                                Message disableDelayedMsg = mHandler.obtainMessage(
-                                        MESSAGE_HANDLE_DISABLE_DELAYED, 1, 0);
-                                mHandler.sendMessageDelayed(disableDelayedMsg,
-                                        ENABLE_DISABLE_DELAY_MS);
-                                break;
-                            } else {
-                                Slog.e(TAG, "Wait for exiting STATE_ON timeout");
-                            }
-                        }
-                        // Either state is exited from STATE_ON or reaches the maximum retry, we
-                        // should move forward to the next step.
-                        Slog.d(TAG, "Handle disable is finished");
-                    }
-                    break;
-                }
-
-                case MESSAGE_RESTORE_USER_SETTING:
-                    if ((msg.arg1 == RESTORE_SETTING_TO_OFF) && mEnable) {
-                        if (DBG) {
-                            Slog.d(TAG, "Restore Bluetooth state to disabled");
-                        }
-                        persistBluetoothSetting(BLUETOOTH_OFF);
-                        mEnableExternal = false;
-                        sendDisableMsg(
-                                BluetoothProtoEnums.ENABLE_DISABLE_REASON_RESTORE_USER_SETTING,
-                                mContext.getPackageName());
-                    } else if ((msg.arg1 == RESTORE_SETTING_TO_ON) && !mEnable) {
-                        if (DBG) {
-                            Slog.d(TAG, "Restore Bluetooth state to enabled");
-                        }
-                        mQuietEnableExternal = false;
-                        mEnableExternal = true;
-                        // waive WRITE_SECURE_SETTINGS permission check
-                        sendEnableMsg(false,
-                                BluetoothProtoEnums.ENABLE_DISABLE_REASON_RESTORE_USER_SETTING,
-                                mContext.getPackageName());
-                    }
-                    break;
-                case MESSAGE_REGISTER_STATE_CHANGE_CALLBACK: {
-                    IBluetoothStateChangeCallback callback =
-                            (IBluetoothStateChangeCallback) msg.obj;
-                    mStateChangeCallbacks.register(callback);
-                    break;
-                }
-                case MESSAGE_UNREGISTER_STATE_CHANGE_CALLBACK: {
-                    IBluetoothStateChangeCallback callback =
-                            (IBluetoothStateChangeCallback) msg.obj;
-                    mStateChangeCallbacks.unregister(callback);
-                    break;
-                }
-                case MESSAGE_ADD_PROXY_DELAYED: {
-                    ProfileServiceConnections psc = mProfileServices.get(msg.arg1);
-                    if (psc == null) {
-                        break;
-                    }
-                    IBluetoothProfileServiceConnection proxy =
-                            (IBluetoothProfileServiceConnection) msg.obj;
-                    psc.addProxy(proxy);
-                    break;
-                }
-                case MESSAGE_BIND_PROFILE_SERVICE: {
-                    ProfileServiceConnections psc = (ProfileServiceConnections) msg.obj;
-                    removeMessages(MESSAGE_BIND_PROFILE_SERVICE, msg.obj);
-                    if (psc == null) {
-                        break;
-                    }
-                    psc.bindService();
-                    break;
-                }
-                case MESSAGE_BLUETOOTH_SERVICE_CONNECTED: {
-                    if (DBG) {
-                        Slog.d(TAG, "MESSAGE_BLUETOOTH_SERVICE_CONNECTED: " + msg.arg1);
-                    }
-
-                    IBinder service = (IBinder) msg.obj;
-                    try {
-                        mBluetoothLock.writeLock().lock();
-                        if (msg.arg1 == SERVICE_IBLUETOOTHGATT) {
-                            mBluetoothGatt =
-                                    IBluetoothGatt.Stub.asInterface(Binder.allowBlocking(service));
-                            continueFromBleOnState();
-                            break;
-                        } // else must be SERVICE_IBLUETOOTH
-
-                        //Remove timeout
-                        mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
-
-                        mBinding = false;
-                        mBluetoothBinder = service;
-                        mBluetooth = IBluetooth.Stub.asInterface(Binder.allowBlocking(service));
-
-                        if (!isNameAndAddressSet()) {
-                            Message getMsg = mHandler.obtainMessage(MESSAGE_GET_NAME_AND_ADDRESS);
-                            mHandler.sendMessage(getMsg);
-                            if (mGetNameAddressOnly) {
-                                return;
-                            }
-                        }
-
-                        //Register callback object
-                        try {
-                            mBluetooth.registerCallback(mBluetoothCallback,
-                                    mContext.getAttributionSource());
-                        } catch (RemoteException re) {
-                            Slog.e(TAG, "Unable to register BluetoothCallback", re);
-                        }
-                        //Inform BluetoothAdapter instances that service is up
-                        sendBluetoothServiceUpCallback();
-
-                        //Do enable request
-                        try {
-                            if (!mBluetooth.enable(mQuietEnable, mContext.getAttributionSource())) {
-                                Slog.e(TAG, "IBluetooth.enable() returned false");
-                            }
-                        } catch (RemoteException e) {
-                            Slog.e(TAG, "Unable to call enable()", e);
-                        }
-                    } finally {
-                        mBluetoothLock.writeLock().unlock();
-                    }
-
-                    if (!mEnable) {
-                        waitForState(Set.of(BluetoothAdapter.STATE_ON));
-                        handleDisable();
-                        waitForState(Set.of(BluetoothAdapter.STATE_OFF,
-                                BluetoothAdapter.STATE_TURNING_ON,
-                                BluetoothAdapter.STATE_TURNING_OFF,
-                                BluetoothAdapter.STATE_BLE_TURNING_ON,
-                                BluetoothAdapter.STATE_BLE_ON,
-                                BluetoothAdapter.STATE_BLE_TURNING_OFF));
-                    }
-                    break;
-                }
-                case MESSAGE_BLUETOOTH_STATE_CHANGE: {
-                    int prevState = msg.arg1;
-                    int newState = msg.arg2;
-                    if (DBG) {
-                        Slog.d(TAG,
-                                "MESSAGE_BLUETOOTH_STATE_CHANGE: " + BluetoothAdapter.nameForState(
-                                        prevState) + " > " + BluetoothAdapter.nameForState(
-                                        newState));
-                    }
-                    mState = newState;
-                    bluetoothStateChangeHandler(prevState, newState);
-                    // handle error state transition case from TURNING_ON to OFF
-                    // unbind and rebind bluetooth service and enable bluetooth
-                    if ((prevState == BluetoothAdapter.STATE_BLE_TURNING_ON) && (newState
-                            == BluetoothAdapter.STATE_OFF) && (mBluetooth != null) && mEnable) {
-                        recoverBluetoothServiceFromError(false);
-                    }
-                    if ((prevState == BluetoothAdapter.STATE_TURNING_ON) && (newState
-                            == BluetoothAdapter.STATE_BLE_ON) && (mBluetooth != null) && mEnable) {
-                        recoverBluetoothServiceFromError(true);
-                    }
-                    // If we tried to enable BT while BT was in the process of shutting down,
-                    // wait for the BT process to fully tear down and then force a restart
-                    // here.  This is a bit of a hack (b/29363429).
-                    if ((prevState == BluetoothAdapter.STATE_BLE_TURNING_OFF) && (newState
-                            == BluetoothAdapter.STATE_OFF)) {
-                        if (mEnable) {
-                            Slog.d(TAG, "Entering STATE_OFF but mEnabled is true; restarting.");
-                            waitForState(Set.of(BluetoothAdapter.STATE_OFF));
-                            Message restartMsg =
-                                    mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE);
-                            mHandler.sendMessageDelayed(restartMsg, getServiceRestartMs());
-                        }
-                    }
-                    if (newState == BluetoothAdapter.STATE_ON
-                            || newState == BluetoothAdapter.STATE_BLE_ON) {
-                        // bluetooth is working, reset the counter
-                        if (mErrorRecoveryRetryCounter != 0) {
-                            Slog.w(TAG, "bluetooth is recovered from error");
-                            mErrorRecoveryRetryCounter = 0;
-                        }
-                    }
-                    break;
-                }
-                case MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED: {
-                    Slog.e(TAG, "MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED(" + msg.arg1 + ")");
-                    try {
-                        mBluetoothLock.writeLock().lock();
-                        if (msg.arg1 == SERVICE_IBLUETOOTH) {
-                            // if service is unbinded already, do nothing and return
-                            if (mBluetooth == null) {
-                                break;
-                            }
-                            mBluetooth = null;
-                        } else if (msg.arg1 == SERVICE_IBLUETOOTHGATT) {
-                            mBluetoothGatt = null;
-                            break;
-                        } else {
-                            Slog.e(TAG, "Unknown argument for service disconnect!");
-                            break;
-                        }
-                    } finally {
-                        mBluetoothLock.writeLock().unlock();
-                    }
-
-                    // log the unexpected crash
-                    addCrashLog();
-                    addActiveLog(BluetoothProtoEnums.ENABLE_DISABLE_REASON_CRASH,
-                            mContext.getPackageName(), false);
-                    if (mEnable) {
-                        mEnable = false;
-                        // Send a Bluetooth Restart message
-                        Message restartMsg =
-                                mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE);
-                        mHandler.sendMessageDelayed(restartMsg, getServiceRestartMs());
-                    }
-
-                    sendBluetoothServiceDownCallback();
-
-                    // Send BT state broadcast to update
-                    // the BT icon correctly
-                    if ((mState == BluetoothAdapter.STATE_TURNING_ON) || (mState
-                            == BluetoothAdapter.STATE_ON)) {
-                        bluetoothStateChangeHandler(BluetoothAdapter.STATE_ON,
-                                BluetoothAdapter.STATE_TURNING_OFF);
-                        mState = BluetoothAdapter.STATE_TURNING_OFF;
-                    }
-                    if (mState == BluetoothAdapter.STATE_TURNING_OFF) {
-                        bluetoothStateChangeHandler(BluetoothAdapter.STATE_TURNING_OFF,
-                                BluetoothAdapter.STATE_OFF);
-                    }
-
-                    mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE);
-                    mState = BluetoothAdapter.STATE_OFF;
-                    break;
-                }
-                case MESSAGE_RESTART_BLUETOOTH_SERVICE: {
-                    mErrorRecoveryRetryCounter++;
-                    Slog.d(TAG, "MESSAGE_RESTART_BLUETOOTH_SERVICE: retry count="
-                            + mErrorRecoveryRetryCounter);
-                    if (mErrorRecoveryRetryCounter < MAX_ERROR_RESTART_RETRIES) {
-                        /* Enable without persisting the setting as
-                         it doesnt change when IBluetooth
-                         service restarts */
-                        mEnable = true;
-                        addActiveLog(BluetoothProtoEnums.ENABLE_DISABLE_REASON_RESTARTED,
-                                mContext.getPackageName(), true);
-                        handleEnable(mQuietEnable);
-                    } else {
-                        Slog.e(TAG, "Reach maximum retry to restart Bluetooth!");
-                    }
-                    break;
-                }
-                case MESSAGE_TIMEOUT_BIND: {
-                    Slog.e(TAG, "MESSAGE_TIMEOUT_BIND");
-                    mBluetoothLock.writeLock().lock();
-                    mBinding = false;
-                    mBluetoothLock.writeLock().unlock();
-                    break;
-                }
-                case MESSAGE_TIMEOUT_UNBIND: {
-                    Slog.e(TAG, "MESSAGE_TIMEOUT_UNBIND");
-                    mBluetoothLock.writeLock().lock();
-                    mUnbinding = false;
-                    mBluetoothLock.writeLock().unlock();
-                    break;
-                }
-
-                case MESSAGE_USER_SWITCHED: {
-                    if (DBG) {
-                        Slog.d(TAG, "MESSAGE_USER_SWITCHED");
-                    }
-                    mHandler.removeMessages(MESSAGE_USER_SWITCHED);
-
-                    /* disable and enable BT when detect a user switch */
-                    if (mBluetooth != null && isEnabled()) {
-                        restartForReason(BluetoothProtoEnums.ENABLE_DISABLE_REASON_USER_SWITCH);
-                    } else if (mBinding || mBluetooth != null) {
-                        Message userMsg = mHandler.obtainMessage(MESSAGE_USER_SWITCHED);
-                        userMsg.arg2 = 1 + msg.arg2;
-                        // if user is switched when service is binding retry after a delay
-                        mHandler.sendMessageDelayed(userMsg, USER_SWITCHED_TIME_MS);
-                        if (DBG) {
-                            Slog.d(TAG, "Retry MESSAGE_USER_SWITCHED " + userMsg.arg2);
-                        }
-                    }
-                    break;
-                }
-                case MESSAGE_USER_UNLOCKED: {
-                    if (DBG) {
-                        Slog.d(TAG, "MESSAGE_USER_UNLOCKED");
-                    }
-                    mHandler.removeMessages(MESSAGE_USER_SWITCHED);
-
-                    if (mEnable && !mBinding && (mBluetooth == null)) {
-                        // We should be connected, but we gave up for some
-                        // reason; maybe the Bluetooth service wasn't encryption
-                        // aware, so try binding again.
-                        if (DBG) {
-                            Slog.d(TAG, "Enabled but not bound; retrying after unlock");
-                        }
-                        handleEnable(mQuietEnable);
-                    }
-                    break;
-                }
-                case MESSAGE_INIT_FLAGS_CHANGED: {
-                    if (DBG) {
-                        Slog.d(TAG, "MESSAGE_INIT_FLAGS_CHANGED");
-                    }
-                    mHandler.removeMessages(MESSAGE_INIT_FLAGS_CHANGED);
-                    if (mBluetoothModeChangeHelper.isMediaProfileConnected()) {
-                        Slog.i(TAG, "Delaying MESSAGE_INIT_FLAGS_CHANGED by "
-                                + DELAY_FOR_RETRY_INIT_FLAG_CHECK_MS
-                                + " ms due to existing connections");
-                        mHandler.sendEmptyMessageDelayed(
-                                MESSAGE_INIT_FLAGS_CHANGED,
-                                DELAY_FOR_RETRY_INIT_FLAG_CHECK_MS);
-                        break;
-                    }
-                    if (!isDeviceProvisioned()) {
-                        Slog.i(TAG, "Delaying MESSAGE_INIT_FLAGS_CHANGED by "
-                                + DELAY_FOR_RETRY_INIT_FLAG_CHECK_MS
-                                +  "ms because device is not provisioned");
-                        mHandler.sendEmptyMessageDelayed(
-                                MESSAGE_INIT_FLAGS_CHANGED,
-                                DELAY_FOR_RETRY_INIT_FLAG_CHECK_MS);
-                        break;
-                    }
-                    if (mBluetooth != null && isEnabled()) {
-                        Slog.i(TAG, "Restarting Bluetooth due to init flag change");
-                        restartForReason(
-                                BluetoothProtoEnums.ENABLE_DISABLE_REASON_INIT_FLAGS_CHANGED);
-                    }
-                    break;
-                }
-            }
-        }
-
-        @RequiresPermission(allOf = {
-                android.Manifest.permission.BLUETOOTH_CONNECT,
-                android.Manifest.permission.BLUETOOTH_PRIVILEGED
-        })
-        private void restartForReason(int reason) {
-            try {
-                mBluetoothLock.readLock().lock();
-                if (mBluetooth != null) {
-                    mBluetooth.unregisterCallback(mBluetoothCallback,
-                            mContext.getAttributionSource());
-                }
-            } catch (RemoteException re) {
-                Slog.e(TAG, "Unable to unregister", re);
-            } finally {
-                mBluetoothLock.readLock().unlock();
-            }
-
-            if (mState == BluetoothAdapter.STATE_TURNING_OFF) {
-                // MESSAGE_USER_SWITCHED happened right after MESSAGE_ENABLE
-                bluetoothStateChangeHandler(mState, BluetoothAdapter.STATE_OFF);
-                mState = BluetoothAdapter.STATE_OFF;
-            }
-            if (mState == BluetoothAdapter.STATE_OFF) {
-                bluetoothStateChangeHandler(mState, BluetoothAdapter.STATE_TURNING_ON);
-                mState = BluetoothAdapter.STATE_TURNING_ON;
-            }
-
-            waitForState(Set.of(BluetoothAdapter.STATE_ON));
-
-            if (mState == BluetoothAdapter.STATE_TURNING_ON) {
-                bluetoothStateChangeHandler(mState, BluetoothAdapter.STATE_ON);
-            }
-
-            unbindAllBluetoothProfileServices();
-            // disable
-            addActiveLog(reason, mContext.getPackageName(), false);
-            handleDisable();
-            // Pbap service need receive STATE_TURNING_OFF intent to close
-            bluetoothStateChangeHandler(BluetoothAdapter.STATE_ON,
-                    BluetoothAdapter.STATE_TURNING_OFF);
-
-            boolean didDisableTimeout =
-                    !waitForState(Set.of(BluetoothAdapter.STATE_OFF));
-
-            bluetoothStateChangeHandler(BluetoothAdapter.STATE_TURNING_OFF,
-                    BluetoothAdapter.STATE_OFF);
-            sendBluetoothServiceDownCallback();
-
-            try {
-                mBluetoothLock.writeLock().lock();
-                if (mBluetooth != null) {
-                    mBluetooth = null;
-                    // Unbind
-                    mContext.unbindService(mConnection);
-                }
-                mBluetoothGatt = null;
-            } finally {
-                mBluetoothLock.writeLock().unlock();
-            }
-
-            //
-            // If disabling Bluetooth times out, wait for an
-            // additional amount of time to ensure the process is
-            // shut down completely before attempting to restart.
-            //
-            if (didDisableTimeout) {
-                SystemClock.sleep(3000);
-            } else {
-                SystemClock.sleep(100);
-            }
-
-            mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE);
-            mState = BluetoothAdapter.STATE_OFF;
-            // enable
-            addActiveLog(reason, mContext.getPackageName(), true);
-            // mEnable flag could have been reset on disableBLE. Reenable it.
-            mEnable = true;
-            handleEnable(mQuietEnable);
-        }
-    }
-
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    private void handleEnable(boolean quietMode) {
-        mQuietEnable = quietMode;
-
-        try {
-            mBluetoothLock.writeLock().lock();
-            if ((mBluetooth == null) && (!mBinding)) {
-                Slog.d(TAG, "binding Bluetooth service");
-                //Start bind timeout and bind
-                Message timeoutMsg = mHandler.obtainMessage(MESSAGE_TIMEOUT_BIND);
-                mHandler.sendMessageDelayed(timeoutMsg, TIMEOUT_BIND_MS);
-                Intent i = new Intent(IBluetooth.class.getName());
-                if (!doBind(i, mConnection, Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
-                        UserHandle.CURRENT)) {
-                    mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
-                } else {
-                    mBinding = true;
-                }
-            } else if (mBluetooth != null) {
-                //Enable bluetooth
-                try {
-                    if (!mBluetooth.enable(mQuietEnable, mContext.getAttributionSource())) {
-                        Slog.e(TAG, "IBluetooth.enable() returned false");
-                    }
-                } catch (RemoteException e) {
-                    Slog.e(TAG, "Unable to call enable()", e);
-                }
-            }
-        } finally {
-            mBluetoothLock.writeLock().unlock();
-        }
-    }
-
-    boolean doBind(Intent intent, ServiceConnection conn, int flags, UserHandle user) {
-        ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
-        intent.setComponent(comp);
-        if (comp == null || !mContext.bindServiceAsUser(intent, conn, flags, user)) {
-            Slog.e(TAG, "Fail to bind to: " + intent);
-            return false;
-        }
-        return true;
-    }
-
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    private void handleDisable() {
-        try {
-            mBluetoothLock.readLock().lock();
-            if (mBluetooth != null) {
-                if (DBG) {
-                    Slog.d(TAG, "Sending off request.");
-                }
-                if (!mBluetooth.disable(mContext.getAttributionSource())) {
-                    Slog.e(TAG, "IBluetooth.disable() returned false");
-                }
-            }
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Unable to call disable()", e);
-        } finally {
-            mBluetoothLock.readLock().unlock();
-        }
-    }
-
-    private boolean checkIfCallerIsForegroundUser() {
-        int foregroundUser;
-        int callingUser = UserHandle.getCallingUserId();
-        int callingUid = Binder.getCallingUid();
-        final long callingIdentity = Binder.clearCallingIdentity();
-        UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
-        UserInfo ui = um.getProfileParent(callingUser);
-        int parentUser = (ui != null) ? ui.id : UserHandle.USER_NULL;
-        int callingAppId = UserHandle.getAppId(callingUid);
-        boolean valid = false;
-        try {
-            foregroundUser = ActivityManager.getCurrentUser();
-            valid = (callingUser == foregroundUser) || parentUser == foregroundUser
-                    || callingAppId == Process.NFC_UID || callingAppId == mSystemUiUid
-                    || callingAppId == Process.SHELL_UID;
-            if (DBG && !valid) {
-                Slog.d(TAG, "checkIfCallerIsForegroundUser: valid=" + valid + " callingUser="
-                        + callingUser + " parentUser=" + parentUser + " foregroundUser="
-                        + foregroundUser);
-            }
-        } finally {
-            Binder.restoreCallingIdentity(callingIdentity);
-        }
-        return valid;
-    }
-
-    private void sendBleStateChanged(int prevState, int newState) {
-        if (DBG) {
-            Slog.d(TAG,
-                    "Sending BLE State Change: " + BluetoothAdapter.nameForState(prevState) + " > "
-                            + BluetoothAdapter.nameForState(newState));
-        }
-        // Send broadcast message to everyone else
-        Intent intent = new Intent(BluetoothAdapter.ACTION_BLE_STATE_CHANGED);
-        intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, prevState);
-        intent.putExtra(BluetoothAdapter.EXTRA_STATE, newState);
-        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
-        mContext.sendBroadcastAsUser(intent, UserHandle.ALL, null, getTempAllowlistBroadcastOptions());
-    }
-
-    private boolean isBleState(int state) {
-        switch (state) {
-            case BluetoothAdapter.STATE_BLE_ON:
-            case BluetoothAdapter.STATE_BLE_TURNING_ON:
-            case BluetoothAdapter.STATE_BLE_TURNING_OFF:
-                return true;
-        }
-        return false;
-    }
-
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    private void bluetoothStateChangeHandler(int prevState, int newState) {
-        boolean isStandardBroadcast = true;
-        if (prevState == newState) { // No change. Nothing to do.
-            return;
-        }
-        // Notify all proxy objects first of adapter state change
-        if (newState == BluetoothAdapter.STATE_BLE_ON || newState == BluetoothAdapter.STATE_OFF) {
-            boolean intermediate_off = (prevState == BluetoothAdapter.STATE_TURNING_OFF
-                    && newState == BluetoothAdapter.STATE_BLE_ON);
-
-            if (newState == BluetoothAdapter.STATE_OFF) {
-                // If Bluetooth is off, send service down event to proxy objects, and unbind
-                if (DBG) {
-                    Slog.d(TAG, "Bluetooth is complete send Service Down");
-                }
-                sendBluetoothServiceDownCallback();
-                unbindAndFinish();
-                sendBleStateChanged(prevState, newState);
-
-                /* Currently, the OFF intent is broadcasted externally only when we transition
-                 * from TURNING_OFF to BLE_ON state. So if the previous state is a BLE state,
-                 * we are guaranteed that the OFF intent has been broadcasted earlier and we
-                 * can safely skip it.
-                 * Conversely, if the previous state is not a BLE state, it indicates that some
-                 * sort of crash has occurred, moving us directly to STATE_OFF without ever
-                 * passing through BLE_ON. We should broadcast the OFF intent in this case. */
-                isStandardBroadcast = !isBleState(prevState);
-
-            } else if (!intermediate_off) {
-                // connect to GattService
-                if (DBG) {
-                    Slog.d(TAG, "Bluetooth is in LE only mode");
-                }
-                if (mBluetoothGatt != null || !mContext.getPackageManager()
-                            .hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
-                    continueFromBleOnState();
-                } else {
-                    if (DBG) {
-                        Slog.d(TAG, "Binding Bluetooth GATT service");
-                    }
-                    Intent i = new Intent(IBluetoothGatt.class.getName());
-                    doBind(i, mConnection, Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
-                            UserHandle.CURRENT);
-                }
-                sendBleStateChanged(prevState, newState);
-                //Don't broadcase this as std intent
-                isStandardBroadcast = false;
-
-            } else if (intermediate_off) {
-                if (DBG) {
-                    Slog.d(TAG, "Intermediate off, back to LE only mode");
-                }
-                // For LE only mode, broadcast as is
-                sendBleStateChanged(prevState, newState);
-                sendBluetoothStateCallback(false); // BT is OFF for general users
-                // Broadcast as STATE_OFF
-                newState = BluetoothAdapter.STATE_OFF;
-                sendBrEdrDownCallback(mContext.getAttributionSource());
-            }
-        } else if (newState == BluetoothAdapter.STATE_ON) {
-            boolean isUp = (newState == BluetoothAdapter.STATE_ON);
-            sendBluetoothStateCallback(isUp);
-            sendBleStateChanged(prevState, newState);
-
-        } else if (newState == BluetoothAdapter.STATE_BLE_TURNING_ON
-                || newState == BluetoothAdapter.STATE_BLE_TURNING_OFF) {
-            sendBleStateChanged(prevState, newState);
-            isStandardBroadcast = false;
-
-        } else if (newState == BluetoothAdapter.STATE_TURNING_ON
-                || newState == BluetoothAdapter.STATE_TURNING_OFF) {
-            sendBleStateChanged(prevState, newState);
-        }
-
-        if (isStandardBroadcast) {
-            if (prevState == BluetoothAdapter.STATE_BLE_ON) {
-                // Show prevState of BLE_ON as OFF to standard users
-                prevState = BluetoothAdapter.STATE_OFF;
-            }
-            if (DBG) {
-                Slog.d(TAG,
-                        "Sending State Change: " + BluetoothAdapter.nameForState(prevState) + " > "
-                                + BluetoothAdapter.nameForState(newState));
-            }
-            Intent intent = new Intent(BluetoothAdapter.ACTION_STATE_CHANGED);
-            intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, prevState);
-            intent.putExtra(BluetoothAdapter.EXTRA_STATE, newState);
-            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
-            mContext.sendBroadcastAsUser(intent, UserHandle.ALL, null,
-                    getTempAllowlistBroadcastOptions());
-        }
-    }
-
-    private boolean waitForState(Set<Integer> states) {
-        int i = 0;
-        while (i < 10) {
-            try {
-                mBluetoothLock.readLock().lock();
-                if (mBluetooth == null) {
-                    break;
-                }
-                if (states.contains(mBluetooth.getState())) {
-                    return true;
-                }
-            } catch (RemoteException e) {
-                Slog.e(TAG, "getState()", e);
-                break;
-            } finally {
-                mBluetoothLock.readLock().unlock();
-            }
-            SystemClock.sleep(300);
-            i++;
-        }
-        Slog.e(TAG, "waitForState " + states + " time out");
-        return false;
-    }
-
-    private void sendDisableMsg(int reason, String packageName) {
-        mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_DISABLE));
-        addActiveLog(reason, packageName, false);
-    }
-
-    private void sendEnableMsg(boolean quietMode, int reason, String packageName) {
-        sendEnableMsg(quietMode, reason, packageName, false);
-    }
-
-    private void sendEnableMsg(boolean quietMode, int reason, String packageName, boolean isBle) {
-        mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_ENABLE, quietMode ? 1 : 0,
-                  isBle ? 1 : 0));
-        addActiveLog(reason, packageName, true);
-        mLastEnabledTime = SystemClock.elapsedRealtime();
-    }
-
-    private void addActiveLog(int reason, String packageName, boolean enable) {
-        synchronized (mActiveLogs) {
-            if (mActiveLogs.size() > ACTIVE_LOG_MAX_SIZE) {
-                mActiveLogs.remove();
-            }
-            mActiveLogs.add(
-                    new ActiveLog(reason, packageName, enable, System.currentTimeMillis()));
-        }
-
-        int state = enable ? FrameworkStatsLog.BLUETOOTH_ENABLED_STATE_CHANGED__STATE__ENABLED :
-                             FrameworkStatsLog.BLUETOOTH_ENABLED_STATE_CHANGED__STATE__DISABLED;
-        FrameworkStatsLog.write_non_chained(FrameworkStatsLog.BLUETOOTH_ENABLED_STATE_CHANGED,
-                Binder.getCallingUid(), null, state, reason, packageName);
-    }
-
-    private void addCrashLog() {
-        synchronized (mCrashTimestamps) {
-            if (mCrashTimestamps.size() == CRASH_LOG_MAX_SIZE) {
-                mCrashTimestamps.removeFirst();
-            }
-            mCrashTimestamps.add(System.currentTimeMillis());
-            mCrashes++;
-        }
-    }
-
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    private void recoverBluetoothServiceFromError(boolean clearBle) {
-        Slog.e(TAG, "recoverBluetoothServiceFromError");
-        try {
-            mBluetoothLock.readLock().lock();
-            if (mBluetooth != null) {
-                //Unregister callback object
-                mBluetooth.unregisterCallback(mBluetoothCallback, mContext.getAttributionSource());
-            }
-        } catch (RemoteException re) {
-            Slog.e(TAG, "Unable to unregister", re);
-        } finally {
-            mBluetoothLock.readLock().unlock();
-        }
-
-        SystemClock.sleep(500);
-
-        // disable
-        addActiveLog(BluetoothProtoEnums.ENABLE_DISABLE_REASON_START_ERROR,
-                mContext.getPackageName(), false);
-        handleDisable();
-
-        waitForState(Set.of(BluetoothAdapter.STATE_OFF));
-
-        sendBluetoothServiceDownCallback();
-
-        try {
-            mBluetoothLock.writeLock().lock();
-            if (mBluetooth != null) {
-                mBluetooth = null;
-                // Unbind
-                mContext.unbindService(mConnection);
-            }
-            mBluetoothGatt = null;
-        } finally {
-            mBluetoothLock.writeLock().unlock();
-        }
-
-        mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE);
-        mState = BluetoothAdapter.STATE_OFF;
-
-        if (clearBle) {
-            clearBleApps();
-        }
-
-        mEnable = false;
-
-        // Send a Bluetooth Restart message to reenable bluetooth
-        Message restartMsg = mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE);
-        mHandler.sendMessageDelayed(restartMsg, ERROR_RESTART_TIME_MS);
-    }
-
-    private boolean isBluetoothDisallowed() {
-        final long callingIdentity = Binder.clearCallingIdentity();
-        try {
-            return mContext.getSystemService(UserManager.class)
-                    .hasUserRestriction(UserManager.DISALLOW_BLUETOOTH, UserHandle.SYSTEM);
-        } finally {
-            Binder.restoreCallingIdentity(callingIdentity);
-        }
-    }
-
-    /**
-     * Disables BluetoothOppLauncherActivity component, so the Bluetooth sharing option is not
-     * offered to the user if Bluetooth or sharing is disallowed. Puts the component to its default
-     * state if Bluetooth is not disallowed.
-     *
-     * @param userId user to disable bluetooth sharing for.
-     * @param bluetoothSharingDisallowed whether bluetooth sharing is disallowed.
-     */
-    private void updateOppLauncherComponentState(int userId, boolean bluetoothSharingDisallowed) {
-        final ComponentName oppLauncherComponent = new ComponentName("com.android.bluetooth",
-                "com.android.bluetooth.opp.BluetoothOppLauncherActivity");
-        final int newState =
-                bluetoothSharingDisallowed ? PackageManager.COMPONENT_ENABLED_STATE_DISABLED
-                        : PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
-        try {
-            final IPackageManager imp = AppGlobals.getPackageManager();
-            imp.setComponentEnabledSetting(oppLauncherComponent, newState,
-                    PackageManager.DONT_KILL_APP, userId);
-        } catch (Exception e) {
-            // The component was not found, do nothing.
-        }
-    }
-
-    private int getServiceRestartMs() {
-        return (mErrorRecoveryRetryCounter + 1) * SERVICE_RESTART_TIME_MS;
-    }
-
-    @Override
-    public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
-        if (!DumpUtils.checkDumpPermission(mContext, TAG, writer)) {
-            return;
-        }
-        if ((args.length > 0) && args[0].startsWith("--proto")) {
-            dumpProto(fd);
-            return;
-        }
-        String errorMsg = null;
-
-        writer.println("Bluetooth Status");
-        writer.println("  enabled: " + isEnabled());
-        writer.println("  state: " + BluetoothAdapter.nameForState(mState));
-        writer.println("  address: " + mAddress);
-        writer.println("  name: " + mName);
-        if (mEnable) {
-            long onDuration = SystemClock.elapsedRealtime() - mLastEnabledTime;
-            String onDurationString = String.format(Locale.US, "%02d:%02d:%02d.%03d",
-                    (int) (onDuration / (1000 * 60 * 60)),
-                    (int) ((onDuration / (1000 * 60)) % 60), (int) ((onDuration / 1000) % 60),
-                    (int) (onDuration % 1000));
-            writer.println("  time since enabled: " + onDurationString);
-        }
-
-        if (mActiveLogs.size() == 0) {
-            writer.println("\nBluetooth never enabled!");
-        } else {
-            writer.println("\nEnable log:");
-            for (ActiveLog log : mActiveLogs) {
-                writer.println("  " + log);
-            }
-        }
-
-        writer.println(
-                "\nBluetooth crashed " + mCrashes + " time" + (mCrashes == 1 ? "" : "s"));
-        if (mCrashes == CRASH_LOG_MAX_SIZE) {
-            writer.println("(last " + CRASH_LOG_MAX_SIZE + ")");
-        }
-        for (Long time : mCrashTimestamps) {
-            writer.println("  " + timeToLog(time));
-        }
-
-        writer.println("\n" + mBleApps.size() + " BLE app" + (mBleApps.size() == 1 ? "" : "s")
-                + " registered");
-        for (ClientDeathRecipient app : mBleApps.values()) {
-            writer.println("  " + app.getPackageName());
-        }
-
-        writer.println("\nBluetoothManagerService:");
-        writer.println("  mEnable:" + mEnable);
-        writer.println("  mQuietEnable:" + mQuietEnable);
-        writer.println("  mEnableExternal:" + mEnableExternal);
-        writer.println("  mQuietEnableExternal:" + mQuietEnableExternal);
-
-        writer.println("");
-        writer.flush();
-        if (args.length == 0) {
-            // Add arg to produce output
-            args = new String[1];
-            args[0] = "--print";
-        }
-
-        if (mBluetoothBinder == null) {
-            errorMsg = "Bluetooth Service not connected";
-        } else {
-            try {
-                mBluetoothBinder.dump(fd, args);
-            } catch (RemoteException re) {
-                errorMsg = "RemoteException while dumping Bluetooth Service";
-            }
-        }
-        if (errorMsg != null) {
-            writer.println(errorMsg);
-        }
-    }
-
-    private void dumpProto(FileDescriptor fd) {
-        final ProtoOutputStream proto = new ProtoOutputStream(fd);
-        proto.write(BluetoothManagerServiceDumpProto.ENABLED, isEnabled());
-        proto.write(BluetoothManagerServiceDumpProto.STATE, mState);
-        proto.write(BluetoothManagerServiceDumpProto.STATE_NAME,
-                BluetoothAdapter.nameForState(mState));
-        proto.write(BluetoothManagerServiceDumpProto.ADDRESS, mAddress);
-        proto.write(BluetoothManagerServiceDumpProto.NAME, mName);
-        if (mEnable) {
-            proto.write(BluetoothManagerServiceDumpProto.LAST_ENABLED_TIME_MS, mLastEnabledTime);
-        }
-        proto.write(BluetoothManagerServiceDumpProto.CURR_TIMESTAMP_MS,
-                SystemClock.elapsedRealtime());
-        for (ActiveLog log : mActiveLogs) {
-            long token = proto.start(BluetoothManagerServiceDumpProto.ACTIVE_LOGS);
-            log.dump(proto);
-            proto.end(token);
-        }
-        proto.write(BluetoothManagerServiceDumpProto.NUM_CRASHES, mCrashes);
-        proto.write(BluetoothManagerServiceDumpProto.CRASH_LOG_MAXED,
-                mCrashes == CRASH_LOG_MAX_SIZE);
-        for (Long time : mCrashTimestamps) {
-            proto.write(BluetoothManagerServiceDumpProto.CRASH_TIMESTAMPS_MS, time);
-        }
-        proto.write(BluetoothManagerServiceDumpProto.NUM_BLE_APPS, mBleApps.size());
-        for (ClientDeathRecipient app : mBleApps.values()) {
-            proto.write(BluetoothManagerServiceDumpProto.BLE_APP_PACKAGE_NAMES,
-                    app.getPackageName());
-        }
-        proto.flush();
-    }
-
-    private static String getEnableDisableReasonString(int reason) {
-        switch (reason) {
-            case BluetoothProtoEnums.ENABLE_DISABLE_REASON_APPLICATION_REQUEST:
-                return "APPLICATION_REQUEST";
-            case BluetoothProtoEnums.ENABLE_DISABLE_REASON_AIRPLANE_MODE:
-                return "AIRPLANE_MODE";
-            case BluetoothProtoEnums.ENABLE_DISABLE_REASON_DISALLOWED:
-                return "DISALLOWED";
-            case BluetoothProtoEnums.ENABLE_DISABLE_REASON_RESTARTED:
-                return "RESTARTED";
-            case BluetoothProtoEnums.ENABLE_DISABLE_REASON_START_ERROR:
-                return "START_ERROR";
-            case BluetoothProtoEnums.ENABLE_DISABLE_REASON_SYSTEM_BOOT:
-                return "SYSTEM_BOOT";
-            case BluetoothProtoEnums.ENABLE_DISABLE_REASON_CRASH:
-                return "CRASH";
-            case BluetoothProtoEnums.ENABLE_DISABLE_REASON_USER_SWITCH:
-                return "USER_SWITCH";
-            case BluetoothProtoEnums.ENABLE_DISABLE_REASON_RESTORE_USER_SETTING:
-                return "RESTORE_USER_SETTING";
-            case BluetoothProtoEnums.ENABLE_DISABLE_REASON_FACTORY_RESET:
-                return "FACTORY_RESET";
-            case BluetoothProtoEnums.ENABLE_DISABLE_REASON_INIT_FLAGS_CHANGED:
-                return "INIT_FLAGS_CHANGED";
-            case BluetoothProtoEnums.ENABLE_DISABLE_REASON_UNSPECIFIED:
-            default: return "UNKNOWN[" + reason + "]";
-        }
-    }
-
-    @SuppressLint("AndroidFrameworkRequiresPermission")
-    private static boolean checkPermissionForDataDelivery(Context context, String permission,
-            AttributionSource attributionSource, String message) {
-        final int result = PermissionChecker.checkPermissionForDataDeliveryFromDataSource(
-                context, permission, PID_UNKNOWN,
-                new AttributionSource(context.getAttributionSource(), attributionSource), message);
-        if (result == PERMISSION_GRANTED) {
-            return true;
-        }
-
-        final String msg = "Need " + permission + " permission for " + attributionSource + ": "
-                + message;
-        if (result == PERMISSION_HARD_DENIED) {
-            throw new SecurityException(msg);
-        } else {
-            Log.w(TAG, msg);
-            return false;
-        }
-    }
-
-    /**
-     * Returns true if the BLUETOOTH_CONNECT permission is granted for the calling app. Returns
-     * false if the result is a soft denial. Throws SecurityException if the result is a hard
-     * denial.
-     *
-     * <p>Should be used in situations where the app op should not be noted.
-     */
-    @SuppressLint("AndroidFrameworkRequiresPermission")
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    public static boolean checkConnectPermissionForDataDelivery(
-            Context context, AttributionSource attributionSource, String message) {
-        return checkPermissionForDataDelivery(context, BLUETOOTH_CONNECT,
-                attributionSource, message);
-    }
-
-    static @NonNull Bundle getTempAllowlistBroadcastOptions() {
-        final long duration = 10_000;
-        final BroadcastOptions bOptions = BroadcastOptions.makeBasic();
-        bOptions.setTemporaryAppAllowlist(duration,
-                TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED,
-                PowerExemptionManager.REASON_BLUETOOTH_BROADCAST, "");
-        return bOptions.toBundle();
-    }
-}
diff --git a/services/core/java/com/android/server/BluetoothModeChangeHelper.java b/services/core/java/com/android/server/BluetoothModeChangeHelper.java
deleted file mode 100644
index e5854c9..0000000
--- a/services/core/java/com/android/server/BluetoothModeChangeHelper.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * 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 com.android.server;
-
-import android.annotation.RequiresPermission;
-import android.bluetooth.BluetoothA2dp;
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothHearingAid;
-import android.bluetooth.BluetoothLeAudio;
-import android.bluetooth.BluetoothProfile;
-import android.bluetooth.BluetoothProfile.ServiceListener;
-import android.content.Context;
-import android.content.res.Resources;
-import android.provider.Settings;
-import android.widget.Toast;
-
-import com.android.internal.R;
-import com.android.internal.annotations.VisibleForTesting;
-
-/**
- * Helper class that handles callout and callback methods without
- * complex logic.
- */
-public class BluetoothModeChangeHelper {
-    private volatile BluetoothA2dp mA2dp;
-    private volatile BluetoothHearingAid mHearingAid;
-    private volatile BluetoothLeAudio mLeAudio;
-    private final BluetoothAdapter mAdapter;
-    private final Context mContext;
-
-    BluetoothModeChangeHelper(Context context) {
-        mAdapter = BluetoothAdapter.getDefaultAdapter();
-        mContext = context;
-
-        mAdapter.getProfileProxy(mContext, mProfileServiceListener, BluetoothProfile.A2DP);
-        mAdapter.getProfileProxy(mContext, mProfileServiceListener,
-                BluetoothProfile.HEARING_AID);
-        mAdapter.getProfileProxy(mContext, mProfileServiceListener, BluetoothProfile.LE_AUDIO);
-    }
-
-    private final ServiceListener mProfileServiceListener = new ServiceListener() {
-        @Override
-        public void onServiceConnected(int profile, BluetoothProfile proxy) {
-            // Setup Bluetooth profile proxies
-            switch (profile) {
-                case BluetoothProfile.A2DP:
-                    mA2dp = (BluetoothA2dp) proxy;
-                    break;
-                case BluetoothProfile.HEARING_AID:
-                    mHearingAid = (BluetoothHearingAid) proxy;
-                    break;
-                case BluetoothProfile.LE_AUDIO:
-                    mLeAudio = (BluetoothLeAudio) proxy;
-                    break;
-                default:
-                    break;
-            }
-        }
-
-        @Override
-        public void onServiceDisconnected(int profile) {
-            // Clear Bluetooth profile proxies
-            switch (profile) {
-                case BluetoothProfile.A2DP:
-                    mA2dp = null;
-                    break;
-                case BluetoothProfile.HEARING_AID:
-                    mHearingAid = null;
-                    break;
-                case BluetoothProfile.LE_AUDIO:
-                    mLeAudio = null;
-                    break;
-                default:
-                    break;
-            }
-        }
-    };
-
-    @VisibleForTesting
-    public boolean isMediaProfileConnected() {
-        return isA2dpConnected() || isHearingAidConnected() || isLeAudioConnected();
-    }
-
-    @VisibleForTesting
-    public boolean isBluetoothOn() {
-        final BluetoothAdapter adapter = mAdapter;
-        if (adapter == null) {
-            return false;
-        }
-        return adapter.getLeState() == BluetoothAdapter.STATE_ON;
-    }
-
-    @VisibleForTesting
-    public boolean isAirplaneModeOn() {
-        return Settings.Global.getInt(mContext.getContentResolver(),
-                Settings.Global.AIRPLANE_MODE_ON, 0) == 1;
-    }
-
-    @VisibleForTesting
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)
-    public void onAirplaneModeChanged(BluetoothManagerService managerService) {
-        managerService.onAirplaneModeChanged();
-    }
-
-    @VisibleForTesting
-    public int getSettingsInt(String name) {
-        return Settings.Global.getInt(mContext.getContentResolver(),
-                name, 0);
-    }
-
-    @VisibleForTesting
-    public void setSettingsInt(String name, int value) {
-        Settings.Global.putInt(mContext.getContentResolver(),
-                name, value);
-    }
-
-    @VisibleForTesting
-    public void showToastMessage() {
-        Resources r = mContext.getResources();
-        final CharSequence text = r.getString(
-                R.string.bluetooth_airplane_mode_toast, 0);
-        Toast.makeText(mContext, text, Toast.LENGTH_LONG).show();
-    }
-
-    private boolean isA2dpConnected() {
-        final BluetoothA2dp a2dp = mA2dp;
-        if (a2dp == null) {
-            return false;
-        }
-        return a2dp.getConnectedDevices().size() > 0;
-    }
-
-    private boolean isHearingAidConnected() {
-        final BluetoothHearingAid hearingAid = mHearingAid;
-        if (hearingAid == null) {
-            return false;
-        }
-        return hearingAid.getConnectedDevices().size() > 0;
-    }
-
-    private boolean isLeAudioConnected() {
-        final BluetoothLeAudio leAudio = mLeAudio;
-        if (leAudio == null) {
-            return false;
-        }
-        return leAudio.getConnectedDevices().size() > 0;
-    }
-}
diff --git a/services/core/java/com/android/server/BluetoothService.java b/services/core/java/com/android/server/BluetoothService.java
deleted file mode 100644
index 1a1eecd..0000000
--- a/services/core/java/com/android/server/BluetoothService.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.bluetooth.BluetoothAdapter;
-import android.content.Context;
-import android.os.UserManager;
-
-import com.android.server.SystemService.TargetUser;
-
-class BluetoothService extends SystemService {
-    private BluetoothManagerService mBluetoothManagerService;
-    private boolean mInitialized = false;
-
-    public BluetoothService(Context context) {
-        super(context);
-        mBluetoothManagerService = new BluetoothManagerService(context);
-    }
-
-    private void initialize() {
-        if (!mInitialized) {
-            mBluetoothManagerService.handleOnBootPhase();
-            mInitialized = true;
-        }
-    }
-
-    @Override
-    public void onStart() {
-    }
-
-    @Override
-    public void onBootPhase(int phase) {
-        if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
-            publishBinderService(BluetoothAdapter.BLUETOOTH_MANAGER_SERVICE,
-                    mBluetoothManagerService);
-        } else if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY &&
-                !UserManager.isHeadlessSystemUserMode()) {
-            initialize();
-        }
-    }
-
-    @Override
-    public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) {
-        if (!mInitialized) {
-            initialize();
-        } else {
-            mBluetoothManagerService.handleOnSwitchUser(to.getUserIdentifier());
-        }
-    }
-
-    @Override
-    public void onUserUnlocking(@NonNull TargetUser user) {
-        mBluetoothManagerService.handleOnUnlockUser(user.getUserIdentifier());
-    }
-}
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index a2c2dbd..8551d88 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -20,12 +20,12 @@
 import static android.Manifest.permission.NETWORK_SETTINGS;
 import static android.Manifest.permission.OBSERVE_NETWORK_POLICY;
 import static android.Manifest.permission.SHUTDOWN;
+import static android.net.ConnectivityManager.FIREWALL_CHAIN_DOZABLE;
+import static android.net.ConnectivityManager.FIREWALL_CHAIN_POWERSAVE;
+import static android.net.ConnectivityManager.FIREWALL_CHAIN_RESTRICTED;
+import static android.net.ConnectivityManager.FIREWALL_CHAIN_STANDBY;
 import static android.net.INetd.FIREWALL_ALLOWLIST;
-import static android.net.INetd.FIREWALL_CHAIN_DOZABLE;
 import static android.net.INetd.FIREWALL_CHAIN_NONE;
-import static android.net.INetd.FIREWALL_CHAIN_POWERSAVE;
-import static android.net.INetd.FIREWALL_CHAIN_RESTRICTED;
-import static android.net.INetd.FIREWALL_CHAIN_STANDBY;
 import static android.net.INetd.FIREWALL_DENYLIST;
 import static android.net.INetd.FIREWALL_RULE_ALLOW;
 import static android.net.INetd.FIREWALL_RULE_DENY;
@@ -39,9 +39,12 @@
 import static android.net.NetworkStats.TAG_NONE;
 import static android.net.TrafficStats.UID_TETHERING;
 
+import static com.android.net.module.util.NetworkStatsUtils.LIMIT_GLOBAL_ALERT;
+
 import android.annotation.NonNull;
 import android.app.ActivityManager;
 import android.content.Context;
+import android.net.ConnectivityManager;
 import android.net.INetd;
 import android.net.INetdUnsolicitedEventListener;
 import android.net.INetworkManagementEventObserver;
@@ -133,12 +136,6 @@
 
     private static final int MAX_UID_RANGES_PER_COMMAND = 10;
 
-    /**
-     * Name representing {@link #setGlobalAlert(long)} limit when delivered to
-     * {@link INetworkManagementEventObserver#limitReached(String, String)}.
-     */
-    public static final String LIMIT_GLOBAL_ALERT = "globalAlert";
-
     static final int DAEMON_MSG_MOBILE_CONN_REAL_TIME_INFO = 1;
 
     static final boolean MODIFY_OPERATION_ADD = true;
@@ -1162,19 +1159,12 @@
             }
 
             Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "inetd bandwidth");
+            final ConnectivityManager cm = mContext.getSystemService(ConnectivityManager.class);
             try {
                 if (allowlist) {
-                    if (enable) {
-                        mNetdService.bandwidthAddNiceApp(uid);
-                    } else {
-                        mNetdService.bandwidthRemoveNiceApp(uid);
-                    }
+                    cm.updateMeteredNetworkAllowList(uid, enable);
                 } else {
-                    if (enable) {
-                        mNetdService.bandwidthAddNaughtyApp(uid);
-                    } else {
-                        mNetdService.bandwidthRemoveNaughtyApp(uid);
-                    }
+                    cm.updateMeteredNetworkDenyList(uid, enable);
                 }
                 synchronized (mRulesLock) {
                     if (enable) {
@@ -1183,7 +1173,7 @@
                         quotaList.delete(uid);
                     }
                 }
-            } catch (RemoteException | ServiceSpecificException e) {
+            } catch (RuntimeException e) {
                 throw new IllegalStateException(e);
             } finally {
                 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
@@ -1468,9 +1458,10 @@
                 throw new IllegalArgumentException("Bad child chain: " + chainName);
             }
 
+            final ConnectivityManager cm = mContext.getSystemService(ConnectivityManager.class);
             try {
-                mNetdService.firewallEnableChildChain(chain, enable);
-            } catch (RemoteException | ServiceSpecificException e) {
+                cm.setFirewallChainEnabled(chain, enable);
+            } catch (RuntimeException e) {
                 throw new IllegalStateException(e);
             }
 
@@ -1542,25 +1533,10 @@
                     updateFirewallUidRuleLocked(chain, uid, FIREWALL_RULE_DEFAULT);
                 }
             }
+            final ConnectivityManager cm = mContext.getSystemService(ConnectivityManager.class);
             try {
-                switch (chain) {
-                    case FIREWALL_CHAIN_DOZABLE:
-                        mNetdService.firewallReplaceUidChain("fw_dozable", true, uids);
-                        break;
-                    case FIREWALL_CHAIN_STANDBY:
-                        mNetdService.firewallReplaceUidChain("fw_standby", false, uids);
-                        break;
-                    case FIREWALL_CHAIN_POWERSAVE:
-                        mNetdService.firewallReplaceUidChain("fw_powersave", true, uids);
-                        break;
-                    case FIREWALL_CHAIN_RESTRICTED:
-                        mNetdService.firewallReplaceUidChain("fw_restricted", true, uids);
-                        break;
-                    case FIREWALL_CHAIN_NONE:
-                    default:
-                        Slog.d(TAG, "setFirewallUidRules() called on invalid chain: " + chain);
-                }
-            } catch (RemoteException e) {
+                cm.replaceFirewallChain(chain, uids);
+            } catch (RuntimeException e) {
                 Slog.w(TAG, "Error flushing firewall chain " + chain, e);
             }
         }
@@ -1576,10 +1552,10 @@
 
     private void setFirewallUidRuleLocked(int chain, int uid, int rule) {
         if (updateFirewallUidRuleLocked(chain, uid, rule)) {
-            final int ruleType = getFirewallRuleType(chain, rule);
+            final ConnectivityManager cm = mContext.getSystemService(ConnectivityManager.class);
             try {
-                mNetdService.firewallSetUidRule(chain, uid, ruleType);
-            } catch (RemoteException | ServiceSpecificException e) {
+                cm.updateFirewallRule(chain, uid, isFirewallRuleAllow(chain, rule));
+            } catch (RuntimeException e) {
                 throw new IllegalStateException(e);
             }
         }
@@ -1649,12 +1625,12 @@
         }
     }
 
-    private int getFirewallRuleType(int chain, int rule) {
+    // There are only two type of firewall rule: FIREWALL_RULE_ALLOW or FIREWALL_RULE_DENY.
+    private boolean isFirewallRuleAllow(int chain, int rule) {
         if (rule == NetworkPolicyManager.FIREWALL_RULE_DEFAULT) {
-            return getFirewallType(chain) == FIREWALL_ALLOWLIST
-                    ? INetd.FIREWALL_RULE_DENY : INetd.FIREWALL_RULE_ALLOW;
+            return getFirewallType(chain) == FIREWALL_DENYLIST;
         }
-        return rule;
+        return rule == INetd.FIREWALL_RULE_ALLOW;
     }
 
     private void enforceSystemUid() {
diff --git a/services/core/java/com/android/server/SerialService.java b/services/core/java/com/android/server/SerialService.java
index 1abe458..e915fa1 100644
--- a/services/core/java/com/android/server/SerialService.java
+++ b/services/core/java/com/android/server/SerialService.java
@@ -16,6 +16,7 @@
 
 package com.android.server;
 
+import android.annotation.EnforcePermission;
 import android.content.Context;
 import android.hardware.ISerialManager;
 import android.os.ParcelFileDescriptor;
@@ -34,9 +35,8 @@
                 com.android.internal.R.array.config_serialPorts);
     }
 
+    @EnforcePermission(android.Manifest.permission.SERIAL_PORT)
     public String[] getSerialPorts() {
-        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.SERIAL_PORT, null);
-
         ArrayList<String> ports = new ArrayList<String>();
         for (int i = 0; i < mSerialPorts.length; i++) {
             String path = mSerialPorts[i];
@@ -49,8 +49,8 @@
         return result;
     }
 
+    @EnforcePermission(android.Manifest.permission.SERIAL_PORT)
     public ParcelFileDescriptor openSerialPort(String path) {
-        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.SERIAL_PORT, null);
         for (int i = 0; i < mSerialPorts.length; i++) {
             if (mSerialPorts[i].equals(path)) {
                 return native_open(path);
diff --git a/services/core/java/com/android/server/SmartStorageMaintIdler.java b/services/core/java/com/android/server/SmartStorageMaintIdler.java
new file mode 100644
index 0000000..2dff72f
--- /dev/null
+++ b/services/core/java/com/android/server/SmartStorageMaintIdler.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server;
+
+import android.app.job.JobInfo;
+import android.app.job.JobParameters;
+import android.app.job.JobScheduler;
+import android.app.job.JobService;
+import android.content.ComponentName;
+import android.content.Context;
+import android.util.Slog;
+
+import java.util.concurrent.TimeUnit;
+
+public class SmartStorageMaintIdler extends JobService {
+    private static final String TAG = "SmartStorageMaintIdler";
+
+    private static final ComponentName SMART_STORAGE_MAINT_SERVICE =
+            new ComponentName("android", SmartStorageMaintIdler.class.getName());
+
+    private static final int SMART_MAINT_JOB_ID = 2808;
+
+    private boolean mStarted;
+    private JobParameters mJobParams;
+    private final Runnable mFinishCallback = new Runnable() {
+        @Override
+        public void run() {
+            Slog.i(TAG, "Got smart storage maintenance service completion callback");
+            if (mStarted) {
+                jobFinished(mJobParams, false);
+                mStarted = false;
+            }
+            // ... and try again in a next period
+            scheduleSmartIdlePass(SmartStorageMaintIdler.this,
+                StorageManagerService.SMART_IDLE_MAINT_PERIOD);
+        }
+    };
+
+    @Override
+    public boolean onStartJob(JobParameters params) {
+        mJobParams = params;
+        StorageManagerService ms = StorageManagerService.sSelf;
+        if (ms != null) {
+            mStarted = true;
+            ms.runSmartIdleMaint(mFinishCallback);
+        }
+        return ms != null;
+    }
+
+    @Override
+    public boolean onStopJob(JobParameters params) {
+        mStarted = false;
+        return false;
+    }
+
+    /**
+     * Schedule the smart storage idle maintenance job
+     */
+    public static void scheduleSmartIdlePass(Context context, int nHours) {
+        StorageManagerService ms = StorageManagerService.sSelf;
+        if ((ms == null) || ms.isPassedLifetimeThresh()) {
+            return;
+        }
+
+        JobScheduler tm = context.getSystemService(JobScheduler.class);
+
+        long nextScheduleTime = TimeUnit.HOURS.toMillis(nHours);
+
+        JobInfo.Builder builder = new JobInfo.Builder(SMART_MAINT_JOB_ID,
+            SMART_STORAGE_MAINT_SERVICE);
+
+        builder.setMinimumLatency(nextScheduleTime);
+        tm.schedule(builder.build());
+    }
+}
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 2d6170b..9546496 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -79,6 +79,7 @@
 import android.content.res.ObbInfo;
 import android.database.ContentObserver;
 import android.net.Uri;
+import android.os.BatteryManager;
 import android.os.Binder;
 import android.os.DropBoxManager;
 import android.os.Environment;
@@ -158,6 +159,8 @@
 import com.android.server.wm.ActivityTaskManagerInternal;
 import com.android.server.wm.ActivityTaskManagerInternal.ScreenObserver;
 
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
 import libcore.io.IoUtils;
 import libcore.util.EmptyArray;
 
@@ -339,7 +342,44 @@
 
     @Nullable public static String sMediaStoreAuthorityProcessName;
 
+    // Run period in hour for smart idle maintenance
+    static final int SMART_IDLE_MAINT_PERIOD = 1;
+
     private final AtomicFile mSettingsFile;
+    private final AtomicFile mHourlyWriteFile;
+
+    private static final int MAX_HOURLY_WRITE_RECORDS = 72;
+
+    /**
+     * Default config values for smart idle maintenance
+     * Actual values will be controlled by DeviceConfig
+     */
+    // Decide whether smart idle maintenance is enabled or not
+    private static final boolean DEFAULT_SMART_IDLE_MAINT_ENABLED = false;
+    // Storage lifetime percentage threshold to decide to turn off the feature
+    private static final int DEFAULT_LIFETIME_PERCENT_THRESHOLD = 70;
+    // Minimum required number of dirty + free segments to trigger GC
+    private static final int DEFAULT_MIN_SEGMENTS_THRESHOLD = 512;
+    // Determine how much portion of current dirty segments will be GCed
+    private static final float DEFAULT_DIRTY_RECLAIM_RATE = 0.5F;
+    // Multiplier to amplify the target segment number for GC
+    private static final float DEFAULT_SEGMENT_RECLAIM_WEIGHT = 1.0F;
+    // Low battery level threshold to decide to turn off the feature
+    private static final float DEFAULT_LOW_BATTERY_LEVEL = 20F;
+    // Decide whether charging is required to turn on the feature
+    private static final boolean DEFAULT_CHARGING_REQUIRED = true;
+
+    private volatile int mLifetimePercentThreshold;
+    private volatile int mMinSegmentsThreshold;
+    private volatile float mDirtyReclaimRate;
+    private volatile float mSegmentReclaimWeight;
+    private volatile float mLowBatteryLevel;
+    private volatile boolean mChargingRequired;
+    private volatile boolean mNeedGC;
+
+    private volatile boolean mPassedLifetimeThresh;
+    // Tracking storage hourly write amounts
+    private volatile int[] mStorageHourlyWrites;
 
     /**
      * <em>Never</em> hold the lock while performing downcalls into vold, since
@@ -901,6 +941,10 @@
     }
 
     private void handleSystemReady() {
+        if (prepareSmartIdleMaint()) {
+            SmartStorageMaintIdler.scheduleSmartIdlePass(mContext, SMART_IDLE_MAINT_PERIOD);
+        }
+
         // Start scheduling nominally-daily fstrim operations
         MountServiceIdler.scheduleIdlePass(mContext);
 
@@ -1907,6 +1951,10 @@
 
         mSettingsFile = new AtomicFile(
                 new File(Environment.getDataSystemDirectory(), "storage.xml"), "storage-settings");
+        mHourlyWriteFile = new AtomicFile(
+                new File(Environment.getDataSystemDirectory(), "storage-hourly-writes"));
+
+        mStorageHourlyWrites = new int[MAX_HOURLY_WRITE_RECORDS];
 
         synchronized (mLock) {
             readSettingsLocked();
@@ -2572,7 +2620,7 @@
             // fstrim time is still updated. If file based checkpoints are used, we run
             // idle maintenance (GC + fstrim) regardless of checkpoint status.
             if (!needsCheckpoint() || !supportsBlockCheckpoint()) {
-                mVold.runIdleMaint(new IVoldTaskListener.Stub() {
+                mVold.runIdleMaint(mNeedGC, new IVoldTaskListener.Stub() {
                     @Override
                     public void onStatus(int status, PersistableBundle extras) {
                         // Not currently used
@@ -2623,6 +2671,176 @@
         abortIdleMaint(null);
     }
 
+    private boolean prepareSmartIdleMaint() {
+        /**
+         * We can choose whether going with a new storage smart idle maintenance job
+         * or falling back to the traditional way using DeviceConfig
+         */
+        boolean smartIdleMaintEnabled = DeviceConfig.getBoolean(
+            DeviceConfig.NAMESPACE_STORAGE_NATIVE_BOOT,
+            "smart_idle_maint_enabled",
+            DEFAULT_SMART_IDLE_MAINT_ENABLED);
+        if (smartIdleMaintEnabled) {
+            mLifetimePercentThreshold = DeviceConfig.getInt(
+                DeviceConfig.NAMESPACE_STORAGE_NATIVE_BOOT,
+                "lifetime_threshold", DEFAULT_LIFETIME_PERCENT_THRESHOLD);
+            mMinSegmentsThreshold = DeviceConfig.getInt(DeviceConfig.NAMESPACE_STORAGE_NATIVE_BOOT,
+                "min_segments_threshold", DEFAULT_MIN_SEGMENTS_THRESHOLD);
+            mDirtyReclaimRate = DeviceConfig.getFloat(DeviceConfig.NAMESPACE_STORAGE_NATIVE_BOOT,
+                "dirty_reclaim_rate", DEFAULT_DIRTY_RECLAIM_RATE);
+            mSegmentReclaimWeight = DeviceConfig.getFloat(
+                DeviceConfig.NAMESPACE_STORAGE_NATIVE_BOOT,
+                "segment_reclaim_weight", DEFAULT_SEGMENT_RECLAIM_WEIGHT);
+            mLowBatteryLevel = DeviceConfig.getFloat(DeviceConfig.NAMESPACE_STORAGE_NATIVE_BOOT,
+                "low_battery_level", DEFAULT_LOW_BATTERY_LEVEL);
+            mChargingRequired = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_STORAGE_NATIVE_BOOT,
+                "charging_required", DEFAULT_CHARGING_REQUIRED);
+
+            // If we use the smart idle maintenance, we need to turn off GC in the traditional idle
+            // maintenance to avoid the conflict
+            mNeedGC = false;
+
+            loadStorageHourlyWrites();
+            try {
+                mVold.refreshLatestWrite();
+            } catch (Exception e) {
+                Slog.wtf(TAG, e);
+            }
+            refreshLifetimeConstraint();
+        }
+        return smartIdleMaintEnabled;
+    }
+
+    // Return whether storage lifetime exceeds the threshold
+    public boolean isPassedLifetimeThresh() {
+        return mPassedLifetimeThresh;
+    }
+
+    private void loadStorageHourlyWrites() {
+        FileInputStream fis = null;
+
+        try {
+            fis = mHourlyWriteFile.openRead();
+            ObjectInputStream ois = new ObjectInputStream(fis);
+            mStorageHourlyWrites = (int[])ois.readObject();
+        } catch (FileNotFoundException e) {
+            // Missing data is okay, probably first boot
+        } catch (Exception e) {
+            Slog.wtf(TAG, "Failed reading write records", e);
+        } finally {
+            IoUtils.closeQuietly(fis);
+        }
+    }
+
+    private int getAverageHourlyWrite() {
+        return Arrays.stream(mStorageHourlyWrites).sum() / MAX_HOURLY_WRITE_RECORDS;
+    }
+
+    private void updateStorageHourlyWrites(int latestWrite) {
+        FileOutputStream fos = null;
+
+        System.arraycopy(mStorageHourlyWrites,0, mStorageHourlyWrites, 1,
+                     MAX_HOURLY_WRITE_RECORDS - 1);
+        mStorageHourlyWrites[0] = latestWrite;
+        try {
+            fos = mHourlyWriteFile.startWrite();
+            ObjectOutputStream oos = new ObjectOutputStream(fos);
+            oos.writeObject(mStorageHourlyWrites);
+            mHourlyWriteFile.finishWrite(fos);
+        } catch (IOException e) {
+            if (fos != null) {
+                mHourlyWriteFile.failWrite(fos);
+            }
+        }
+    }
+
+    private boolean checkChargeStatus() {
+        IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
+        Intent batteryStatus = mContext.registerReceiver(null, ifilter);
+
+        if (mChargingRequired) {
+            int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
+            if (status != BatteryManager.BATTERY_STATUS_CHARGING &&
+                status != BatteryManager.BATTERY_STATUS_FULL) {
+                Slog.w(TAG, "Battery is not being charged");
+                return false;
+            }
+        }
+
+        int level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
+        int scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
+        float chargePercent = level * 100f / (float)scale;
+
+        if (chargePercent < mLowBatteryLevel) {
+            Slog.w(TAG, "Battery level is " + chargePercent + ", which is lower than threshold: " +
+                        mLowBatteryLevel);
+            return false;
+        }
+        return true;
+    }
+
+    private boolean refreshLifetimeConstraint() {
+        int storageLifeTime = 0;
+
+        try {
+            storageLifeTime = mVold.getStorageLifeTime();
+        } catch (Exception e) {
+            Slog.wtf(TAG, e);
+            return false;
+        }
+
+        if (storageLifeTime == -1) {
+            Slog.w(TAG, "Failed to get storage lifetime");
+            return false;
+        } else if (storageLifeTime > mLifetimePercentThreshold) {
+            Slog.w(TAG, "Ended smart idle maintenance, because of lifetime(" + storageLifeTime +
+                        ")" + ", lifetime threshold(" + mLifetimePercentThreshold + ")");
+            mPassedLifetimeThresh = true;
+            return false;
+        }
+        Slog.i(TAG, "Storage lifetime: " + storageLifeTime);
+        return true;
+    }
+
+    void runSmartIdleMaint(Runnable callback) {
+        enforcePermission(android.Manifest.permission.MOUNT_FORMAT_FILESYSTEMS);
+
+        try {
+            // Block based checkpoint process runs fstrim. So, if checkpoint is in progress
+            // (first boot after OTA), We skip the smart idle maintenance
+            if (!needsCheckpoint() || !supportsBlockCheckpoint()) {
+                if (!refreshLifetimeConstraint() || !checkChargeStatus()) {
+                    return;
+                }
+
+                int latestHourlyWrite = mVold.getWriteAmount();
+                if (latestHourlyWrite == -1) {
+                    Slog.w(TAG, "Failed to get storage hourly write");
+                    return;
+                }
+
+                updateStorageHourlyWrites(latestHourlyWrite);
+                int avgHourlyWrite = getAverageHourlyWrite();
+
+                Slog.i(TAG, "Set smart idle maintenance: " + "latest hourly write: " +
+                            latestHourlyWrite + ", average hourly write: " + avgHourlyWrite +
+                            ", min segment threshold: " + mMinSegmentsThreshold +
+                            ", dirty reclaim rate: " + mDirtyReclaimRate +
+                            ", segment reclaim weight:" + mSegmentReclaimWeight);
+                mVold.setGCUrgentPace(avgHourlyWrite, mMinSegmentsThreshold, mDirtyReclaimRate,
+                                      mSegmentReclaimWeight);
+            } else {
+                Slog.i(TAG, "Skipping smart idle maintenance - block based checkpoint in progress");
+            }
+        } catch (Exception e) {
+            Slog.wtf(TAG, e);
+        } finally {
+            if (callback != null) {
+                callback.run();
+            }
+        }
+    }
+
     @Override
     public void setDebugFlags(int flags, int mask) {
         enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
@@ -3402,8 +3620,12 @@
                     mInstaller.tryMountDataMirror(volumeUuid);
                 }
             }
-        } catch (Exception e) {
+        } catch (RemoteException | Installer.InstallerException e) {
             Slog.wtf(TAG, e);
+            // Make sure to re-throw this exception; we must not ignore failure
+            // to prepare the user storage as it could indicate that encryption
+            // wasn't successfully set up.
+            throw new RuntimeException(e);
         }
     }
 
diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
index 4fc6614..2eb59b2 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
@@ -1205,6 +1205,7 @@
                         mDeviceInventory.onSetBtActiveDevice((BtDeviceInfo) msg.obj,
                                 mAudioService.getBluetoothContextualVolumeStream());
                     }
+                    break;
                 case MSG_BT_HEADSET_CNCT_FAILED:
                     synchronized (mSetModeLock) {
                         synchronized (mDeviceStateLock) {
diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
index 0a114b9..fba8c05 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
@@ -1088,6 +1088,12 @@
     private void makeLeAudioDeviceAvailable(String address, String name, int streamType, int device,
             String eventSource) {
         if (device != AudioSystem.DEVICE_NONE) {
+
+            /* Audio Policy sees Le Audio similar to A2DP. Let's make sure
+             * AUDIO_POLICY_FORCE_NO_BT_A2DP is not set
+             */
+            mDeviceBroker.setBluetoothA2dpOnInt(true, false /*fromA2dp*/, eventSource);
+
             AudioSystem.setDeviceConnectionState(device, AudioSystem.DEVICE_STATE_AVAILABLE,
                     address, name, AudioSystem.AUDIO_FORMAT_DEFAULT);
             mConnectedDevices.put(DeviceInfo.makeDeviceListKey(device, address),
diff --git a/services/core/java/com/android/server/broadcastradio/hal2/ProgramInfoCache.java b/services/core/java/com/android/server/broadcastradio/hal2/ProgramInfoCache.java
index 8c93891..6654c0c 100644
--- a/services/core/java/com/android/server/broadcastradio/hal2/ProgramInfoCache.java
+++ b/services/core/java/com/android/server/broadcastradio/hal2/ProgramInfoCache.java
@@ -189,7 +189,8 @@
                 removed.add(id);
             }
         }
-        if (modified.isEmpty() && removed.isEmpty() && mComplete == chunk.isComplete()) {
+        if (modified.isEmpty() && removed.isEmpty() && mComplete == chunk.isComplete()
+                && !chunk.isPurge()) {
             return null;
         }
         mComplete = chunk.isComplete();
@@ -239,9 +240,10 @@
         }
 
         // Determine number of chunks we need to send.
-        int numChunks = 0;
+        int numChunks = purge ? 1 : 0;
         if (modified != null) {
-            numChunks = roundUpFraction(modified.size(), maxNumModifiedPerChunk);
+            numChunks = Math.max(numChunks,
+                    roundUpFraction(modified.size(), maxNumModifiedPerChunk));
         }
         if (removed != null) {
             numChunks = Math.max(numChunks, roundUpFraction(removed.size(), maxNumRemovedPerChunk));
diff --git a/services/core/java/com/android/server/clipboard/ClipboardService.java b/services/core/java/com/android/server/clipboard/ClipboardService.java
index 093ecd5..3d5abfe 100644
--- a/services/core/java/com/android/server/clipboard/ClipboardService.java
+++ b/services/core/java/com/android/server/clipboard/ClipboardService.java
@@ -535,9 +535,6 @@
         mEmulatorClipboardMonitor.accept(clip);
 
         final int userId = UserHandle.getUserId(uid);
-        if (clip != null) {
-            startClassificationLocked(clip, userId);
-        }
 
         // Update this user
         setPrimaryClipInternalLocked(getClipboardLocked(userId), clip, uid, sourcePackage);
@@ -593,6 +590,17 @@
     @GuardedBy("mLock")
     private void setPrimaryClipInternalLocked(PerUserClipboard clipboard, @Nullable ClipData clip,
             int uid, @Nullable String sourcePackage) {
+        final int userId = UserHandle.getUserId(uid);
+        if (clip != null) {
+            startClassificationLocked(clip, userId);
+        }
+
+        setPrimaryClipInternalNoClassifyLocked(clipboard, clip, uid, sourcePackage);
+    }
+
+    @GuardedBy("mLock")
+    private void setPrimaryClipInternalNoClassifyLocked(PerUserClipboard clipboard,
+            @Nullable ClipData clip, int uid, @Nullable String sourcePackage) {
         revokeUris(clipboard);
         clipboard.activePermissionOwners.clear();
         if (clip == null && clipboard.primaryClip == null) {
diff --git a/services/core/java/com/android/server/clipboard/OWNERS b/services/core/java/com/android/server/clipboard/OWNERS
index 5449df9..0d5dbf9 100644
--- a/services/core/java/com/android/server/clipboard/OWNERS
+++ b/services/core/java/com/android/server/clipboard/OWNERS
@@ -1 +1,3 @@
 per-file EmulatorClipboardMonitor.java = bohu@google.com,lfy@google.com,rkir@google.com
+
+olilan@google.com
diff --git a/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java b/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java
index cc9efbc..603f206 100644
--- a/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java
+++ b/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java
@@ -18,14 +18,12 @@
 
 import static android.net.ConnectivityManager.MULTIPATH_PREFERENCE_HANDOVER;
 import static android.net.ConnectivityManager.MULTIPATH_PREFERENCE_RELIABILITY;
-import static android.net.ConnectivityManager.TYPE_MOBILE;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
 import static android.net.NetworkPolicy.LIMIT_DISABLED;
 import static android.net.NetworkPolicy.WARNING_DISABLED;
-import static android.net.NetworkTemplate.OEM_MANAGED_ALL;
 import static android.provider.Settings.Global.NETWORK_DEFAULT_DAILY_MULTIPATH_QUOTA_BYTES;
 import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
 
@@ -95,6 +93,7 @@
     private static String TAG = MultipathPolicyTracker.class.getSimpleName();
 
     private static final boolean DBG = false;
+    private static final long MIN_THRESHOLD_BYTES = 2 * 1_048_576L; // 2MiB
 
     // This context is for the current user.
     private final Context mContext;
@@ -199,6 +198,7 @@
         private final NetworkTemplate mNetworkTemplate;
         private final UsageCallback mUsageCallback;
         private NetworkCapabilities mNetworkCapabilities;
+        private final NetworkStatsManager mStatsManager;
 
         public MultipathTracker(Network network, NetworkCapabilities nc) {
             this.network = network;
@@ -238,6 +238,13 @@
                     updateMultipathBudget();
                 }
             };
+            mStatsManager = mContext.getSystemService(NetworkStatsManager.class);
+            // Query stats from NetworkStatsService will trigger a poll by default.
+            // But since MultipathPolicyTracker listens NPMS events that triggered by
+            // stats updated event, and will query stats
+            // after the event. A polling -> updated -> query -> polling loop will be introduced
+            // if polls on open. Hence, set flag to false to prevent a polling loop.
+            mStatsManager.setPollOnOpen(false);
 
             updateMultipathBudget();
         }
@@ -262,8 +269,7 @@
         private long getNetworkTotalBytes(long start, long end) {
             try {
                 final android.app.usage.NetworkStats.Bucket ret =
-                        mContext.getSystemService(NetworkStatsManager.class)
-                        .querySummaryForDevice(mNetworkTemplate, start, end);
+                        mStatsManager.querySummaryForDevice(mNetworkTemplate, start, end);
                 return ret.getRxBytes() + ret.getTxBytes();
             } catch (RuntimeException e) {
                 Log.w(TAG, "Failed to get data usage: " + e);
@@ -272,15 +278,11 @@
         }
 
         private NetworkIdentity getTemplateMatchingNetworkIdentity(NetworkCapabilities nc) {
-            return new NetworkIdentity(
-                    ConnectivityManager.TYPE_MOBILE,
-                    0 /* subType, unused for template matching */,
-                    subscriberId,
-                    null /* networkId, unused for matching mobile networks */,
-                    !nc.hasCapability(NET_CAPABILITY_NOT_ROAMING),
-                    !nc.hasCapability(NET_CAPABILITY_NOT_METERED),
-                    false /* defaultNetwork, templates should have DEFAULT_NETWORK_ALL */,
-                    OEM_MANAGED_ALL);
+            return new NetworkIdentity.Builder().setType(ConnectivityManager.TYPE_MOBILE)
+                    .setSubscriberId(subscriberId)
+                    .setRoaming(!nc.hasCapability(NET_CAPABILITY_NOT_ROAMING))
+                    .setMetered(!nc.hasCapability(NET_CAPABILITY_NOT_METERED))
+                    .build();
         }
 
         private long getRemainingDailyBudget(long limitBytes,
@@ -369,7 +371,7 @@
             // This will only be called if the total quota for the day changed, not if usage changed
             // since last time, so even if this is called very often the budget will not snap to 0
             // as soon as there are less than 2MB left for today.
-            if (budget > NetworkStatsManager.MIN_THRESHOLD_BYTES) {
+            if (budget > MIN_THRESHOLD_BYTES) {
                 if (DBG) {
                     Log.d(TAG, "Setting callback for " + budget + " bytes on network " + network);
                 }
@@ -402,8 +404,8 @@
 
         private void registerUsageCallback(long budget) {
             maybeUnregisterUsageCallback();
-            mStatsManager.registerUsageCallback(mNetworkTemplate, TYPE_MOBILE, budget,
-                    mUsageCallback, mHandler);
+            mStatsManager.registerUsageCallback(mNetworkTemplate, budget,
+                    (command) -> mHandler.post(command), mUsageCallback);
             mMultipathBudget = budget;
         }
 
diff --git a/services/core/java/com/android/server/media/BluetoothRouteProvider.java b/services/core/java/com/android/server/media/BluetoothRouteProvider.java
index ffc1aed..91de9e5 100644
--- a/services/core/java/com/android/server/media/BluetoothRouteProvider.java
+++ b/services/core/java/com/android/server/media/BluetoothRouteProvider.java
@@ -344,10 +344,19 @@
     }
 
     private void addActiveRoute(BluetoothRouteInfo btRoute) {
+        if (btRoute == null) {
+            if (DEBUG) {
+                Log.d(TAG, " btRoute is null");
+            }
+            return;
+        }
         if (DEBUG) {
             Log.d(TAG, "Adding active route: " + btRoute.route);
         }
-        if (btRoute == null || mActiveRoutes.contains(btRoute)) {
+        if (mActiveRoutes.contains(btRoute)) {
+            if (DEBUG) {
+                Log.d(TAG, " btRoute is already added.");
+            }
             return;
         }
         setRouteConnectionState(btRoute, STATE_CONNECTED);
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerInternal.java b/services/core/java/com/android/server/net/NetworkPolicyManagerInternal.java
index 03a63b9..8ef42ff 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerInternal.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerInternal.java
@@ -16,11 +16,8 @@
 
 package com.android.server.net;
 
-import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.net.Network;
-import android.net.NetworkTemplate;
-import android.net.netstats.provider.NetworkStatsProvider;
 import android.os.PowerExemptionManager.ReasonCode;
 import android.telephony.SubscriptionPlan;
 
@@ -56,11 +53,6 @@
      */
     public abstract SubscriptionPlan getSubscriptionPlan(Network network);
 
-    /**
-     * Return the active {@link SubscriptionPlan} for the given template.
-     */
-    public abstract SubscriptionPlan getSubscriptionPlan(NetworkTemplate template);
-
     public static final int QUOTA_TYPE_JOBS = 1;
     public static final int QUOTA_TYPE_MULTIPATH = 2;
 
@@ -99,13 +91,4 @@
      */
     public abstract void setMeteredRestrictedPackagesAsync(
             Set<String> packageNames, int userId);
-
-    /**
-     *  Notifies that the specified {@link NetworkStatsProvider} has reached its quota
-     *  which was set through {@link NetworkStatsProvider#onSetLimit(String, long)} or
-     *  {@link NetworkStatsProvider#onSetWarningAndLimit(String, long, long)}.
-     *
-     * @param tag the human readable identifier of the custom network stats provider.
-     */
-    public abstract void onStatsProviderWarningOrLimitReached(@NonNull String tag);
 }
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 2ca057d..c05138f 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -24,7 +24,6 @@
 import static android.Manifest.permission.NETWORK_SETTINGS;
 import static android.Manifest.permission.NETWORK_STACK;
 import static android.Manifest.permission.OBSERVE_NETWORK_POLICY;
-import static android.Manifest.permission.READ_NETWORK_USAGE_HISTORY;
 import static android.Manifest.permission.READ_PHONE_STATE;
 import static android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE;
 import static android.app.PendingIntent.FLAG_IMMUTABLE;
@@ -63,7 +62,6 @@
 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
-import static android.net.NetworkIdentity.OEM_NONE;
 import static android.net.NetworkPolicy.LIMIT_DISABLED;
 import static android.net.NetworkPolicy.SNOOZE_NEVER;
 import static android.net.NetworkPolicy.WARNING_DISABLED;
@@ -102,7 +100,6 @@
 import static android.net.NetworkTemplate.MATCH_WIFI;
 import static android.net.NetworkTemplate.buildTemplateCarrierMetered;
 import static android.net.NetworkTemplate.buildTemplateMobileAll;
-import static android.net.TrafficStats.MB_IN_BYTES;
 import static android.net.netstats.provider.NetworkStatsProvider.QUOTA_UNLIMITED;
 import static android.os.Trace.TRACE_TAG_NETWORK;
 import static android.provider.Settings.Global.NETPOLICY_OVERRIDE_ENABLED;
@@ -130,8 +127,7 @@
 import static com.android.internal.util.XmlUtils.writeIntAttribute;
 import static com.android.internal.util.XmlUtils.writeLongAttribute;
 import static com.android.internal.util.XmlUtils.writeStringAttribute;
-import static com.android.server.NetworkManagementService.LIMIT_GLOBAL_ALERT;
-import static com.android.server.net.NetworkStatsService.ACTION_NETWORK_STATS_UPDATED;
+import static com.android.net.module.util.NetworkStatsUtils.LIMIT_GLOBAL_ALERT;
 
 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
 import static org.xmlpull.v1.XmlPullParser.END_TAG;
@@ -151,6 +147,8 @@
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
+import android.app.usage.NetworkStats;
+import android.app.usage.NetworkStatsManager;
 import android.app.usage.UsageStatsManagerInternal;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
@@ -181,10 +179,8 @@
 import android.net.NetworkSpecifier;
 import android.net.NetworkStack;
 import android.net.NetworkStateSnapshot;
-import android.net.NetworkStats;
 import android.net.NetworkTemplate;
 import android.net.TelephonyNetworkSpecifier;
-import android.net.TrafficStats;
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiManager;
 import android.os.BestClock;
@@ -443,7 +439,7 @@
 
     private final Context mContext;
     private final IActivityManager mActivityManager;
-    private NetworkStatsManagerInternal mNetworkStats;
+    private NetworkStatsManager mNetworkStats;
     private final INetworkManagementService mNetworkManager;
     private UsageStatsManagerInternal mUsageStats;
     private AppStandbyInternal mAppStandby;
@@ -455,6 +451,8 @@
     private ConnectivityManager mConnManager;
     private PowerManagerInternal mPowerManagerInternal;
     private PowerWhitelistManager mPowerWhitelistManager;
+    @NonNull
+    private final Dependencies mDeps;
 
     /** Current cached value of the current Battery Saver mode's setting for restrict background. */
     @GuardedBy("mUidRulesFirstLock")
@@ -706,7 +704,7 @@
     public NetworkPolicyManagerService(Context context, IActivityManager activityManager,
             INetworkManagementService networkManagement) {
         this(context, activityManager, networkManagement, AppGlobals.getPackageManager(),
-                getDefaultClock(), getDefaultSystemDir(), false);
+                getDefaultClock(), getDefaultSystemDir(), false, new Dependencies(context));
     }
 
     private static @NonNull File getDefaultSystemDir() {
@@ -718,9 +716,59 @@
                 Clock.systemUTC());
     }
 
+    static class Dependencies {
+        final Context mContext;
+        final NetworkStatsManager mNetworkStatsManager;
+        Dependencies(Context context) {
+            mContext = context;
+            mNetworkStatsManager = mContext.getSystemService(NetworkStatsManager.class);
+            // Query stats from NetworkStatsService will trigger a poll by default.
+            // But since NPMS listens stats updated event, and will query stats
+            // after the event. A polling -> updated -> query -> polling loop will be introduced
+            // if polls on open. Hence, while NPMS manages it's poll requests explicitly, set
+            // flag to false to prevent a polling loop.
+            mNetworkStatsManager.setPollOnOpen(false);
+        }
+
+        long getNetworkTotalBytes(NetworkTemplate template, long start, long end) {
+            Trace.traceBegin(TRACE_TAG_NETWORK, "getNetworkTotalBytes");
+            try {
+                final NetworkStats.Bucket ret = mNetworkStatsManager
+                        .querySummaryForDevice(template, start, end);
+                return ret.getRxBytes() + ret.getTxBytes();
+            } catch (RuntimeException e) {
+                Slog.w(TAG, "Failed to read network stats: " + e);
+                return 0;
+            } finally {
+                Trace.traceEnd(TRACE_TAG_NETWORK);
+            }
+        }
+
+        @NonNull
+        List<NetworkStats.Bucket> getNetworkUidBytes(
+                @NonNull NetworkTemplate template, long start, long end) {
+            Trace.traceBegin(TRACE_TAG_NETWORK, "getNetworkUidBytes");
+            final List<NetworkStats.Bucket> buckets = new ArrayList<>();
+            try {
+                final NetworkStats stats = mNetworkStatsManager.querySummary(template, start, end);
+                while (stats.hasNextBucket()) {
+                    final NetworkStats.Bucket bucket = new NetworkStats.Bucket();
+                    stats.getNextBucket(bucket);
+                    buckets.add(bucket);
+                }
+            } catch (RuntimeException e) {
+                Slog.w(TAG, "Failed to read network stats: " + e);
+            } finally {
+                Trace.traceEnd(TRACE_TAG_NETWORK);
+            }
+            return buckets;
+        }
+    }
+
+    @VisibleForTesting
     public NetworkPolicyManagerService(Context context, IActivityManager activityManager,
             INetworkManagementService networkManagement, IPackageManager pm, Clock clock,
-            File systemDir, boolean suppressDefaultPolicy) {
+            File systemDir, boolean suppressDefaultPolicy, Dependencies deps) {
         mContext = Objects.requireNonNull(context, "missing context");
         mActivityManager = Objects.requireNonNull(activityManager, "missing activityManager");
         mNetworkManager = Objects.requireNonNull(networkManagement, "missing networkManagement");
@@ -741,10 +789,12 @@
         mUidEventHandler = new Handler(mUidEventThread.getLooper(), mUidEventHandlerCallback);
 
         mSuppressDefaultPolicy = suppressDefaultPolicy;
+        mDeps = Objects.requireNonNull(deps, "missing Dependencies");
 
         mPolicyFile = new AtomicFile(new File(systemDir, "netpolicy.xml"), "net-policy");
 
         mAppOps = context.getSystemService(AppOpsManager.class);
+        mNetworkStats = context.getSystemService(NetworkStatsManager.class);
         mMultipathPolicyTracker = new MultipathPolicyTracker(mContext, mHandler);
         // Expose private service for system components to use.
         LocalServices.addService(NetworkPolicyManagerInternal.class,
@@ -844,7 +894,6 @@
 
             mUsageStats = LocalServices.getService(UsageStatsManagerInternal.class);
             mAppStandby = LocalServices.getService(AppStandbyInternal.class);
-            mNetworkStats = LocalServices.getService(NetworkStatsManagerInternal.class);
 
             synchronized (mUidRulesFirstLock) {
                 synchronized (mNetworkPoliciesSecondLock) {
@@ -959,10 +1008,11 @@
             userFilter.addAction(ACTION_USER_REMOVED);
             mContext.registerReceiver(mUserReceiver, userFilter, null, mHandler);
 
-            // listen for stats update events
-            final IntentFilter statsFilter = new IntentFilter(ACTION_NETWORK_STATS_UPDATED);
-            mContext.registerReceiver(
-                    mStatsReceiver, statsFilter, READ_NETWORK_USAGE_HISTORY, mHandler);
+            // listen for stats updated callbacks for interested network types.
+            mNetworkStats.registerUsageCallback(new NetworkTemplate.Builder(MATCH_MOBILE).build(),
+                    0 /* thresholdBytes */, new HandlerExecutor(mHandler), mStatsCallback);
+            mNetworkStats.registerUsageCallback(new NetworkTemplate.Builder(MATCH_WIFI).build(),
+                    0 /* thresholdBytes */, new HandlerExecutor(mHandler), mStatsCallback);
 
             // listen for restrict background changes from notifications
             final IntentFilter allowFilter = new IntentFilter(ACTION_ALLOW_BACKGROUND);
@@ -1167,14 +1217,16 @@
     };
 
     /**
-     * Receiver that watches for {@link INetworkStatsService} updates, which we
-     * use to check against {@link NetworkPolicy#warningBytes}.
+     * Listener that watches for {@link NetworkStatsManager} updates, which
+     * NetworkPolicyManagerService uses to check against {@link NetworkPolicy#warningBytes}.
      */
-    final private BroadcastReceiver mStatsReceiver = new BroadcastReceiver() {
+    private final StatsCallback mStatsCallback = new StatsCallback();
+    private class StatsCallback extends NetworkStatsManager.UsageCallback {
+        private boolean mIsAnyCallbackReceived = false;
+
         @Override
-        public void onReceive(Context context, Intent intent) {
-            // on background handler thread, and verified
-            // READ_NETWORK_USAGE_HISTORY permission above.
+        public void onThresholdReached(int networkType, String subscriberId) {
+            mIsAnyCallbackReceived = true;
 
             synchronized (mNetworkPoliciesSecondLock) {
                 updateNetworkRulesNL();
@@ -1182,6 +1234,14 @@
                 updateNotificationsNL();
             }
         }
+
+        /**
+         * Return whether any callback is received.
+         * Used to determine if NetworkStatsService is ready.
+         */
+        public boolean isAnyCallbackReceived() {
+            return mIsAnyCallbackReceived;
+        }
     };
 
     /**
@@ -1405,15 +1465,17 @@
         long maxBytes = 0;
         int maxUid = 0;
 
-        final NetworkStats stats = getNetworkUidBytes(template, start, end);
-        NetworkStats.Entry entry = null;
-        for (int i = 0; i < stats.size(); i++) {
-            entry = stats.getValues(i, entry);
-            final long bytes = entry.rxBytes + entry.txBytes;
+        // Skip if not ready. NetworkStatsService will block public API calls until it is
+        // ready. To prevent NPMS be blocked on that, skip and fail fast instead.
+        if (!mStatsCallback.isAnyCallbackReceived()) return null;
+
+        final List<NetworkStats.Bucket> stats = mDeps.getNetworkUidBytes(template, start, end);
+        for (final NetworkStats.Bucket entry : stats) {
+            final long bytes = entry.getRxBytes() + entry.getTxBytes();
             totalBytes += bytes;
             if (bytes > maxBytes) {
                 maxBytes = bytes;
-                maxUid = entry.uid;
+                maxUid = entry.getUid();
             }
         }
 
@@ -1449,13 +1511,11 @@
         for (int i = 0; i < mSubIdToSubscriberId.size(); i++) {
             final int subId = mSubIdToSubscriberId.keyAt(i);
             final String subscriberId = mSubIdToSubscriberId.valueAt(i);
-            final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE,
-                    TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true,
-                    true, OEM_NONE);
-            /* While OEM_NONE indicates "any non OEM managed network", OEM_NONE is meant to be a
-             * placeholder value here. The probeIdent is matched against a NetworkTemplate which
-             * should have its OEM managed value set to OEM_MANAGED_ALL, which will cause the
-             * template to match probeIdent without regard to OEM managed status. */
+            final NetworkIdentity probeIdent = new NetworkIdentity.Builder()
+                    .setType(TYPE_MOBILE)
+                    .setSubscriberId(subscriberId)
+                    .setMetered(true)
+                    .setDefaultNetwork(true).build();
             if (template.matches(probeIdent)) {
                 return subId;
             }
@@ -1688,9 +1748,11 @@
 
         // find and update the carrier NetworkPolicy for this subscriber id
         boolean policyUpdated = false;
-        final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE,
-                TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true, true,
-                OEM_NONE);
+        final NetworkIdentity probeIdent = new NetworkIdentity.Builder()
+                .setType(TYPE_MOBILE)
+                .setSubscriberId(subscriberId)
+                .setMetered(true)
+                .setDefaultNetwork(true).build();
         for (int i = mNetworkPolicy.size() - 1; i >= 0; i--) {
             final NetworkTemplate template = mNetworkPolicy.keyAt(i);
             if (template.matches(probeIdent)) {
@@ -1918,10 +1980,11 @@
                 for (int i = 0; i < mSubIdToSubscriberId.size(); i++) {
                     final int subId = mSubIdToSubscriberId.keyAt(i);
                     final String subscriberId = mSubIdToSubscriberId.valueAt(i);
-
-                    final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE,
-                            TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true,
-                            true, OEM_NONE);
+                    final NetworkIdentity probeIdent = new NetworkIdentity.Builder()
+                            .setType(TYPE_MOBILE)
+                            .setSubscriberId(subscriberId)
+                            .setMetered(true)
+                            .setDefaultNetwork(true).build();
                     // Template is matched when subscriber id matches.
                     if (template.matches(probeIdent)) {
                         matchingSubIds.add(subId);
@@ -2025,11 +2088,9 @@
         for (final NetworkStateSnapshot snapshot : snapshots) {
             mNetIdToSubId.put(snapshot.getNetwork().getNetId(), parseSubId(snapshot));
 
-            // Policies matched by NPMS only match by subscriber ID or by network ID. Thus subtype
-            // in the object created here is never used and its value doesn't matter, so use
-            // NETWORK_TYPE_UNKNOWN.
-            final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, snapshot,
-                    true, TelephonyManager.NETWORK_TYPE_UNKNOWN /* subType */);
+            // Policies matched by NPMS only match by subscriber ID or by network ID.
+            final NetworkIdentity ident = new NetworkIdentity.Builder()
+                    .setNetworkStateSnapshot(snapshot).setDefaultNetwork(true).build();
             identified.put(snapshot, ident);
         }
 
@@ -2226,9 +2287,11 @@
     @GuardedBy("mNetworkPoliciesSecondLock")
     private boolean ensureActiveCarrierPolicyAL(int subId, String subscriberId) {
         // Poke around to see if we already have a policy
-        final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE,
-                TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true, true,
-                OEM_NONE);
+        final NetworkIdentity probeIdent = new NetworkIdentity.Builder()
+                .setType(TYPE_MOBILE)
+                .setSubscriberId(subscriberId)
+                .setMetered(true)
+                .setDefaultNetwork(true).build();
         for (int i = mNetworkPolicy.size() - 1; i >= 0; i--) {
             final NetworkTemplate template = mNetworkPolicy.keyAt(i);
             if (template.matches(probeIdent)) {
@@ -2254,7 +2317,7 @@
         if (dataWarningConfig == WARNING_DISABLED) {
             return WARNING_DISABLED;
         } else {
-            return dataWarningConfig * MB_IN_BYTES;
+            return DataUnit.MEBIBYTES.toBytes(dataWarningConfig);
         }
     }
 
@@ -2638,7 +2701,7 @@
         final List<WifiConfiguration> configs = wm.getConfiguredNetworks();
         for (int i = 0; i < configs.size(); ++i) {
             final WifiConfiguration config = configs.get(i);
-            for (String key : config.getAllPersistableNetworkKeys()) {
+            for (String key : config.getAllNetworkKeys()) {
                 final Boolean metered = wifiNetworkKeys.get(key);
                 if (metered != null) {
                     Slog.d(TAG, "Found network " + key + "; upgrading metered hint");
@@ -3383,6 +3446,35 @@
         return result;
     }
 
+    /**
+     * Get subscription plan for the given networkTemplate.
+     *
+     * @param template the networkTemplate to get the subscription plan for.
+     */
+    @Override
+    public SubscriptionPlan getSubscriptionPlan(@NonNull NetworkTemplate template) {
+        enforceAnyPermissionOf(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
+        synchronized (mNetworkPoliciesSecondLock) {
+            final int subId = findRelevantSubIdNL(template);
+            return getPrimarySubscriptionPlanLocked(subId);
+        }
+    }
+
+    /**
+     * Notifies that the specified {@link NetworkStatsProvider} has reached its quota
+     * which was set through {@link NetworkStatsProvider#onSetLimit(String, long)} or
+     * {@link NetworkStatsProvider#onSetWarningAndLimit(String, long, long)}.
+     */
+    @Override
+    public void notifyStatsProviderWarningOrLimitReached() {
+        enforceAnyPermissionOf(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
+        // This API may be called before the system is ready.
+        synchronized (mNetworkPoliciesSecondLock) {
+            if (!mSystemReady) return;
+        }
+        mHandler.obtainMessage(MSG_STATS_PROVIDER_WARNING_OR_LIMIT_REACHED).sendToTarget();
+    }
+
     @Override
     public SubscriptionPlan[] getSubscriptionPlans(int subId, String callingPackage) {
         enforceSubscriptionPlanAccess(subId, Binder.getCallingUid(), callingPackage);
@@ -3394,9 +3486,9 @@
                 plans.add(SubscriptionPlan.Builder
                         .createRecurringMonthly(ZonedDateTime.parse("2007-03-14T00:00:00.000Z"))
                         .setTitle("G-Mobile")
-                        .setDataLimit(5 * TrafficStats.GB_IN_BYTES,
+                        .setDataLimit(DataUnit.GIBIBYTES.toBytes(5),
                                 SubscriptionPlan.LIMIT_BEHAVIOR_BILLED)
-                        .setDataUsage(1 * TrafficStats.GB_IN_BYTES,
+                        .setDataUsage(DataUnit.GIBIBYTES.toBytes(1),
                                 ZonedDateTime.now().minusHours(36).toInstant().toEpochMilli())
                         .build());
                 plans.add(SubscriptionPlan.Builder
@@ -3404,15 +3496,15 @@
                         .setTitle("G-Mobile Happy")
                         .setDataLimit(SubscriptionPlan.BYTES_UNLIMITED,
                                 SubscriptionPlan.LIMIT_BEHAVIOR_BILLED)
-                        .setDataUsage(5 * TrafficStats.GB_IN_BYTES,
+                        .setDataUsage(DataUnit.GIBIBYTES.toBytes(5),
                                 ZonedDateTime.now().minusHours(36).toInstant().toEpochMilli())
                         .build());
                 plans.add(SubscriptionPlan.Builder
                         .createRecurringMonthly(ZonedDateTime.parse("2017-03-14T00:00:00.000Z"))
                         .setTitle("G-Mobile, Charged after limit")
-                        .setDataLimit(5 * TrafficStats.GB_IN_BYTES,
+                        .setDataLimit(DataUnit.GIBIBYTES.toBytes(5),
                                 SubscriptionPlan.LIMIT_BEHAVIOR_BILLED)
-                        .setDataUsage(5 * TrafficStats.GB_IN_BYTES,
+                        .setDataUsage(DataUnit.GIBIBYTES.toBytes(5),
                                 ZonedDateTime.now().minusHours(36).toInstant().toEpochMilli())
                         .build());
             } else if ("month_soft".equals(fake)) {
@@ -3421,25 +3513,25 @@
                         .setTitle("G-Mobile is the carriers name who this plan belongs to")
                         .setSummary("Crazy unlimited bandwidth plan with incredibly long title "
                                 + "that should be cut off to prevent UI from looking terrible")
-                        .setDataLimit(5 * TrafficStats.GB_IN_BYTES,
+                        .setDataLimit(DataUnit.GIBIBYTES.toBytes(5),
                                 SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED)
-                        .setDataUsage(1 * TrafficStats.GB_IN_BYTES,
+                        .setDataUsage(DataUnit.GIBIBYTES.toBytes(1),
                                 ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli())
                         .build());
                 plans.add(SubscriptionPlan.Builder
                         .createRecurringMonthly(ZonedDateTime.parse("2017-03-14T00:00:00.000Z"))
                         .setTitle("G-Mobile, Throttled after limit")
-                        .setDataLimit(5 * TrafficStats.GB_IN_BYTES,
+                        .setDataLimit(DataUnit.GIBIBYTES.toBytes(5),
                                 SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED)
-                        .setDataUsage(5 * TrafficStats.GB_IN_BYTES,
+                        .setDataUsage(DataUnit.GIBIBYTES.toBytes(5),
                                 ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli())
                         .build());
                 plans.add(SubscriptionPlan.Builder
                         .createRecurringMonthly(ZonedDateTime.parse("2017-03-14T00:00:00.000Z"))
                         .setTitle("G-Mobile, No data connection after limit")
-                        .setDataLimit(5 * TrafficStats.GB_IN_BYTES,
+                        .setDataLimit(DataUnit.GIBIBYTES.toBytes(5),
                                 SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED)
-                        .setDataUsage(5 * TrafficStats.GB_IN_BYTES,
+                        .setDataUsage(DataUnit.GIBIBYTES.toBytes(5),
                                 ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli())
                         .build());
 
@@ -3447,25 +3539,25 @@
                 plans.add(SubscriptionPlan.Builder
                         .createRecurringMonthly(ZonedDateTime.parse("2007-03-14T00:00:00.000Z"))
                         .setTitle("G-Mobile is the carriers name who this plan belongs to")
-                        .setDataLimit(5 * TrafficStats.GB_IN_BYTES,
+                        .setDataLimit(DataUnit.GIBIBYTES.toBytes(5),
                                 SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED)
-                        .setDataUsage(6 * TrafficStats.GB_IN_BYTES,
+                        .setDataUsage(DataUnit.GIBIBYTES.toBytes(6),
                                 ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli())
                         .build());
                 plans.add(SubscriptionPlan.Builder
                         .createRecurringMonthly(ZonedDateTime.parse("2017-03-14T00:00:00.000Z"))
                         .setTitle("G-Mobile, Throttled after limit")
-                        .setDataLimit(5 * TrafficStats.GB_IN_BYTES,
+                        .setDataLimit(DataUnit.GIBIBYTES.toBytes(5),
                                 SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED)
-                        .setDataUsage(5 * TrafficStats.GB_IN_BYTES,
+                        .setDataUsage(DataUnit.GIBIBYTES.toBytes(5),
                                 ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli())
                         .build());
                 plans.add(SubscriptionPlan.Builder
                         .createRecurringMonthly(ZonedDateTime.parse("2017-03-14T00:00:00.000Z"))
                         .setTitle("G-Mobile, No data connection after limit")
-                        .setDataLimit(5 * TrafficStats.GB_IN_BYTES,
+                        .setDataLimit(DataUnit.GIBIBYTES.toBytes(5),
                                 SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED)
-                        .setDataUsage(5 * TrafficStats.GB_IN_BYTES,
+                        .setDataUsage(DataUnit.GIBIBYTES.toBytes(5),
                                 ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli())
                         .build());
 
@@ -3479,9 +3571,9 @@
                         .createNonrecurring(ZonedDateTime.now().minusDays(20),
                                 ZonedDateTime.now().plusDays(10))
                         .setTitle("G-Mobile")
-                        .setDataLimit(512 * TrafficStats.MB_IN_BYTES,
+                        .setDataLimit(DataUnit.MEBIBYTES.toBytes(512),
                                 SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED)
-                        .setDataUsage(100 * TrafficStats.MB_IN_BYTES,
+                        .setDataUsage(DataUnit.MEBIBYTES.toBytes(100),
                                 ZonedDateTime.now().minusHours(3).toInstant().toEpochMilli())
                         .build());
             } else if ("prepaid_crazy".equals(fake)) {
@@ -3489,9 +3581,9 @@
                         .createNonrecurring(ZonedDateTime.now().minusDays(20),
                                 ZonedDateTime.now().plusDays(10))
                         .setTitle("G-Mobile Anytime")
-                        .setDataLimit(512 * TrafficStats.MB_IN_BYTES,
+                        .setDataLimit(DataUnit.MEBIBYTES.toBytes(512),
                                 SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED)
-                        .setDataUsage(100 * TrafficStats.MB_IN_BYTES,
+                        .setDataUsage(DataUnit.MEBIBYTES.toBytes(100),
                                 ZonedDateTime.now().minusHours(3).toInstant().toEpochMilli())
                         .build());
                 plans.add(SubscriptionPlan.Builder
@@ -3499,9 +3591,9 @@
                                 ZonedDateTime.now().plusDays(20))
                         .setTitle("G-Mobile Nickel Nights")
                         .setSummary("5¢/GB between 1-5AM")
-                        .setDataLimit(5 * TrafficStats.GB_IN_BYTES,
+                        .setDataLimit(DataUnit.GIBIBYTES.toBytes(5),
                                 SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED)
-                        .setDataUsage(15 * TrafficStats.MB_IN_BYTES,
+                        .setDataUsage(DataUnit.MEBIBYTES.toBytes(15),
                                 ZonedDateTime.now().minusHours(30).toInstant().toEpochMilli())
                         .build());
                 plans.add(SubscriptionPlan.Builder
@@ -3509,9 +3601,9 @@
                                 ZonedDateTime.now().plusDays(20))
                         .setTitle("G-Mobile Bonus 3G")
                         .setSummary("Unlimited 3G data")
-                        .setDataLimit(1 * TrafficStats.GB_IN_BYTES,
+                        .setDataLimit(DataUnit.GIBIBYTES.toBytes(1),
                                 SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED)
-                        .setDataUsage(300 * TrafficStats.MB_IN_BYTES,
+                        .setDataUsage(DataUnit.MEBIBYTES.toBytes(300),
                                 ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli())
                         .build());
             } else if ("unlimited".equals(fake)) {
@@ -3521,7 +3613,7 @@
                         .setTitle("G-Mobile Awesome")
                         .setDataLimit(SubscriptionPlan.BYTES_UNLIMITED,
                                 SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED)
-                        .setDataUsage(50 * TrafficStats.MB_IN_BYTES,
+                        .setDataUsage(DataUnit.MEBIBYTES.toBytes(50),
                                 ZonedDateTime.now().minusHours(3).toInstant().toEpochMilli())
                         .build());
             }
@@ -5000,7 +5092,8 @@
                     // make sure stats are recorded frequently enough; we aim
                     // for 2MB threshold for 2GB/month rules.
                     final long persistThreshold = lowestRule / 1000;
-                    mNetworkStats.advisePersistThreshold(persistThreshold);
+                    // TODO: Sync internal naming with the API surface.
+                    mNetworkStats.setDefaultGlobalAlert(persistThreshold);
                     return true;
                 }
                 case MSG_UPDATE_INTERFACE_QUOTAS: {
@@ -5369,25 +5462,10 @@
 
     @Deprecated
     private long getTotalBytes(NetworkTemplate template, long start, long end) {
-        return getNetworkTotalBytes(template, start, end);
-    }
-
-    private long getNetworkTotalBytes(NetworkTemplate template, long start, long end) {
-        try {
-            return mNetworkStats.getNetworkTotalBytes(template, start, end);
-        } catch (RuntimeException e) {
-            Slog.w(TAG, "Failed to read network stats: " + e);
-            return 0;
-        }
-    }
-
-    private NetworkStats getNetworkUidBytes(NetworkTemplate template, long start, long end) {
-        try {
-            return mNetworkStats.getNetworkUidBytes(template, start, end);
-        } catch (RuntimeException e) {
-            Slog.w(TAG, "Failed to read network stats: " + e);
-            return new NetworkStats(SystemClock.elapsedRealtime(), 0);
-        }
+        // Skip if not ready. NetworkStatsService will block public API calls until it is
+        // ready. To prevent NPMS be blocked on that, skip and fail fast instead.
+        if (!mStatsCallback.isAnyCallbackReceived()) return 0;
+        return mDeps.getNetworkTotalBytes(template, start, end);
     }
 
     private boolean isBandwidthControlEnabled() {
@@ -5607,14 +5685,6 @@
         }
 
         @Override
-        public SubscriptionPlan getSubscriptionPlan(NetworkTemplate template) {
-            synchronized (mNetworkPoliciesSecondLock) {
-                final int subId = findRelevantSubIdNL(template);
-                return getPrimarySubscriptionPlanLocked(subId);
-            }
-        }
-
-        @Override
         public long getSubscriptionOpportunisticQuota(Network network, int quotaType) {
             final long quotaBytes;
             synchronized (mNetworkPoliciesSecondLock) {
@@ -5656,12 +5726,6 @@
             mHandler.obtainMessage(MSG_METERED_RESTRICTED_PACKAGES_CHANGED,
                     userId, 0, packageNames).sendToTarget();
         }
-
-        @Override
-        public void onStatsProviderWarningOrLimitReached(@NonNull String tag) {
-            Log.v(TAG, "onStatsProviderWarningOrLimitReached: " + tag);
-            mHandler.obtainMessage(MSG_STATS_PROVIDER_WARNING_OR_LIMIT_REACHED).sendToTarget();
-        }
     }
 
     private void setMeteredRestrictedPackagesInternal(Set<String> packageNames, int userId) {
diff --git a/services/core/java/com/android/server/pm/UserDataPreparer.java b/services/core/java/com/android/server/pm/UserDataPreparer.java
index 045a295..5047690 100644
--- a/services/core/java/com/android/server/pm/UserDataPreparer.java
+++ b/services/core/java/com/android/server/pm/UserDataPreparer.java
@@ -22,6 +22,7 @@
 import android.content.pm.UserInfo;
 import android.os.Environment;
 import android.os.FileUtils;
+import android.os.RecoverySystem;
 import android.os.storage.StorageManager;
 import android.os.storage.VolumeInfo;
 import android.os.SystemProperties;
@@ -115,6 +116,13 @@
                 // Try one last time; if we fail again we're really in trouble
                 prepareUserDataLI(volumeUuid, userId, userSerial,
                     flags | StorageManager.FLAG_STORAGE_DE, false);
+            } else {
+                try {
+                    Log.e(TAG, "prepareUserData failed", e);
+                    RecoverySystem.rebootPromptAndWipeUserData(mContext, "prepareUserData failed");
+                } catch (IOException e2) {
+                    throw new RuntimeException("error rebooting into recovery", e2);
+                }
             }
         }
     }
diff --git a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
index 1ef2025..758877b 100644
--- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
+++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
@@ -18,27 +18,17 @@
 
 import static android.app.AppOpsManager.OP_FLAG_SELF;
 import static android.app.AppOpsManager.OP_FLAG_TRUSTED_PROXIED;
-import static android.app.usage.NetworkStatsManager.FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN;
-import static android.app.usage.NetworkStatsManager.FLAG_POLL_FORCE;
-import static android.app.usage.NetworkStatsManager.FLAG_POLL_ON_OPEN;
 import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED;
 import static android.content.pm.PermissionInfo.PROTECTION_DANGEROUS;
 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
 import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
-import static android.net.NetworkIdentity.OEM_PAID;
-import static android.net.NetworkIdentity.OEM_PRIVATE;
-import static android.net.NetworkStats.DEFAULT_NETWORK_ALL;
-import static android.net.NetworkStats.METERED_ALL;
 import static android.net.NetworkStats.METERED_YES;
-import static android.net.NetworkStats.ROAMING_ALL;
 import static android.net.NetworkTemplate.MATCH_ETHERNET;
-import static android.net.NetworkTemplate.MATCH_MOBILE_WILDCARD;
-import static android.net.NetworkTemplate.MATCH_WIFI_WILDCARD;
-import static android.net.NetworkTemplate.NETWORK_TYPE_ALL;
+import static android.net.NetworkTemplate.MATCH_MOBILE;
+import static android.net.NetworkTemplate.MATCH_WIFI;
 import static android.net.NetworkTemplate.OEM_MANAGED_ALL;
-import static android.net.NetworkTemplate.buildTemplateMobileWildcard;
-import static android.net.NetworkTemplate.buildTemplateMobileWithRatType;
-import static android.net.NetworkTemplate.buildTemplateWifiWildcard;
+import static android.net.NetworkTemplate.OEM_MANAGED_PAID;
+import static android.net.NetworkTemplate.OEM_MANAGED_PRIVATE;
 import static android.net.NetworkTemplate.getAllCollapsedRatTypes;
 import static android.os.Debug.getIonHeapsSizeKb;
 import static android.os.Process.LAST_SHARED_APPLICATION_GID;
@@ -80,6 +70,7 @@
 import android.app.RuntimeAppOpAccessMessage;
 import android.app.StatsManager;
 import android.app.StatsManager.PullAtomMetadata;
+import android.app.usage.NetworkStatsManager;
 import android.bluetooth.BluetoothActivityEnergyInfo;
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.UidTraffic;
@@ -93,8 +84,6 @@
 import android.hardware.face.FaceManager;
 import android.hardware.fingerprint.FingerprintManager;
 import android.net.ConnectivityManager;
-import android.net.INetworkStatsService;
-import android.net.INetworkStatsSession;
 import android.net.Network;
 import android.net.NetworkRequest;
 import android.net.NetworkStats;
@@ -188,6 +177,7 @@
 import com.android.internal.os.SystemServerCpuThreadReader.SystemServiceCpuThreadTimes;
 import com.android.internal.util.CollectionUtils;
 import com.android.internal.util.FrameworkStatsLog;
+import com.android.net.module.util.NetworkStatsUtils;
 import com.android.role.RoleManagerLocal;
 import com.android.server.BinderCallsStatsService;
 import com.android.server.LocalManagerRegistry;
@@ -235,7 +225,7 @@
 import java.util.concurrent.ThreadLocalRandom;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
-import java.util.function.BiConsumer;
+import java.util.function.Function;
 
 /**
  * SystemService containing PullAtomCallbacks that are registered with statsd.
@@ -331,6 +321,7 @@
     private WifiManager mWifiManager;
     private TelephonyManager mTelephony;
     private SubscriptionManager mSubscriptionManager;
+    private NetworkStatsManager mNetworkStatsManager;
 
     @GuardedBy("mKernelWakelockLock")
     private KernelWakelockReader mKernelWakelockReader;
@@ -776,7 +767,7 @@
                 mContext.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
         mStatsSubscriptionsListener = new StatsSubscriptionsListener(mSubscriptionManager);
         mStorageManager = (StorageManager) mContext.getSystemService(StorageManager.class);
-
+        mNetworkStatsManager = mContext.getSystemService(NetworkStatsManager.class);
         // Initialize DiskIO
         mStoragedUidIoStatsReader = new StoragedUidIoStatsReader();
 
@@ -966,32 +957,6 @@
         registerOemManagedBytesTransfer();
     }
 
-    /**
-     * Return the {@code INetworkStatsSession} object that holds the necessary properties needed
-     * for the subsequent queries to {@link com.android.server.net.NetworkStatsService}. Or
-     * null if the service or binder cannot be obtained. Calling this method will trigger poll
-     * in NetworkStatsService with once per 15 seconds rate-limit, unless {@code bypassRateLimit}
-     * is set to true. This is needed in {@link #getUidNetworkStatsSnapshotForTemplate}, where
-     * bypassing the limit is necessary for perfd to supply realtime stats to developers looking at
-     * the network usage of their app.
-     */
-    @Nullable
-    private INetworkStatsSession getNetworkStatsSession(boolean bypassRateLimit) {
-        final INetworkStatsService networkStatsService =
-                INetworkStatsService.Stub.asInterface(
-                        ServiceManager.getService(Context.NETWORK_STATS_SERVICE));
-        if (networkStatsService == null) return null;
-
-        try {
-            return networkStatsService.openSessionForUsageStats(
-                    FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN | (bypassRateLimit ? FLAG_POLL_FORCE
-                            : FLAG_POLL_ON_OPEN), mContext.getOpPackageName());
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Cannot get NetworkStats session", e);
-            return null;
-        }
-    }
-
     private IThermalService getIThermalService() {
         synchronized (mThermalLock) {
             if (mThermalService == null) {
@@ -1122,8 +1087,8 @@
             case FrameworkStatsLog.WIFI_BYTES_TRANSFER: {
                 final NetworkStats stats = getUidNetworkStatsSnapshotForTransport(TRANSPORT_WIFI);
                 if (stats != null) {
-                    ret.add(new NetworkStatsExt(stats.groupedByUid(), new int[] {TRANSPORT_WIFI},
-                                    /*slicedByFgbg=*/false));
+                    ret.add(new NetworkStatsExt(sliceNetworkStatsByUid(stats),
+                            new int[] {TRANSPORT_WIFI}, /*slicedByFgbg=*/false));
                 }
                 break;
             }
@@ -1139,7 +1104,7 @@
                 final NetworkStats stats =
                         getUidNetworkStatsSnapshotForTransport(TRANSPORT_CELLULAR);
                 if (stats != null) {
-                    ret.add(new NetworkStatsExt(stats.groupedByUid(),
+                    ret.add(new NetworkStatsExt(sliceNetworkStatsByUid(stats),
                                     new int[] {TRANSPORT_CELLULAR}, /*slicedByFgbg=*/false));
                 }
                 break;
@@ -1155,9 +1120,10 @@
             }
             case FrameworkStatsLog.BYTES_TRANSFER_BY_TAG_AND_METERED: {
                 final NetworkStats wifiStats = getUidNetworkStatsSnapshotForTemplate(
-                        buildTemplateWifiWildcard(), /*includeTags=*/true);
+                        new NetworkTemplate.Builder(MATCH_WIFI).build(), /*includeTags=*/true);
                 final NetworkStats cellularStats = getUidNetworkStatsSnapshotForTemplate(
-                        buildTemplateMobileWildcard(), /*includeTags=*/true);
+                        new NetworkTemplate.Builder(MATCH_MOBILE)
+                        .setMeteredness(METERED_YES).build(), /*includeTags=*/true);
                 if (wifiStats != null && cellularStats != null) {
                     final NetworkStats stats = wifiStats.add(cellularStats);
                     ret.add(new NetworkStatsExt(sliceNetworkStatsByUidTagAndMetered(stats),
@@ -1229,23 +1195,19 @@
 
     private void addNetworkStats(int atomTag, @NonNull List<StatsEvent> ret,
             @NonNull NetworkStatsExt statsExt) {
-        int size = statsExt.stats.size();
-        final NetworkStats.Entry entry = new NetworkStats.Entry(); // For recycling
-        for (int j = 0; j < size; j++) {
-            statsExt.stats.getValues(j, entry);
+        for (NetworkStats.Entry entry : statsExt.stats) {
             StatsEvent statsEvent;
-
             if (statsExt.slicedByFgbg) {
                 // MobileBytesTransferByFgBg atom or WifiBytesTransferByFgBg atom.
                 statsEvent = FrameworkStatsLog.buildStatsEvent(
-                        atomTag, entry.uid,
-                        (entry.set > 0), entry.rxBytes, entry.rxPackets, entry.txBytes,
-                        entry.txPackets);
+                        atomTag, entry.getUid(),
+                        (entry.getSet() > 0), entry.getRxBytes(), entry.getRxPackets(),
+                        entry.getTxBytes(), entry.getTxPackets());
             } else {
                 // MobileBytesTransfer atom or WifiBytesTransfer atom.
                 statsEvent = FrameworkStatsLog.buildStatsEvent(
-                        atomTag, entry.uid, entry.rxBytes,
-                        entry.rxPackets, entry.txBytes, entry.txPackets);
+                        atomTag, entry.getUid(), entry.getRxBytes(),
+                        entry.getRxPackets(), entry.getTxBytes(), entry.getTxPackets());
             }
             ret.add(statsEvent);
         }
@@ -1253,13 +1215,12 @@
 
     private void addBytesTransferByTagAndMeteredAtoms(@NonNull NetworkStatsExt statsExt,
             @NonNull List<StatsEvent> pulledData) {
-        final NetworkStats.Entry entry = new NetworkStats.Entry(); // for recycling
-        for (int i = 0; i < statsExt.stats.size(); i++) {
-            statsExt.stats.getValues(i, entry);
+        for (NetworkStats.Entry entry : statsExt.stats) {
             pulledData.add(FrameworkStatsLog.buildStatsEvent(
-                    FrameworkStatsLog.BYTES_TRANSFER_BY_TAG_AND_METERED, entry.uid,
-                    entry.metered == NetworkStats.METERED_YES, entry.tag, entry.rxBytes,
-                    entry.rxPackets, entry.txBytes, entry.txPackets));
+                    FrameworkStatsLog.BYTES_TRANSFER_BY_TAG_AND_METERED, entry.getUid(),
+                    entry.getMetered() == NetworkStats.METERED_YES, entry.getTag(),
+                    entry.getRxBytes(), entry.getRxPackets(), entry.getTxBytes(),
+                    entry.getTxPackets()));
         }
     }
 
@@ -1274,12 +1235,11 @@
         // Report NR connected in 5G non-standalone mode, or if the RAT type is NR to begin with.
         final boolean isNR = is5GNsa || statsExt.ratType == TelephonyManager.NETWORK_TYPE_NR;
 
-        final NetworkStats.Entry entry = new NetworkStats.Entry(); // for recycling
-        for (int i = 0; i < statsExt.stats.size(); i++) {
-            statsExt.stats.getValues(i, entry);
+        for (NetworkStats.Entry entry : statsExt.stats) {
             pulledData.add(FrameworkStatsLog.buildStatsEvent(
-                    FrameworkStatsLog.DATA_USAGE_BYTES_TRANSFER, entry.set, entry.rxBytes,
-                    entry.rxPackets, entry.txBytes, entry.txPackets,
+                    FrameworkStatsLog.DATA_USAGE_BYTES_TRANSFER,
+                    entry.getSet(), entry.getRxBytes(), entry.getRxPackets(),
+                    entry.getTxBytes(), entry.getTxPackets(),
                     is5GNsa ? TelephonyManager.NETWORK_TYPE_LTE : statsExt.ratType,
                     // Fill information about subscription, these cannot be null since invalid data
                     // would be filtered when adding into subInfo list.
@@ -1293,38 +1253,35 @@
 
     private void addOemDataUsageBytesTransferAtoms(@NonNull NetworkStatsExt statsExt,
             @NonNull List<StatsEvent> pulledData) {
-        final NetworkStats.Entry entry = new NetworkStats.Entry(); // for recycling
         final int oemManaged = statsExt.oemManaged;
         for (final int transport : statsExt.transports) {
-            for (int i = 0; i < statsExt.stats.size(); i++) {
-                statsExt.stats.getValues(i, entry);
+            for (NetworkStats.Entry entry : statsExt.stats) {
                 pulledData.add(FrameworkStatsLog.buildStatsEvent(
-                        FrameworkStatsLog.OEM_MANAGED_BYTES_TRANSFER, entry.uid, (entry.set > 0),
-                        oemManaged, transport, entry.rxBytes, entry.rxPackets, entry.txBytes,
-                        entry.txPackets));
+                        FrameworkStatsLog.OEM_MANAGED_BYTES_TRANSFER, entry.getUid(),
+                        (entry.getSet() > 0), oemManaged, transport, entry.getRxBytes(),
+                        entry.getRxPackets(), entry.getTxBytes(), entry.getTxPackets()));
             }
         }
     }
 
     @NonNull private List<NetworkStatsExt> getDataUsageBytesTransferSnapshotForOemManaged() {
-        final int[] transports = new int[] {MATCH_ETHERNET, MATCH_MOBILE_WILDCARD,
-                MATCH_WIFI_WILDCARD};
-        final int[] oemManagedTypes = new int[] {OEM_PAID | OEM_PRIVATE, OEM_PAID, OEM_PRIVATE};
+        final int[] matchRules = new int[] {MATCH_ETHERNET, MATCH_MOBILE, MATCH_WIFI};
+        final int[] oemManagedTypes = new int[] {OEM_MANAGED_PAID | OEM_MANAGED_PRIVATE,
+                OEM_MANAGED_PAID, OEM_MANAGED_PRIVATE};
 
         final List<NetworkStatsExt> ret = new ArrayList<>();
 
-        for (final int transport : transports) {
+        for (final int matchRule : matchRules) {
             for (final int oemManaged : oemManagedTypes) {
-                /* A null subscriberId will set wildcard=true, since we aren't trying to select a
-                   specific ssid or subscriber. */
-                final NetworkTemplate template = new NetworkTemplate(transport,
-                        /*subscriberId=*/null, /*matchSubscriberIds=*/null, /*networkId=*/null,
-                        METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
-                        oemManaged);
+                // Subscriber Ids and Wifi Network Keys will not be set since the purpose is to
+                // slice statistics of different OEM managed networks among all network types.
+                // Thus, specifying networks through their identifiers are not needed.
+                final NetworkTemplate template = new NetworkTemplate.Builder(matchRule)
+                        .setOemManaged(oemManaged).build();
                 final NetworkStats stats = getUidNetworkStatsSnapshotForTemplate(template, true);
                 if (stats != null) {
                     ret.add(new NetworkStatsExt(sliceNetworkStatsByUidTagAndMetered(stats),
-                            new int[] {transport}, /*slicedByFgbg=*/true, /*slicedByTag=*/true,
+                            new int[] {matchRule}, /*slicedByFgbg=*/true, /*slicedByTag=*/true,
                             /*slicedByMetered=*/true, TelephonyManager.NETWORK_TYPE_UNKNOWN,
                             /*subInfo=*/null, oemManaged));
                 }
@@ -1338,10 +1295,18 @@
      * Create a snapshot of NetworkStats for a given transport.
      */
     @Nullable private NetworkStats getUidNetworkStatsSnapshotForTransport(int transport) {
-        final NetworkTemplate template = (transport == TRANSPORT_CELLULAR)
-                ? NetworkTemplate.buildTemplateMobileWithRatType(
-                /*subscriptionId=*/null, NETWORK_TYPE_ALL, METERED_YES)
-                : NetworkTemplate.buildTemplateWifiWildcard();
+        NetworkTemplate template = null;
+        switch (transport) {
+            case TRANSPORT_CELLULAR:
+                template = new NetworkTemplate.Builder(MATCH_MOBILE)
+                        .setMeteredness(METERED_YES).build();
+                break;
+            case TRANSPORT_WIFI:
+                template = new NetworkTemplate.Builder(MATCH_WIFI).build();
+                break;
+            default:
+                Log.wtf(TAG, "Unexpected transport.");
+        }
         return getUidNetworkStatsSnapshotForTemplate(template, /*includeTags=*/false);
     }
 
@@ -1357,22 +1322,32 @@
         final long currentTimeInMillis = MICROSECONDS.toMillis(SystemClock.currentTimeMicro());
         final long bucketDuration = Settings.Global.getLong(mContext.getContentResolver(),
                 NETSTATS_UID_BUCKET_DURATION, NETSTATS_UID_DEFAULT_BUCKET_DURATION_MS);
-        try {
-            // TODO (b/156313635): This is short-term hack to allow perfd gets updated networkStats
-            //  history when query in every second in order to show realtime statistics. However,
-            //  this is not a good long-term solution since NetworkStatsService will make frequent
-            //  I/O and also block main thread when polling.
-            //  Consider making perfd queries NetworkStatsService directly.
-            final NetworkStats stats = getNetworkStatsSession(template.getMatchRule()
-                    == NetworkTemplate.MATCH_WIFI_WILDCARD).getSummaryForAllUid(template,
-                    currentTimeInMillis - elapsedMillisSinceBoot - bucketDuration,
-                    currentTimeInMillis, includeTags);
-            return stats;
-        } catch (RemoteException | NullPointerException e) {
-            Slog.e(TAG, "Pulling netstats for template=" + template + " and includeTags="
-                    + includeTags  + " causes error", e);
+
+        // TODO (b/156313635): This is short-term hack to allow perfd gets updated networkStats
+        //  history when query in every second in order to show realtime statistics. However,
+        //  this is not a good long-term solution since NetworkStatsService will make frequent
+        //  I/O and also block main thread when polling.
+        //  Consider making perfd queries NetworkStatsService directly.
+        if (template.getMatchRule() == MATCH_WIFI && template.getSubscriberIds().isEmpty()) {
+            mNetworkStatsManager.forceUpdate();
         }
-        return null;
+
+        final android.app.usage.NetworkStats queryNonTaggedStats =
+                mNetworkStatsManager.querySummary(
+                template, currentTimeInMillis - elapsedMillisSinceBoot - bucketDuration,
+                currentTimeInMillis);
+
+        final NetworkStats nonTaggedStats =
+                NetworkStatsUtils.fromPublicNetworkStats(queryNonTaggedStats);
+        if (!includeTags) return nonTaggedStats;
+
+        final android.app.usage.NetworkStats queryTaggedStats =
+                mNetworkStatsManager.queryTaggedSummary(template,
+                currentTimeInMillis - elapsedMillisSinceBoot - bucketDuration,
+                currentTimeInMillis);
+        final NetworkStats taggedStats =
+                NetworkStatsUtils.fromPublicNetworkStats(queryTaggedStats);
+        return nonTaggedStats.add(taggedStats);
     }
 
     @NonNull private List<NetworkStatsExt> getDataUsageBytesTransferSnapshotForSub(
@@ -1380,8 +1355,10 @@
         final List<NetworkStatsExt> ret = new ArrayList<>();
         for (final int ratType : getAllCollapsedRatTypes()) {
             final NetworkTemplate template =
-                    buildTemplateMobileWithRatType(subInfo.subscriberId, ratType,
-                    METERED_YES);
+                    new NetworkTemplate.Builder(MATCH_MOBILE)
+                    .setSubscriberIds(Set.of(subInfo.subscriberId))
+                    .setRatType(ratType)
+                    .setMeteredness(METERED_YES).build();
             final NetworkStats stats =
                     getUidNetworkStatsSnapshotForTemplate(template, /*includeTags=*/false);
             if (stats != null) {
@@ -1394,27 +1371,51 @@
         return ret;
     }
 
+    @NonNull private NetworkStats sliceNetworkStatsByUid(@NonNull NetworkStats stats) {
+        return sliceNetworkStats(stats,
+                (entry) -> {
+                        return new NetworkStats.Entry(null /* IFACE_ALL */, entry.getUid(),
+                                NetworkStats.SET_ALL, NetworkStats.TAG_NONE,
+                                NetworkStats.METERED_ALL, NetworkStats.ROAMING_ALL,
+                                NetworkStats.DEFAULT_NETWORK_ALL,
+                                entry.getRxBytes(), entry.getRxPackets(),
+                                entry.getTxBytes(), entry.getTxPackets(), 0);
+                });
+    }
+
     @NonNull private NetworkStats sliceNetworkStatsByFgbg(@NonNull NetworkStats stats) {
         return sliceNetworkStats(stats,
-                (newEntry, oldEntry) -> {
-                    newEntry.set = oldEntry.set;
+                (entry) -> {
+                        return new NetworkStats.Entry(null /* IFACE_ALL */, NetworkStats.UID_ALL,
+                                entry.getSet(), NetworkStats.TAG_NONE,
+                                NetworkStats.METERED_ALL, NetworkStats.ROAMING_ALL,
+                                NetworkStats.DEFAULT_NETWORK_ALL,
+                                entry.getRxBytes(), entry.getRxPackets(),
+                                entry.getTxBytes(), entry.getTxPackets(), 0);
                 });
     }
 
     @NonNull private NetworkStats sliceNetworkStatsByUidAndFgbg(@NonNull NetworkStats stats) {
         return sliceNetworkStats(stats,
-                (newEntry, oldEntry) -> {
-                    newEntry.uid = oldEntry.uid;
-                    newEntry.set = oldEntry.set;
+                (entry) -> {
+                        return new NetworkStats.Entry(null /* IFACE_ALL */, entry.getUid(),
+                                entry.getSet(), NetworkStats.TAG_NONE,
+                                NetworkStats.METERED_ALL, NetworkStats.ROAMING_ALL,
+                                NetworkStats.DEFAULT_NETWORK_ALL,
+                                entry.getRxBytes(), entry.getRxPackets(),
+                                entry.getTxBytes(), entry.getTxPackets(), 0);
                 });
     }
 
     @NonNull private NetworkStats sliceNetworkStatsByUidTagAndMetered(@NonNull NetworkStats stats) {
         return sliceNetworkStats(stats,
-                (newEntry, oldEntry) -> {
-                    newEntry.uid = oldEntry.uid;
-                    newEntry.tag = oldEntry.tag;
-                    newEntry.metered = oldEntry.metered;
+                (entry) -> {
+                        return new NetworkStats.Entry(null /* IFACE_ALL */, entry.getUid(),
+                                NetworkStats.SET_ALL, entry.getTag(),
+                                entry.getMetered(), NetworkStats.ROAMING_ALL,
+                                NetworkStats.DEFAULT_NETWORK_ALL,
+                                entry.getRxBytes(), entry.getRxPackets(),
+                                entry.getTxBytes(), entry.getTxPackets(), 0);
                 });
     }
 
@@ -1424,46 +1425,31 @@
      *
      * This function iterates through each NetworkStats.Entry, sets its dimensions equal to the
      * default state (with the presumption that we don't want to slice on anything), and then
-     * applies the slicer lambda to allow users to control which dimensions to slice on. This is
-     * adapted from groupedByUid within NetworkStats.java
+     * applies the slicer lambda to allow users to control which dimensions to slice on.
      *
-     * @param slicer An operation taking into two parameters, new NetworkStats.Entry and old
-     *               NetworkStats.Entry, that should be used to copy state from the old to the new.
+     * @param slicer An operation taking one parameter, NetworkStats.Entry, that should be used to
+     *               get the state from entry to replace the default value.
      *               This is useful for slicing by particular dimensions. For example, if we wished
      *               to slice by uid and tag, we could write the following lambda:
-     *                  (new, old) -> {
-     *                          new.uid = old.uid;
-     *                          new.tag = old.tag;
+     *                  (entry) -> {
+     *                   return new NetworkStats.Entry(null, entry.getUid(),
+     *                           NetworkStats.SET_ALL, entry.getTag(),
+     *                           NetworkStats.METERED_ALL, NetworkStats.ROAMING_ALL,
+     *                           NetworkStats.DEFAULT_NETWORK_ALL,
+     *                           entry.getRxBytes(), entry.getRxPackets(),
+     *                           entry.getTxBytes(), entry.getTxPackets(), 0);
      *                  }
-     *               If no slicer is provided, the data is not sliced by any dimensions.
      * @return new NeworkStats object appropriately sliced
      */
     @NonNull private NetworkStats sliceNetworkStats(@NonNull NetworkStats stats,
-            @Nullable BiConsumer<NetworkStats.Entry, NetworkStats.Entry> slicer) {
-        final NetworkStats ret = new NetworkStats(stats.getElapsedRealtime(), 1);
-
-        final NetworkStats.Entry entry = new NetworkStats.Entry();
-        entry.uid = NetworkStats.UID_ALL;
-        entry.iface = NetworkStats.IFACE_ALL;
-        entry.set = NetworkStats.SET_ALL;
-        entry.tag = NetworkStats.TAG_NONE;
-        entry.metered = NetworkStats.METERED_ALL;
-        entry.roaming = NetworkStats.ROAMING_ALL;
-        entry.defaultNetwork = NetworkStats.DEFAULT_NETWORK_ALL;
-
-        final NetworkStats.Entry recycle = new NetworkStats.Entry(); // used for retrieving values
-        for (int i = 0; i < stats.size(); i++) {
-            stats.getValues(i, recycle);
+            @NonNull Function<NetworkStats.Entry, NetworkStats.Entry> slicer) {
+        NetworkStats ret = new NetworkStats(0, 1);
+        NetworkStats.Entry entry = new NetworkStats.Entry();
+        for (NetworkStats.Entry e : stats) {
             if (slicer != null) {
-                slicer.accept(entry, recycle);
+                entry = slicer.apply(e);
             }
-
-            entry.rxBytes = recycle.rxBytes;
-            entry.rxPackets = recycle.rxPackets;
-            entry.txBytes = recycle.txBytes;
-            entry.txPackets = recycle.txPackets;
-            // Operations purposefully omitted since we don't use them for statsd.
-            ret.combineValues(entry);
+            ret = ret.addEntry(entry);
         }
         return ret;
     }
diff --git a/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java b/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java
index 0f37450..e7d05b6 100644
--- a/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java
+++ b/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java
@@ -527,12 +527,13 @@
                     callback.onFailure();
                     return;
                 }
-                textClassifierServiceConsumer.accept(serviceState.mService);
+                consumeServiceNoExceptLocked(textClassifierServiceConsumer, serviceState.mService);
             } else {
                 serviceState.mPendingRequests.add(
                         new PendingRequest(
                                 methodName,
-                                () -> textClassifierServiceConsumer.accept(serviceState.mService),
+                                () -> consumeServiceNoExceptLocked(
+                                        textClassifierServiceConsumer, serviceState.mService),
                                 callback::onFailure, callback.asBinder(),
                                 this,
                                 serviceState,
@@ -541,6 +542,16 @@
         }
     }
 
+    private static void consumeServiceNoExceptLocked(
+            @NonNull ThrowingConsumer<ITextClassifierService> textClassifierServiceConsumer,
+            @Nullable ITextClassifierService service) {
+        try {
+            textClassifierServiceConsumer.accept(service);
+        } catch (RuntimeException | Error e) {
+            Slog.e(LOG_TAG, "Exception when consume textClassifierService: " + e);
+        }
+    }
+
     private static ITextClassifierCallback wrap(ITextClassifierCallback orig) {
         return new CallbackWrapper(orig);
     }
diff --git a/services/core/java/com/android/server/vcn/Vcn.java b/services/core/java/com/android/server/vcn/Vcn.java
index e0cc8e1..f29c40f 100644
--- a/services/core/java/com/android/server/vcn/Vcn.java
+++ b/services/core/java/com/android/server/vcn/Vcn.java
@@ -39,10 +39,13 @@
 import android.net.vcn.VcnGatewayConnectionConfig;
 import android.net.vcn.VcnManager.VcnErrorCode;
 import android.os.Handler;
+import android.os.HandlerExecutor;
 import android.os.Message;
 import android.os.ParcelUuid;
 import android.provider.Settings;
+import android.telephony.TelephonyCallback;
 import android.telephony.TelephonyManager;
+import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.Slog;
 
@@ -57,6 +60,7 @@
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
@@ -148,6 +152,10 @@
     @NonNull private final VcnContentResolver mContentResolver;
     @NonNull private final ContentObserver mMobileDataSettingsObserver;
 
+    @NonNull
+    private final Map<Integer, VcnUserMobileDataStateListener> mMobileDataStateListeners =
+            new ArrayMap<>();
+
     /**
      * Map containing all VcnGatewayConnections and their VcnGatewayConnectionConfigs.
      *
@@ -221,6 +229,9 @@
         // Update mIsMobileDataEnabled before starting handling of NetworkRequests.
         mIsMobileDataEnabled = getMobileDataStatus();
 
+        // Register mobile data state listeners.
+        updateMobileDataStateListeners();
+
         // Register to receive cached and future NetworkRequests
         mVcnContext.getVcnNetworkProvider().registerListener(mRequestListener);
     }
@@ -348,6 +359,12 @@
             gatewayConnection.teardownAsynchronously();
         }
 
+        // Unregister MobileDataStateListeners
+        for (VcnUserMobileDataStateListener listener : mMobileDataStateListeners.values()) {
+            getTelephonyManager().unregisterTelephonyCallback(listener);
+        }
+        mMobileDataStateListeners.clear();
+
         mCurrentStatus = VCN_STATUS_CODE_INACTIVE;
     }
 
@@ -454,11 +471,40 @@
             gatewayConnection.updateSubscriptionSnapshot(mLastSnapshot);
         }
 
+        updateMobileDataStateListeners();
+
         // Update the mobile data state after updating the subscription snapshot as a change in
         // subIds for a subGroup may affect the mobile data state.
         handleMobileDataToggled();
     }
 
+    private void updateMobileDataStateListeners() {
+        final Set<Integer> subIdsInGroup = mLastSnapshot.getAllSubIdsInGroup(mSubscriptionGroup);
+        final HandlerExecutor executor = new HandlerExecutor(this);
+
+        // Register new callbacks
+        for (int subId : subIdsInGroup) {
+            if (!mMobileDataStateListeners.containsKey(subId)) {
+                final VcnUserMobileDataStateListener listener =
+                        new VcnUserMobileDataStateListener();
+
+                getTelephonyManagerForSubid(subId).registerTelephonyCallback(executor, listener);
+                mMobileDataStateListeners.put(subId, listener);
+            }
+        }
+
+        // Unregister old callbacks
+        Iterator<Entry<Integer, VcnUserMobileDataStateListener>> iterator =
+                mMobileDataStateListeners.entrySet().iterator();
+        while (iterator.hasNext()) {
+            final Entry<Integer, VcnUserMobileDataStateListener> entry = iterator.next();
+            if (!subIdsInGroup.contains(entry.getKey())) {
+                getTelephonyManager().unregisterTelephonyCallback(entry.getValue());
+                iterator.remove();
+            }
+        }
+    }
+
     private void handleMobileDataToggled() {
         final boolean oldMobileDataEnabledStatus = mIsMobileDataEnabled;
         mIsMobileDataEnabled = getMobileDataStatus();
@@ -493,11 +539,8 @@
     }
 
     private boolean getMobileDataStatus() {
-        final TelephonyManager genericTelMan =
-                mVcnContext.getContext().getSystemService(TelephonyManager.class);
-
         for (int subId : mLastSnapshot.getAllSubIdsInGroup(mSubscriptionGroup)) {
-            if (genericTelMan.createForSubscriptionId(subId).isDataEnabled()) {
+            if (getTelephonyManagerForSubid(subId).isDataEnabled()) {
                 return true;
             }
         }
@@ -517,6 +560,14 @@
         return request.canBeSatisfiedBy(builder.build());
     }
 
+    private TelephonyManager getTelephonyManager() {
+        return mVcnContext.getContext().getSystemService(TelephonyManager.class);
+    }
+
+    private TelephonyManager getTelephonyManagerForSubid(int subid) {
+        return getTelephonyManager().createForSubscriptionId(subid);
+    }
+
     private String getLogPrefix() {
         return "["
                 + LogUtils.getHashedSubscriptionGroup(mSubscriptionGroup)
@@ -670,6 +721,16 @@
         }
     }
 
+    @VisibleForTesting(visibility = Visibility.PRIVATE)
+    class VcnUserMobileDataStateListener extends TelephonyCallback
+            implements TelephonyCallback.UserMobileDataStateListener {
+
+        @Override
+        public void onUserMobileDataStateChanged(boolean enabled) {
+            sendMessage(obtainMessage(MSG_EVENT_MOBILE_DATA_TOGGLED));
+        }
+    }
+
     /** External dependencies used by Vcn, for injection in tests */
     @VisibleForTesting(visibility = Visibility.PRIVATE)
     public static class Dependencies {
diff --git a/services/core/java/com/android/server/vcn/routeselection/NetworkPriorityClassifier.java b/services/core/java/com/android/server/vcn/routeselection/NetworkPriorityClassifier.java
index 6db25b7..c96c1ee 100644
--- a/services/core/java/com/android/server/vcn/routeselection/NetworkPriorityClassifier.java
+++ b/services/core/java/com/android/server/vcn/routeselection/NetworkPriorityClassifier.java
@@ -22,8 +22,6 @@
 import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
 import static android.net.vcn.VcnUnderlyingNetworkTemplate.MATCH_FORBIDDEN;
 import static android.net.vcn.VcnUnderlyingNetworkTemplate.MATCH_REQUIRED;
-import static android.net.vcn.VcnUnderlyingNetworkTemplate.NETWORK_QUALITY_ANY;
-import static android.net.vcn.VcnUnderlyingNetworkTemplate.NETWORK_QUALITY_OK;
 
 import static com.android.server.VcnManagementService.LOCAL_LOG;
 
@@ -47,6 +45,7 @@
 import com.android.server.vcn.VcnContext;
 
 import java.util.List;
+import java.util.Objects;
 import java.util.Set;
 
 /** @hide */
@@ -121,9 +120,10 @@
             TelephonySubscriptionSnapshot snapshot,
             UnderlyingNetworkRecord currentlySelected,
             PersistableBundle carrierConfig) {
-        // TODO: Check Network Quality reported by metric monitors/probers.
-
         final NetworkCapabilities caps = networkRecord.networkCapabilities;
+        final boolean isSelectedUnderlyingNetwork =
+                currentlySelected != null
+                        && Objects.equals(currentlySelected.network, networkRecord.network);
 
         final int meteredMatch = networkPriority.getMetered();
         final boolean isMetered = !caps.hasCapability(NET_CAPABILITY_NOT_METERED);
@@ -132,6 +132,23 @@
             return false;
         }
 
+        // Fails bandwidth requirements if either (a) less than exit threshold, or (b), not
+        // selected, but less than entry threshold
+        if (caps.getLinkUpstreamBandwidthKbps() < networkPriority.getMinExitUpstreamBandwidthKbps()
+                || (caps.getLinkUpstreamBandwidthKbps()
+                                < networkPriority.getMinEntryUpstreamBandwidthKbps()
+                        && !isSelectedUnderlyingNetwork)) {
+            return false;
+        }
+
+        if (caps.getLinkDownstreamBandwidthKbps()
+                        < networkPriority.getMinExitDownstreamBandwidthKbps()
+                || (caps.getLinkDownstreamBandwidthKbps()
+                                < networkPriority.getMinEntryDownstreamBandwidthKbps()
+                        && !isSelectedUnderlyingNetwork)) {
+            return false;
+        }
+
         if (vcnContext.isInTestMode() && caps.hasTransport(TRANSPORT_TEST)) {
             return true;
         }
@@ -172,8 +189,7 @@
         }
 
         // TODO: Move the Network Quality check to the network metric monitor framework.
-        if (networkPriority.getNetworkQuality()
-                > getWifiQuality(networkRecord, currentlySelected, carrierConfig)) {
+        if (!isWifiRssiAcceptable(networkRecord, currentlySelected, carrierConfig)) {
             return false;
         }
 
@@ -185,7 +201,7 @@
         return true;
     }
 
-    private static int getWifiQuality(
+    private static boolean isWifiRssiAcceptable(
             UnderlyingNetworkRecord networkRecord,
             UnderlyingNetworkRecord currentlySelected,
             PersistableBundle carrierConfig) {
@@ -196,14 +212,14 @@
 
         if (isSelectedNetwork
                 && caps.getSignalStrength() >= getWifiExitRssiThreshold(carrierConfig)) {
-            return NETWORK_QUALITY_OK;
+            return true;
         }
 
         if (caps.getSignalStrength() >= getWifiEntryRssiThreshold(carrierConfig)) {
-            return NETWORK_QUALITY_OK;
+            return true;
         }
 
-        return NETWORK_QUALITY_ANY;
+        return false;
     }
 
     @VisibleForTesting(visibility = Visibility.PRIVATE)
diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp
index e7005da..e48b5e1 100644
--- a/services/core/jni/Android.bp
+++ b/services/core/jni/Android.bp
@@ -141,8 +141,8 @@
         "libutils",
         "libhwui",
         "libbpf_android",
-        "libnetdbpf",
         "libnetdutils",
+        "libnetworkstats",
         "libpsi",
         "libdataloader",
         "libincfs",
diff --git a/services/core/jni/com_android_server_UsbAlsaJackDetector.cpp b/services/core/jni/com_android_server_UsbAlsaJackDetector.cpp
index ccb4f59..cba54b3 100644
--- a/services/core/jni/com_android_server_UsbAlsaJackDetector.cpp
+++ b/services/core/jni/com_android_server_UsbAlsaJackDetector.cpp
@@ -25,7 +25,6 @@
 
 #include <stdio.h>
 #include <string.h>
-#include <asm/byteorder.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
diff --git a/services/core/jni/com_android_server_UsbDescriptorParser.cpp b/services/core/jni/com_android_server_UsbDescriptorParser.cpp
index d29d3fc..9917bcb 100644
--- a/services/core/jni/com_android_server_UsbDescriptorParser.cpp
+++ b/services/core/jni/com_android_server_UsbDescriptorParser.cpp
@@ -15,16 +15,14 @@
  */
 
 #define LOG_TAG "UsbHostManagerJNI"
-#include "utils/Log.h"
-
+#include <nativehelper/JNIHelp.h>
 #include <stdlib.h>
+#include <usbhost/usbhost.h>
+#include <usbhost/usbhost_jni.h>
 
 #include "jni.h"
-#include <nativehelper/JNIHelp.h>
+#include "utils/Log.h"
 
-#include <usbhost/usbhost.h>
-
-#define MAX_DESCRIPTORS_LENGTH 4096
 static const int USB_CONTROL_TRANSFER_TIMEOUT_MS = 200;
 
 // com.android.server.usb.descriptors
@@ -41,26 +39,9 @@
     }
 
     int fd = usb_device_get_fd(device);
-    if (fd < 0) {
-        usb_device_close(device);
-        return NULL;
-    }
-
-    // from android_hardware_UsbDeviceConnection_get_desc()
-    jbyte buffer[MAX_DESCRIPTORS_LENGTH];
-    lseek(fd, 0, SEEK_SET);
-    int numBytes = read(fd, buffer, sizeof(buffer));
-    jbyteArray ret = NULL;
+    jbyteArray descriptors = usb_jni_read_descriptors(env, fd);
     usb_device_close(device);
-
-    if (numBytes > 0) {
-        ret = env->NewByteArray(numBytes);
-        env->SetByteArrayRegion(ret, 0, numBytes, buffer);
-    } else {
-        ALOGE("error reading descriptors\n");
-    }
-
-    return ret;
+    return descriptors;
 }
 
 jstring JNICALL Java_com_android_server_usb_descriptors_UsbDescriptorParser_getDescriptorString_1native(
diff --git a/services/core/jni/com_android_server_UsbDeviceManager.cpp b/services/core/jni/com_android_server_UsbDeviceManager.cpp
index 3ab5920..0a9ce2f 100644
--- a/services/core/jni/com_android_server_UsbDeviceManager.cpp
+++ b/services/core/jni/com_android_server_UsbDeviceManager.cpp
@@ -25,7 +25,6 @@
 #include "MtpDescriptors.h"
 
 #include <stdio.h>
-#include <asm/byteorder.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
diff --git a/services/core/jni/com_android_server_UsbHostManager.cpp b/services/core/jni/com_android_server_UsbHostManager.cpp
index a629b69..e29d2ca 100644
--- a/services/core/jni/com_android_server_UsbHostManager.cpp
+++ b/services/core/jni/com_android_server_UsbHostManager.cpp
@@ -23,7 +23,6 @@
 #include "android_runtime/Log.h"
 
 #include <stdio.h>
-#include <asm/byteorder.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
@@ -31,8 +30,6 @@
 
 #include <usbhost/usbhost.h>
 
-#define MAX_DESCRIPTORS_LENGTH 4096
-
 namespace android
 {
 
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java b/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java
index 37a84f3..1c9d584 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java
@@ -32,6 +32,7 @@
 import android.app.admin.DevicePolicyManager;
 import android.app.admin.FactoryResetProtectionPolicy;
 import android.app.admin.PasswordPolicy;
+import android.app.admin.PreferentialNetworkServiceConfig;
 import android.graphics.Color;
 import android.os.Bundle;
 import android.os.PersistableBundle;
@@ -294,6 +295,8 @@
     public boolean mAdminCanGrantSensorsPermissions;
     public boolean mPreferentialNetworkServiceEnabled =
             DevicePolicyManager.PREFERENTIAL_NETWORK_SERVICE_ENABLED_DEFAULT;
+    public PreferentialNetworkServiceConfig mPreferentialNetworkServiceConfig =
+            PreferentialNetworkServiceConfig.DEFAULT;
 
     private static final boolean USB_DATA_SIGNALING_ENABLED_DEFAULT = true;
     boolean mUsbDataSignalingEnabled = USB_DATA_SIGNALING_ENABLED_DEFAULT;
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 0792d9b..564b608 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -109,6 +109,8 @@
 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
 import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_DEFAULT;
 import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE;
+import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK;
+import static android.net.NetworkCapabilities.NET_ENTERPRISE_ID_1;
 import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
 import static android.provider.Settings.Global.PRIVATE_DNS_SPECIFIER;
 import static android.provider.Settings.Secure.USER_SETUP_COMPLETE;
@@ -179,6 +181,7 @@
 import android.app.admin.ParcelableGranteeMap;
 import android.app.admin.PasswordMetrics;
 import android.app.admin.PasswordPolicy;
+import android.app.admin.PreferentialNetworkServiceConfig;
 import android.app.admin.SecurityLog;
 import android.app.admin.SecurityLog.SecurityEvent;
 import android.app.admin.StartInstallingUpdateCallback;
@@ -231,6 +234,7 @@
 import android.net.ConnectivityManager;
 import android.net.ConnectivitySettingsManager;
 import android.net.IIpConnectivityMetrics;
+import android.net.ProfileNetworkPreference;
 import android.net.ProxyInfo;
 import android.net.Uri;
 import android.net.VpnManager;
@@ -3276,14 +3280,14 @@
         updatePermissionPolicyCache(userId);
         updateAdminCanGrantSensorsPermissionCache(userId);
 
-        final boolean preferentialNetworkServiceEnabled;
+        final PreferentialNetworkServiceConfig preferentialNetworkServiceConfig;
         synchronized (getLockObject()) {
             ActiveAdmin owner = getDeviceOrProfileOwnerAdminLocked(userId);
-            preferentialNetworkServiceEnabled = owner != null
-                    ? owner.mPreferentialNetworkServiceEnabled
-                             : DevicePolicyManager.PREFERENTIAL_NETWORK_SERVICE_ENABLED_DEFAULT;
+            preferentialNetworkServiceConfig = owner != null
+                    ? owner.mPreferentialNetworkServiceConfig
+                    : PreferentialNetworkServiceConfig.DEFAULT;
         }
-        updateNetworkPreferenceForUser(userId, preferentialNetworkServiceEnabled);
+        updateNetworkPreferenceForUser(userId, preferentialNetworkServiceConfig);
 
         startOwnerService(userId, "start-user");
     }
@@ -3300,7 +3304,7 @@
 
     @Override
     void handleStopUser(int userId) {
-        updateNetworkPreferenceForUser(userId, false);
+        updateNetworkPreferenceForUser(userId, PreferentialNetworkServiceConfig.DEFAULT);
         stopOwnerService(userId, "stop-user");
     }
 
@@ -11844,7 +11848,7 @@
         final CallerIdentity caller = getCallerIdentity();
         Preconditions.checkCallAuthorization(isProfileOwner(caller),
                 "Caller is not profile owner;"
-                        + " only profile owner may control the preferntial network service");
+                        + " only profile owner may control the preferential network service");
         synchronized (getLockObject()) {
             final ActiveAdmin requiredAdmin = getProfileOwnerAdminLocked(
                     caller.getUserId());
@@ -11881,6 +11885,47 @@
     }
 
     @Override
+    public void setPreferentialNetworkServiceConfig(
+            PreferentialNetworkServiceConfig preferentialNetworkServiceConfig) {
+        if (!mHasFeature) {
+            return;
+        }
+        final CallerIdentity caller = getCallerIdentity();
+        Preconditions.checkCallAuthorization(isProfileOwner(caller),
+                "Caller is not profile owner;"
+                        + " only profile owner may control the preferential network service");
+        synchronized (getLockObject()) {
+            final ActiveAdmin requiredAdmin = getProfileOwnerAdminLocked(
+                    caller.getUserId());
+            if (!requiredAdmin.mPreferentialNetworkServiceConfig.equals(
+                    preferentialNetworkServiceConfig)) {
+                requiredAdmin.mPreferentialNetworkServiceConfig = preferentialNetworkServiceConfig;
+                saveSettingsLocked(caller.getUserId());
+            }
+        }
+        updateNetworkPreferenceForUser(caller.getUserId(), preferentialNetworkServiceConfig);
+        DevicePolicyEventLogger
+                .createEvent(DevicePolicyEnums.SET_PREFERENTIAL_NETWORK_SERVICE_ENABLED)
+                .setBoolean(preferentialNetworkServiceConfig.isEnabled())
+                .write();
+    }
+
+    @Override
+    public PreferentialNetworkServiceConfig getPreferentialNetworkServiceConfig() {
+        if (!mHasFeature) {
+            return PreferentialNetworkServiceConfig.DEFAULT;
+        }
+
+        final CallerIdentity caller = getCallerIdentity();
+        Preconditions.checkCallAuthorization(isProfileOwner(caller),
+                "Caller is not profile owner");
+        synchronized (getLockObject()) {
+            final ActiveAdmin requiredAdmin = getProfileOwnerAdminLocked(caller.getUserId());
+            return requiredAdmin.mPreferentialNetworkServiceConfig;
+        }
+    }
+
+    @Override
     public void setLockTaskPackages(ComponentName who, String[] packages)
             throws SecurityException {
         Objects.requireNonNull(who, "ComponentName is null");
@@ -17536,12 +17581,53 @@
         if (!isManagedProfile(userId)) {
             return;
         }
-        int networkPreference = preferentialNetworkServiceEnabled
-                ? PROFILE_NETWORK_PREFERENCE_ENTERPRISE : PROFILE_NETWORK_PREFERENCE_DEFAULT;
+        ProfileNetworkPreference.Builder preferenceBuilder =
+                new ProfileNetworkPreference.Builder();
+        if (preferentialNetworkServiceEnabled) {
+            preferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE);
+            preferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1);
+        } else {
+            preferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_DEFAULT);
+        }
+        List<ProfileNetworkPreference> preferences = new ArrayList<>();
+        preferences.add(preferenceBuilder.build());
         mInjector.binderWithCleanCallingIdentity(() ->
-                mInjector.getConnectivityManager().setProfileNetworkPreference(
-                        UserHandle.of(userId),
-                        networkPreference,
+                mInjector.getConnectivityManager().setProfileNetworkPreferences(
+                        UserHandle.of(userId), preferences,
+                        null /* executor */, null /* listener */));
+    }
+
+    private void updateNetworkPreferenceForUser(int userId,
+            PreferentialNetworkServiceConfig preferentialNetworkServiceConfig) {
+        if (!isManagedProfile(userId)) {
+            return;
+        }
+        ProfileNetworkPreference.Builder preferenceBuilder =
+                new ProfileNetworkPreference.Builder();
+        if (preferentialNetworkServiceConfig.isEnabled()) {
+            if (preferentialNetworkServiceConfig.isFallbackToDefaultConnectionAllowed()) {
+                preferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE);
+            } else {
+                preferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK);
+            }
+        } else {
+            preferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_DEFAULT);
+        }
+        List<Integer> allowedUids = Arrays.stream(
+                preferentialNetworkServiceConfig.getIncludedUids()).boxed().collect(
+                        Collectors.toList());
+        List<Integer> excludedUids = Arrays.stream(
+                preferentialNetworkServiceConfig.getExcludedUids()).boxed().collect(
+                Collectors.toList());
+        preferenceBuilder.setIncludedUids(allowedUids);
+        preferenceBuilder.setExcludedUids(excludedUids);
+        preferenceBuilder.setPreferenceEnterpriseId(
+                preferentialNetworkServiceConfig.getNetworkId());
+        List<ProfileNetworkPreference> preferences = new ArrayList<>();
+        preferences.add(preferenceBuilder.build());
+        mInjector.binderWithCleanCallingIdentity(() ->
+                mInjector.getConnectivityManager().setProfileNetworkPreferences(
+                        UserHandle.of(userId), preferences,
                         null /* executor */, null /* listener */));
     }
 
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 2aee778..710a9cf 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -54,6 +54,7 @@
 import android.net.ConnectivityManager;
 import android.net.ConnectivityModuleConnector;
 import android.net.NetworkStackClient;
+import android.net.TrafficStats;
 import android.os.BaseBundle;
 import android.os.Binder;
 import android.os.Build;
@@ -1338,7 +1339,6 @@
         VcnManagementService vcnManagement = null;
         NetworkStatsService networkStats = null;
         NetworkPolicyManagerService networkPolicy = null;
-        NsdService serviceDiscovery = null;
         WindowManagerService wm = null;
         SerialService serial = null;
         NetworkTimeUpdateService networkTimeUpdater = null;
@@ -1837,8 +1837,9 @@
 
             t.traceBegin("StartNetworkStatsService");
             try {
-                networkStats = NetworkStatsService.create(context, networkManagement);
+                networkStats = NetworkStatsService.create(context);
                 ServiceManager.addService(Context.NETWORK_STATS_SERVICE, networkStats);
+                TrafficStats.init(context);
             } catch (Throwable e) {
                 reportWtf("starting NetworkStats Service", e);
             }
@@ -1941,16 +1942,6 @@
             }
             t.traceEnd();
 
-            t.traceBegin("StartNsdService");
-            try {
-                serviceDiscovery = NsdService.create(context);
-                ServiceManager.addService(
-                        Context.NSD_SERVICE, serviceDiscovery);
-            } catch (Throwable e) {
-                reportWtf("starting Service Discovery Service", e);
-            }
-            t.traceEnd();
-
             t.traceBegin("StartSystemUpdateManagerService");
             try {
                 ServiceManager.addService(Context.SYSTEM_UPDATE_SERVICE,
diff --git a/services/tests/servicestests/Android.bp b/services/tests/servicestests/Android.bp
index f182b66..428327c 100644
--- a/services/tests/servicestests/Android.bp
+++ b/services/tests/servicestests/Android.bp
@@ -25,6 +25,7 @@
         "test-apps/JobTestApp/src/**/*.java",
 
         "test-apps/SuspendTestApp/src/**/*.java",
+	":service-bluetooth-tests-sources", // TODO(b/214988855) : Remove once framework-bluetooth jar is ready
     ],
     static_libs: [
         "frameworks-base-testutils",
diff --git a/services/tests/servicestests/AndroidManifest.xml b/services/tests/servicestests/AndroidManifest.xml
index bcb2cf8..187b012 100644
--- a/services/tests/servicestests/AndroidManifest.xml
+++ b/services/tests/servicestests/AndroidManifest.xml
@@ -93,6 +93,7 @@
     <uses-permission android:name="android.permission.CONTROL_DEVICE_STATE"/>
     <uses-permission android:name="android.permission.READ_PROJECTION_STATE"/>
     <uses-permission android:name="android.permission.KILL_UID"/>
+    <uses-permission android:name="android.permission.MAINLINE_NETWORK_STACK"/>
     <uses-permission
         android:name="android.permission.OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD"/>
 
diff --git a/services/tests/servicestests/src/com/android/server/BluetoothAirplaneModeListenerTest.java b/services/tests/servicestests/src/com/android/server/BluetoothAirplaneModeListenerTest.java
deleted file mode 100644
index a1d4c20..0000000
--- a/services/tests/servicestests/src/com/android/server/BluetoothAirplaneModeListenerTest.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server;
-
-import static org.mockito.Mockito.*;
-
-import android.bluetooth.BluetoothAdapter;
-import android.content.Context;
-import android.os.Looper;
-import android.provider.Settings;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.MediumTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-
-@MediumTest
-@RunWith(AndroidJUnit4.class)
-public class BluetoothAirplaneModeListenerTest {
-    private Context mContext;
-    private BluetoothAirplaneModeListener mBluetoothAirplaneModeListener;
-    private BluetoothAdapter mBluetoothAdapter;
-    private BluetoothModeChangeHelper mHelper;
-
-    @Mock BluetoothManagerService mBluetoothManagerService;
-
-    @Before
-    public void setUp() throws Exception {
-        mContext = InstrumentationRegistry.getTargetContext();
-
-        mHelper = mock(BluetoothModeChangeHelper.class);
-        when(mHelper.getSettingsInt(BluetoothAirplaneModeListener.TOAST_COUNT))
-                .thenReturn(BluetoothAirplaneModeListener.MAX_TOAST_COUNT);
-        doNothing().when(mHelper).setSettingsInt(anyString(), anyInt());
-        doNothing().when(mHelper).showToastMessage();
-        doNothing().when(mHelper).onAirplaneModeChanged(any(BluetoothManagerService.class));
-
-        mBluetoothAirplaneModeListener = new BluetoothAirplaneModeListener(
-                    mBluetoothManagerService, Looper.getMainLooper(), mContext);
-        mBluetoothAirplaneModeListener.start(mHelper);
-    }
-
-    @Test
-    public void testIgnoreOnAirplanModeChange() {
-        Assert.assertFalse(mBluetoothAirplaneModeListener.shouldSkipAirplaneModeChange());
-
-        when(mHelper.isBluetoothOn()).thenReturn(true);
-        Assert.assertFalse(mBluetoothAirplaneModeListener.shouldSkipAirplaneModeChange());
-
-        when(mHelper.isMediaProfileConnected()).thenReturn(true);
-        Assert.assertFalse(mBluetoothAirplaneModeListener.shouldSkipAirplaneModeChange());
-
-        when(mHelper.isAirplaneModeOn()).thenReturn(true);
-        Assert.assertTrue(mBluetoothAirplaneModeListener.shouldSkipAirplaneModeChange());
-    }
-
-    @Test
-    public void testHandleAirplaneModeChange_InvokeAirplaneModeChanged() {
-        mBluetoothAirplaneModeListener.handleAirplaneModeChange();
-        verify(mHelper).onAirplaneModeChanged(mBluetoothManagerService);
-    }
-
-    @Test
-    public void testHandleAirplaneModeChange_NotInvokeAirplaneModeChanged_NotPopToast() {
-        mBluetoothAirplaneModeListener.mToastCount = BluetoothAirplaneModeListener.MAX_TOAST_COUNT;
-        when(mHelper.isBluetoothOn()).thenReturn(true);
-        when(mHelper.isMediaProfileConnected()).thenReturn(true);
-        when(mHelper.isAirplaneModeOn()).thenReturn(true);
-        mBluetoothAirplaneModeListener.handleAirplaneModeChange();
-
-        verify(mHelper).setSettingsInt(Settings.Global.BLUETOOTH_ON,
-                BluetoothManagerService.BLUETOOTH_ON_AIRPLANE);
-        verify(mHelper, times(0)).showToastMessage();
-        verify(mHelper, times(0)).onAirplaneModeChanged(mBluetoothManagerService);
-    }
-
-    @Test
-    public void testHandleAirplaneModeChange_NotInvokeAirplaneModeChanged_PopToast() {
-        mBluetoothAirplaneModeListener.mToastCount = 0;
-        when(mHelper.isBluetoothOn()).thenReturn(true);
-        when(mHelper.isMediaProfileConnected()).thenReturn(true);
-        when(mHelper.isAirplaneModeOn()).thenReturn(true);
-        mBluetoothAirplaneModeListener.handleAirplaneModeChange();
-
-        verify(mHelper).setSettingsInt(Settings.Global.BLUETOOTH_ON,
-                BluetoothManagerService.BLUETOOTH_ON_AIRPLANE);
-        verify(mHelper).showToastMessage();
-        verify(mHelper, times(0)).onAirplaneModeChanged(mBluetoothManagerService);
-    }
-
-    @Test
-    public void testIsPopToast_PopToast() {
-        mBluetoothAirplaneModeListener.mToastCount = 0;
-        Assert.assertTrue(mBluetoothAirplaneModeListener.shouldPopToast());
-        verify(mHelper).setSettingsInt(BluetoothAirplaneModeListener.TOAST_COUNT, 1);
-    }
-
-    @Test
-    public void testIsPopToast_NotPopToast() {
-        mBluetoothAirplaneModeListener.mToastCount = BluetoothAirplaneModeListener.MAX_TOAST_COUNT;
-        Assert.assertFalse(mBluetoothAirplaneModeListener.shouldPopToast());
-        verify(mHelper, times(0)).setSettingsInt(anyString(), anyInt());
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
index 3ac30d02..3511fc1 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -37,7 +37,11 @@
 import static android.app.admin.DevicePolicyManager.WIPE_EUICC;
 import static android.app.admin.PasswordMetrics.computeForPasswordOrPin;
 import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE;
+import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_DEFAULT;
+import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE;
+import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK;
 import static android.net.InetAddresses.parseNumericAddress;
+import static android.net.NetworkCapabilities.NET_ENTERPRISE_ID_1;
 
 import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_NONE;
 import static com.android.internal.widget.LockPatternUtils.EscrowTokenStateChangeCallback;
@@ -87,6 +91,7 @@
 import android.app.admin.DevicePolicyManagerLiteInternal;
 import android.app.admin.FactoryResetProtectionPolicy;
 import android.app.admin.PasswordMetrics;
+import android.app.admin.PreferentialNetworkServiceConfig;
 import android.app.admin.SystemUpdatePolicy;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
@@ -99,7 +104,7 @@
 import android.content.pm.UserInfo;
 import android.graphics.Color;
 import android.hardware.usb.UsbManager;
-import android.net.ConnectivityManager;
+import android.net.ProfileNetworkPreference;
 import android.net.Uri;
 import android.os.Build.VERSION_CODES;
 import android.os.Bundle;
@@ -4044,12 +4049,15 @@
         mServiceContext.permissions.add(permission.INTERACT_ACROSS_USERS_FULL);
 
         dpms.handleStartUser(managedProfileUserId);
-        verify(getServices().connectivityManager, times(1)).setProfileNetworkPreference(
-                eq(UserHandle.of(managedProfileUserId)),
-                anyInt(),
-                any(),
-                any()
-        );
+        ProfileNetworkPreference preferenceDetails =
+                new ProfileNetworkPreference.Builder()
+                .setPreference(PROFILE_NETWORK_PREFERENCE_DEFAULT)
+                .build();
+        List<ProfileNetworkPreference> preferences = new ArrayList<>();
+        preferences.add(preferenceDetails);
+        verify(getServices().connectivityManager, times(1))
+                .setProfileNetworkPreferences(UserHandle.of(managedProfileUserId), preferences,
+                null, null);
     }
 
     @Test
@@ -4061,12 +4069,15 @@
         mServiceContext.permissions.add(permission.INTERACT_ACROSS_USERS_FULL);
 
         dpms.handleStopUser(managedProfileUserId);
-        verify(getServices().connectivityManager, times(1)).setProfileNetworkPreference(
-                eq(UserHandle.of(managedProfileUserId)),
-                eq(ConnectivityManager.PROFILE_NETWORK_PREFERENCE_DEFAULT),
-                any(),
-                any()
-        );
+        ProfileNetworkPreference preferenceDetails =
+                new ProfileNetworkPreference.Builder()
+                        .setPreference(PROFILE_NETWORK_PREFERENCE_DEFAULT)
+                        .build();
+        List<ProfileNetworkPreference> preferences = new ArrayList<>();
+        preferences.add(preferenceDetails);
+        verify(getServices().connectivityManager, times(1))
+                .setProfileNetworkPreferences(UserHandle.of(managedProfileUserId), preferences,
+                        null, null);
     }
 
     @Test
@@ -4084,21 +4095,188 @@
 
         dpm.setPreferentialNetworkServiceEnabled(false);
         assertThat(dpm.isPreferentialNetworkServiceEnabled()).isFalse();
-        verify(getServices().connectivityManager, times(1)).setProfileNetworkPreference(
-                eq(UserHandle.of(managedProfileUserId)),
-                eq(ConnectivityManager.PROFILE_NETWORK_PREFERENCE_DEFAULT),
-                any(),
-                any()
-        );
+
+        ProfileNetworkPreference preferenceDetails =
+                new ProfileNetworkPreference.Builder()
+                        .setPreference(PROFILE_NETWORK_PREFERENCE_DEFAULT)
+                        .build();
+        List<ProfileNetworkPreference> preferences = new ArrayList<>();
+        preferences.add(preferenceDetails);
+        verify(getServices().connectivityManager, times(1))
+                .setProfileNetworkPreferences(UserHandle.of(managedProfileUserId), preferences,
+                        null, null);
 
         dpm.setPreferentialNetworkServiceEnabled(true);
         assertThat(dpm.isPreferentialNetworkServiceEnabled()).isTrue();
-        verify(getServices().connectivityManager, times(1)).setProfileNetworkPreference(
-                eq(UserHandle.of(managedProfileUserId)),
-                eq(ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE),
-                any(),
-                any()
-        );
+
+        ProfileNetworkPreference preferenceDetails2 =
+                new ProfileNetworkPreference.Builder()
+                        .setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE)
+                        .setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1)
+                        .build();
+        List<ProfileNetworkPreference> preferences2 = new ArrayList<>();
+        preferences2.add(preferenceDetails);
+        verify(getServices().connectivityManager, times(1))
+                .setProfileNetworkPreferences(UserHandle.of(managedProfileUserId), preferences2,
+                        null, null);
+    }
+
+    @Test
+    public void testSetPreferentialNetworkServiceConfig_noProfileOwner() throws Exception {
+        assertExpectException(SecurityException.class, null,
+                () -> dpm.setPreferentialNetworkServiceConfig(
+                        PreferentialNetworkServiceConfig.DEFAULT));
+    }
+
+    @Test
+    public void testIsPreferentialNetworkServiceEnabled_noProfileOwner() throws Exception {
+        assertExpectException(SecurityException.class, null,
+                () -> dpm.isPreferentialNetworkServiceEnabled());
+    }
+
+    @Test
+    public void testSetPreferentialNetworkServiceConfig_invalidConfig() throws Exception {
+        final int managedProfileUserId = 15;
+        final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436);
+        addManagedProfile(admin1, managedProfileAdminUid, admin1);
+        mContext.binder.callingUid = managedProfileAdminUid;
+
+        PreferentialNetworkServiceConfig.Builder preferentialNetworkServiceConfigBuilder =
+                new PreferentialNetworkServiceConfig.Builder();
+        assertExpectException(NullPointerException.class, null,
+                () -> preferentialNetworkServiceConfigBuilder.setIncludedUids(null));
+        assertExpectException(NullPointerException.class, null,
+                () -> preferentialNetworkServiceConfigBuilder.setExcludedUids(null));
+        assertExpectException(IllegalArgumentException.class, null,
+                () -> preferentialNetworkServiceConfigBuilder.setNetworkId(6));
+        int[] includedUids = new int[]{1, 2};
+        int[] excludedUids = new int[]{3, 4};
+        preferentialNetworkServiceConfigBuilder.setIncludedUids(includedUids);
+        preferentialNetworkServiceConfigBuilder.setExcludedUids(excludedUids);
+
+        assertExpectException(IllegalStateException.class, null,
+                () -> preferentialNetworkServiceConfigBuilder.build());
+    }
+
+    @Test
+    public void testSetPreferentialNetworkServiceConfig_defaultPreference() throws Exception {
+        final int managedProfileUserId = 15;
+        final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436);
+        addManagedProfile(admin1, managedProfileAdminUid, admin1);
+        mContext.binder.callingUid = managedProfileAdminUid;
+
+        dpm.setPreferentialNetworkServiceConfig(PreferentialNetworkServiceConfig.DEFAULT);
+        assertThat(dpm.isPreferentialNetworkServiceEnabled()).isFalse();
+        assertThat(dpm.getPreferentialNetworkServiceConfig()
+                .isEnabled()).isFalse();
+
+        ProfileNetworkPreference preferenceDetails =
+                new ProfileNetworkPreference.Builder()
+                        .setPreference(PROFILE_NETWORK_PREFERENCE_DEFAULT)
+                        .build();
+        List<ProfileNetworkPreference> preferences = new ArrayList<>();
+        preferences.add(preferenceDetails);
+        verify(getServices().connectivityManager, times(1))
+                .setProfileNetworkPreferences(UserHandle.of(managedProfileUserId), preferences,
+                        null, null);
+    }
+
+    @Test
+    public void testSetPreferentialNetworkServiceConfig_enterprisePreference() throws Exception {
+        PreferentialNetworkServiceConfig preferentialNetworkServiceConfigEnabled =
+                (new PreferentialNetworkServiceConfig.Builder())
+                        .setEnabled(true)
+                        .setNetworkId(NET_ENTERPRISE_ID_1)
+                        .build();
+
+        final int managedProfileUserId = 15;
+        final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436);
+        addManagedProfile(admin1, managedProfileAdminUid, admin1);
+        mContext.binder.callingUid = managedProfileAdminUid;
+
+        dpm.setPreferentialNetworkServiceConfig(preferentialNetworkServiceConfigEnabled);
+        assertThat(dpm.getPreferentialNetworkServiceConfig()
+                .isEnabled()).isTrue();
+        ProfileNetworkPreference preferenceDetails =
+                new ProfileNetworkPreference.Builder()
+                        .setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE)
+                        .setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1)
+                        .build();
+        List<ProfileNetworkPreference> preferences = new ArrayList<>();
+        preferences.add(preferenceDetails);
+        verify(getServices().connectivityManager, times(1))
+                .setProfileNetworkPreferences(UserHandle.of(managedProfileUserId), preferences,
+                        null, null);
+    }
+
+    @Test
+    public void testSetPreferentialNetworkServiceConfig_enterprisePreferenceIncludedUids()
+            throws Exception {
+        final int managedProfileUserId = 15;
+        final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436);
+        addManagedProfile(admin1, managedProfileAdminUid, admin1);
+        mContext.binder.callingUid = managedProfileAdminUid;
+
+        PreferentialNetworkServiceConfig preferentialNetworkServiceConfigEnabled =
+                (new PreferentialNetworkServiceConfig.Builder())
+                        .setEnabled(true)
+                        .setNetworkId(NET_ENTERPRISE_ID_1)
+                        .setFallbackToDefaultConnectionAllowed(false)
+                        .setIncludedUids(new int[]{1, 2})
+                        .build();
+        dpm.setPreferentialNetworkServiceConfig(preferentialNetworkServiceConfigEnabled);
+        assertThat(dpm.getPreferentialNetworkServiceConfig()
+                .isEnabled()).isTrue();
+        List<Integer> includedList = new ArrayList<>();
+        includedList.add(1);
+        includedList.add(2);
+        ProfileNetworkPreference preferenceDetails =
+                new ProfileNetworkPreference.Builder()
+                        .setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK)
+                        .setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1)
+                        .setIncludedUids(includedList)
+                        .build();
+        List<ProfileNetworkPreference> preferences = new ArrayList<>();
+        preferences.add(preferenceDetails);
+        verify(getServices().connectivityManager, times(1))
+                .setProfileNetworkPreferences(UserHandle.of(managedProfileUserId), preferences,
+                        null, null);
+    }
+
+    @Test
+    public void testSetPreferentialNetworkServiceConfig_enterprisePreferenceExcludedUids()
+            throws Exception {
+        final int managedProfileUserId = 15;
+        final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436);
+        addManagedProfile(admin1, managedProfileAdminUid, admin1);
+        mContext.binder.callingUid = managedProfileAdminUid;
+
+        PreferentialNetworkServiceConfig preferentialNetworkServiceConfigEnabled =
+                (new PreferentialNetworkServiceConfig.Builder())
+                        .setEnabled(true)
+                        .setNetworkId(NET_ENTERPRISE_ID_1)
+                        .setFallbackToDefaultConnectionAllowed(false)
+                        .setExcludedUids(new int[]{1, 2})
+                        .build();
+
+        dpm.setPreferentialNetworkServiceConfig(preferentialNetworkServiceConfigEnabled);
+        assertThat(dpm.getPreferentialNetworkServiceConfig()
+                .isEnabled()).isTrue();
+        List<Integer> excludedUids = new ArrayList<>();
+        excludedUids.add(1);
+        excludedUids.add(2);
+        ProfileNetworkPreference preferenceDetails =
+                new ProfileNetworkPreference.Builder()
+                        .setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK)
+                        .setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1)
+                        .setExcludedUids(excludedUids)
+                        .build();
+        List<ProfileNetworkPreference> preferences = new ArrayList<>();
+        preferences.clear();
+        preferences.add(preferenceDetails);
+        verify(getServices().connectivityManager, times(1))
+                .setProfileNetworkPreferences(UserHandle.of(managedProfileUserId), preferences,
+                        null, null);
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
index b811e28..e80721a 100644
--- a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
@@ -49,12 +49,9 @@
 import static android.net.NetworkPolicyManager.uidPoliciesToString;
 import static android.net.NetworkPolicyManager.uidRulesToString;
 import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
-import static android.net.NetworkStats.IFACE_ALL;
 import static android.net.NetworkStats.METERED_NO;
 import static android.net.NetworkStats.METERED_YES;
-import static android.net.NetworkStats.SET_ALL;
-import static android.net.NetworkStats.TAG_ALL;
-import static android.net.NetworkStats.TAG_NONE;
+import static android.net.NetworkTemplate.MATCH_MOBILE;
 import static android.net.NetworkTemplate.buildTemplateCarrierMetered;
 import static android.net.NetworkTemplate.buildTemplateWifi;
 import static android.net.TrafficStats.MB_IN_BYTES;
@@ -98,6 +95,7 @@
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -108,6 +106,8 @@
 import android.app.IUidObserver;
 import android.app.Notification;
 import android.app.NotificationManager;
+import android.app.usage.NetworkStats;
+import android.app.usage.NetworkStatsManager;
 import android.app.usage.UsageStatsManagerInternal;
 import android.content.Context;
 import android.content.Intent;
@@ -125,8 +125,6 @@
 import android.net.NetworkCapabilities;
 import android.net.NetworkPolicy;
 import android.net.NetworkStateSnapshot;
-import android.net.NetworkStats;
-import android.net.NetworkStatsHistory;
 import android.net.NetworkTemplate;
 import android.net.TelephonyNetworkSpecifier;
 import android.net.wifi.WifiInfo;
@@ -138,7 +136,6 @@
 import android.os.PowerSaveState;
 import android.os.RemoteException;
 import android.os.SimpleClock;
-import android.os.SystemClock;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.platform.test.annotations.Presubmit;
@@ -263,12 +260,13 @@
     private @Mock CarrierConfigManager mCarrierConfigManager;
     private @Mock TelephonyManager mTelephonyManager;
     private @Mock UserManager mUserManager;
+    private @Mock NetworkStatsManager mStatsManager;
+    private TestDependencies mDeps;
 
     private ArgumentCaptor<ConnectivityManager.NetworkCallback> mNetworkCallbackCaptor =
             ArgumentCaptor.forClass(ConnectivityManager.NetworkCallback.class);
 
     private ActivityManagerInternal mActivityManagerInternal;
-    private NetworkStatsManagerInternal mStatsService;
 
     private IUidObserver mUidObserver;
     private INetworkManagementEventObserver mNetworkObserver;
@@ -335,8 +333,47 @@
                 .setBatterySaverEnabled(false).build();
         final PowerManagerInternal pmInternal = addLocalServiceMock(PowerManagerInternal.class);
         when(pmInternal.getLowPowerState(anyInt())).thenReturn(state);
+    }
 
-        mStatsService = addLocalServiceMock(NetworkStatsManagerInternal.class);
+    private class TestDependencies extends NetworkPolicyManagerService.Dependencies {
+        private final SparseArray<NetworkStats.Bucket> mMockedStats = new SparseArray<>();
+
+        TestDependencies(Context context) {
+            super(context);
+        }
+
+        @Override
+        long getNetworkTotalBytes(NetworkTemplate template, long start, long end) {
+            int total = 0;
+            for (int i = 0; i < mMockedStats.size(); i++) {
+                NetworkStats.Bucket bucket = mMockedStats.valueAt(i);
+                total += bucket.getRxBytes() + bucket.getTxBytes();
+            }
+            return total;
+        }
+
+        @Override
+        List<NetworkStats.Bucket> getNetworkUidBytes(NetworkTemplate template, long start,
+                long end) {
+            final List<NetworkStats.Bucket> ret = new ArrayList<>();
+            for (int i = 0; i < mMockedStats.size(); i++) {
+                ret.add(mMockedStats.valueAt(i));
+            }
+            return ret;
+        }
+
+        private void setMockedTotalBytes(int uid, long rxBytes, long txBytes) {
+            final NetworkStats.Bucket bucket = mock(NetworkStats.Bucket.class);
+            when(bucket.getUid()).thenReturn(uid);
+            when(bucket.getRxBytes()).thenReturn(rxBytes);
+            when(bucket.getTxBytes()).thenReturn(txBytes);
+            mMockedStats.set(uid, bucket);
+        }
+
+        private void increaseMockedTotalBytes(int uid, long rxBytes, long txBytes) {
+            final NetworkStats.Bucket bucket = mMockedStats.get(uid);
+            setMockedTotalBytes(uid, bucket.getRxBytes() + rxBytes, bucket.getTxBytes() + txBytes);
+        }
     }
 
     @Before
@@ -376,6 +413,8 @@
                         return mConnManager;
                     case Context.USER_SERVICE:
                         return mUserManager;
+                    case Context.NETWORK_STATS_SERVICE:
+                        return mStatsManager;
                     default:
                         return super.getSystemService(name);
                 }
@@ -400,8 +439,9 @@
         }).when(mActivityManager).registerUidObserver(any(), anyInt(), anyInt(), any(String.class));
 
         mFutureIntent = newRestrictBackgroundChangedFuture();
+        mDeps = new TestDependencies(mServiceContext);
         mService = new NetworkPolicyManagerService(mServiceContext, mActivityManager,
-                mNetworkManager, mIpm, mClock, mPolicyDir, true);
+                mNetworkManager, mIpm, mClock, mPolicyDir, true, mDeps);
         mService.bindConnectivityManager();
         mPolicyListener = new NetworkPolicyListenerAnswer(mService);
 
@@ -456,6 +496,15 @@
         verify(mNetworkManager).registerObserver(networkObserver.capture());
         mNetworkObserver = networkObserver.getValue();
 
+        // Catch UsageCallback during systemReady(). Simulate NetworkStatsService triggered
+        // stats updated callback to signal its readiness.
+        final ArgumentCaptor<NetworkStatsManager.UsageCallback> usageObserver =
+                ArgumentCaptor.forClass(NetworkStatsManager.UsageCallback.class);
+        verify(mStatsManager, times(2))
+                .registerUsageCallback(any(), anyLong(), any(), usageObserver.capture());
+        usageObserver.getValue().onThresholdReached(
+                new NetworkTemplate.Builder(MATCH_MOBILE).build());
+
         NetworkPolicy defaultPolicy = mService.buildDefaultCarrierPolicy(0, "");
         mDefaultWarningBytes = defaultPolicy.warningBytes;
         mDefaultLimitBytes = defaultPolicy.limitBytes;
@@ -479,7 +528,6 @@
         LocalServices.removeServiceForTest(DeviceIdleInternal.class);
         LocalServices.removeServiceForTest(AppStandbyInternal.class);
         LocalServices.removeServiceForTest(UsageStatsManagerInternal.class);
-        LocalServices.removeServiceForTest(NetworkStatsManagerInternal.class);
     }
 
     @After
@@ -1108,10 +1156,7 @@
         when(mConnManager.getAllNetworkStateSnapshots()).thenReturn(snapshots);
 
         // pretend that 512 bytes total have happened
-        stats = new NetworkStats(getElapsedRealtime(), 1)
-                .insertEntry(TEST_IFACE, 256L, 2L, 256L, 2L);
-        when(mStatsService.getNetworkTotalBytes(sTemplateWifi, CYCLE_START, CYCLE_END))
-                .thenReturn(stats.getTotalBytes());
+        mDeps.setMockedTotalBytes(UID_A, 256L, 256L);
 
         mPolicyListener.expect().onMeteredIfacesChanged(any());
         setNetworkPolicies(new NetworkPolicy(
@@ -1124,26 +1169,6 @@
 
     @Test
     public void testNotificationWarningLimitSnooze() throws Exception {
-        // Create a place to store fake usage
-        final NetworkStatsHistory history = new NetworkStatsHistory(TimeUnit.HOURS.toMillis(1));
-        final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 0);
-        when(mStatsService.getNetworkTotalBytes(any(), anyLong(), anyLong()))
-                .thenAnswer(new Answer<Long>() {
-                    @Override
-                    public Long answer(InvocationOnMock invocation) throws Throwable {
-                        final NetworkStatsHistory.Entry entry = history.getValues(
-                                invocation.getArgument(1), invocation.getArgument(2), null);
-                        return entry.rxBytes + entry.txBytes;
-                    }
-                });
-        when(mStatsService.getNetworkUidBytes(any(), anyLong(), anyLong()))
-                .thenAnswer(new Answer<NetworkStats>() {
-                    @Override
-                    public NetworkStats answer(InvocationOnMock invocation) throws Throwable {
-                        return stats;
-                    }
-                });
-
         // Get active mobile network in place
         expectMobileDefaults();
         mService.updateNetworks();
@@ -1161,9 +1186,7 @@
 
         // Normal usage means no notification
         {
-            history.clear();
-            history.recordData(start, end,
-                    new NetworkStats.Entry(DataUnit.MEGABYTES.toBytes(360), 0L, 0L, 0L, 0));
+            mDeps.setMockedTotalBytes(UID_A, DataUnit.MEGABYTES.toBytes(360), 0);
 
             reset(mTelephonyManager, mNetworkManager, mNotifManager);
             TelephonyManager tmSub = expectMobileDefaults();
@@ -1178,9 +1201,7 @@
 
         // Push over warning
         {
-            history.clear();
-            history.recordData(start, end,
-                    new NetworkStats.Entry(DataUnit.MEGABYTES.toBytes(1799), 0L, 0L, 0L, 0));
+            mDeps.setMockedTotalBytes(UID_A, DataUnit.MEGABYTES.toBytes(1799), 0);
 
             reset(mTelephonyManager, mNetworkManager, mNotifManager);
             TelephonyManager tmSub = expectMobileDefaults();
@@ -1196,9 +1217,7 @@
 
         // Push over warning, but with a config that isn't from an identified carrier
         {
-            history.clear();
-            history.recordData(start, end,
-                    new NetworkStats.Entry(DataUnit.MEGABYTES.toBytes(1799), 0L, 0L, 0L, 0));
+            mDeps.setMockedTotalBytes(UID_A, DataUnit.MEGABYTES.toBytes(1799), 0);
 
             reset(mTelephonyManager, mNetworkManager, mNotifManager);
             TelephonyManager tmSub = expectMobileDefaults();
@@ -1215,9 +1234,7 @@
 
         // Push over limit
         {
-            history.clear();
-            history.recordData(start, end,
-                    new NetworkStats.Entry(DataUnit.MEGABYTES.toBytes(1810), 0L, 0L, 0L, 0));
+            mDeps.setMockedTotalBytes(UID_A, DataUnit.MEGABYTES.toBytes(1810), 0);
 
             reset(mTelephonyManager, mNetworkManager, mNotifManager);
             TelephonyManager tmSub = expectMobileDefaults();
@@ -1248,26 +1265,6 @@
 
     @Test
     public void testNotificationRapid() throws Exception {
-        // Create a place to store fake usage
-        final NetworkStatsHistory history = new NetworkStatsHistory(TimeUnit.HOURS.toMillis(1));
-        final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 0);
-        when(mStatsService.getNetworkTotalBytes(any(), anyLong(), anyLong()))
-                .thenAnswer(new Answer<Long>() {
-                    @Override
-                    public Long answer(InvocationOnMock invocation) throws Throwable {
-                        final NetworkStatsHistory.Entry entry = history.getValues(
-                                invocation.getArgument(1), invocation.getArgument(2), null);
-                        return entry.rxBytes + entry.txBytes;
-                    }
-                });
-        when(mStatsService.getNetworkUidBytes(any(), anyLong(), anyLong()))
-                .thenAnswer(new Answer<NetworkStats>() {
-                    @Override
-                    public NetworkStats answer(InvocationOnMock invocation) throws Throwable {
-                        return stats;
-                    }
-                });
-
         // Get active mobile network in place
         expectMobileDefaults();
         mService.updateNetworks();
@@ -1285,9 +1282,7 @@
 
         // Using 20% data in 20% time is normal
         {
-            history.clear();
-            history.recordData(start, end,
-                    new NetworkStats.Entry(DataUnit.MEGABYTES.toBytes(360), 0L, 0L, 0L, 0));
+            mDeps.setMockedTotalBytes(UID_A, DataUnit.MEGABYTES.toBytes(360), 0);
 
             reset(mNotifManager);
             mService.updateNetworks();
@@ -1297,16 +1292,9 @@
         // Using 80% data in 20% time is alarming; but spread equally among
         // three UIDs means we get generic alert
         {
-            history.clear();
-            history.recordData(start, end,
-                    new NetworkStats.Entry(DataUnit.MEGABYTES.toBytes(1440), 0L, 0L, 0L, 0));
-            stats.clear();
-            stats.insertEntry(IFACE_ALL, UID_A, SET_ALL, TAG_ALL,
-                    DataUnit.MEGABYTES.toBytes(480), 0, 0, 0, 0);
-            stats.insertEntry(IFACE_ALL, UID_B, SET_ALL, TAG_ALL,
-                    DataUnit.MEGABYTES.toBytes(480), 0, 0, 0, 0);
-            stats.insertEntry(IFACE_ALL, UID_C, SET_ALL, TAG_ALL,
-                    DataUnit.MEGABYTES.toBytes(480), 0, 0, 0, 0);
+            mDeps.setMockedTotalBytes(UID_A, DataUnit.MEGABYTES.toBytes(480), 0);
+            mDeps.setMockedTotalBytes(UID_B, DataUnit.MEGABYTES.toBytes(480), 0);
+            mDeps.setMockedTotalBytes(UID_C, DataUnit.MEGABYTES.toBytes(480), 0);
 
             reset(mNotifManager);
             mService.updateNetworks();
@@ -1325,14 +1313,9 @@
         // Using 80% data in 20% time is alarming; but mostly done by one UID
         // means we get specific alert
         {
-            history.clear();
-            history.recordData(start, end,
-                    new NetworkStats.Entry(DataUnit.MEGABYTES.toBytes(1440), 0L, 0L, 0L, 0));
-            stats.clear();
-            stats.insertEntry(IFACE_ALL, UID_A, SET_ALL, TAG_ALL,
-                    DataUnit.MEGABYTES.toBytes(960), 0, 0, 0, 0);
-            stats.insertEntry(IFACE_ALL, UID_B, SET_ALL, TAG_ALL,
-                    DataUnit.MEGABYTES.toBytes(480), 0, 0, 0, 0);
+            mDeps.setMockedTotalBytes(UID_A, DataUnit.MEGABYTES.toBytes(960), 0);
+            mDeps.setMockedTotalBytes(UID_B, DataUnit.MEGABYTES.toBytes(480), 0);
+            mDeps.setMockedTotalBytes(UID_C, 0, 0);
 
             reset(mNotifManager);
             mService.updateNetworks();
@@ -1362,13 +1345,10 @@
 
         // bring up wifi network with metered policy
         snapshots = List.of(buildWifi());
-        stats = new NetworkStats(getElapsedRealtime(), 1)
-                .insertEntry(TEST_IFACE, 0L, 0L, 0L, 0L);
+        mDeps.setMockedTotalBytes(UID_A, 0L, 0L);
 
         {
             when(mConnManager.getAllNetworkStateSnapshots()).thenReturn(snapshots);
-            when(mStatsService.getNetworkTotalBytes(sTemplateWifi, TIME_FEB_15,
-                    currentTimeMillis())).thenReturn(stats.getTotalBytes());
 
             mPolicyListener.expect().onMeteredIfacesChanged(any());
             setNetworkPolicies(new NetworkPolicy(
@@ -1647,18 +1627,6 @@
         final NetworkPolicyManagerInternal internal = LocalServices
                 .getService(NetworkPolicyManagerInternal.class);
 
-        // Create a place to store fake usage
-        final NetworkStatsHistory history = new NetworkStatsHistory(TimeUnit.HOURS.toMillis(1));
-        final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 0);
-        when(mStatsService.getNetworkTotalBytes(any(), anyLong(), anyLong()))
-                .thenAnswer(invocation -> {
-                    final NetworkStatsHistory.Entry entry = history.getValues(
-                            invocation.getArgument(1), invocation.getArgument(2), null);
-                    return entry.rxBytes + entry.txBytes;
-                });
-        when(mStatsService.getNetworkUidBytes(any(), anyLong(), anyLong()))
-                .thenReturn(stats);
-
         // Get active mobile network in place
         expectMobileDefaults();
         mService.updateNetworks();
@@ -1669,9 +1637,7 @@
         setCurrentTimeMillis(end);
 
         // Get some data usage in place
-        history.clear();
-        history.recordData(start, end,
-                new NetworkStats.Entry(DataUnit.MEGABYTES.toBytes(360), 0L, 0L, 0L, 0));
+        mDeps.setMockedTotalBytes(UID_A, DataUnit.MEGABYTES.toBytes(360), 0);
 
         // No data plan
         {
@@ -1786,22 +1752,11 @@
                 true);
     }
 
-    private void increaseMockedTotalBytes(NetworkStats stats, long rxBytes, long txBytes) {
-        stats.insertEntry(TEST_IFACE, UID_A, SET_ALL, TAG_NONE,
-                rxBytes, 1, txBytes, 1, 0);
-        when(mStatsService.getNetworkTotalBytes(any(), anyLong(), anyLong()))
-                .thenReturn(stats.getTotalBytes());
-        when(mStatsService.getNetworkUidBytes(any(), anyLong(), anyLong()))
-                .thenReturn(stats);
-    }
-
     private void triggerOnStatsProviderWarningOrLimitReached() throws InterruptedException {
-        final NetworkPolicyManagerInternal npmi = LocalServices
-                .getService(NetworkPolicyManagerInternal.class);
-        npmi.onStatsProviderWarningOrLimitReached("TEST");
+        mService.notifyStatsProviderWarningOrLimitReached();
         // Wait for processing of MSG_STATS_PROVIDER_WARNING_OR_LIMIT_REACHED.
         postMsgAndWaitForCompletion();
-        verify(mStatsService).forceUpdate();
+        verify(mStatsManager).forceUpdate();
         // Wait for processing of MSG_*_INTERFACE_QUOTAS.
         postMsgAndWaitForCompletion();
     }
@@ -1814,13 +1769,12 @@
     public void testStatsProviderWarningAndLimitReached() throws Exception {
         final int CYCLE_DAY = 15;
 
-        final NetworkStats stats = new NetworkStats(0L, 1);
-        increaseMockedTotalBytes(stats, 2999, 2000);
+        mDeps.setMockedTotalBytes(UID_A, 2999, 2000);
 
         // Get active mobile network in place
         expectMobileDefaults();
         mService.updateNetworks();
-        verify(mStatsService).setStatsProviderWarningAndLimitAsync(TEST_IFACE, Long.MAX_VALUE,
+        verify(mStatsManager).setStatsProviderWarningAndLimitAsync(TEST_IFACE, Long.MAX_VALUE,
                 Long.MAX_VALUE);
 
         // Set warning to 7KB and limit to 10KB.
@@ -1830,32 +1784,32 @@
         postMsgAndWaitForCompletion();
 
         // Verifies that remaining quotas are set to providers.
-        verify(mStatsService).setStatsProviderWarningAndLimitAsync(TEST_IFACE, 2001L, 5001L);
-        reset(mStatsService);
+        verify(mStatsManager).setStatsProviderWarningAndLimitAsync(TEST_IFACE, 2001L, 5001L);
+        reset(mStatsManager);
 
         // Increase the usage and simulates that limit reached fires earlier by provider,
         // but actually the quota is not yet reached. Verifies that the limit reached leads to
         // a force update and new quotas should be set.
-        increaseMockedTotalBytes(stats, 1000, 999);
+        mDeps.increaseMockedTotalBytes(UID_A, 1000, 999);
         triggerOnStatsProviderWarningOrLimitReached();
-        verify(mStatsService).setStatsProviderWarningAndLimitAsync(TEST_IFACE, 2L, 3002L);
-        reset(mStatsService);
+        verify(mStatsManager).setStatsProviderWarningAndLimitAsync(TEST_IFACE, 2L, 3002L);
+        reset(mStatsManager);
 
         // Increase the usage and simulate warning reached, the new warning should be unlimited
         // since service will disable warning quota to stop lower layer from keep triggering
         // warning reached event.
-        increaseMockedTotalBytes(stats, 1000L, 1000);
+        mDeps.increaseMockedTotalBytes(UID_A, 1000L, 1000);
         triggerOnStatsProviderWarningOrLimitReached();
-        verify(mStatsService).setStatsProviderWarningAndLimitAsync(
+        verify(mStatsManager).setStatsProviderWarningAndLimitAsync(
                 TEST_IFACE, Long.MAX_VALUE, 1002L);
-        reset(mStatsService);
+        reset(mStatsManager);
 
         // Increase the usage that over the warning and limit, the new limit should set to 1 to
         // block the network traffic.
-        increaseMockedTotalBytes(stats, 1000L, 1000);
+        mDeps.increaseMockedTotalBytes(UID_A, 1000L, 1000);
         triggerOnStatsProviderWarningOrLimitReached();
-        verify(mStatsService).setStatsProviderWarningAndLimitAsync(TEST_IFACE, Long.MAX_VALUE, 1L);
-        reset(mStatsService);
+        verify(mStatsManager).setStatsProviderWarningAndLimitAsync(TEST_IFACE, Long.MAX_VALUE, 1L);
+        reset(mStatsManager);
     }
 
     private void enableRestrictedMode(boolean enable) throws Exception {
@@ -2099,7 +2053,7 @@
     private static NetworkStateSnapshot buildWifi() {
         WifiInfo mockWifiInfo = mock(WifiInfo.class);
         when(mockWifiInfo.makeCopy(anyLong())).thenReturn(mockWifiInfo);
-        when(mockWifiInfo.getCurrentNetworkKey()).thenReturn(TEST_WIFI_NETWORK_KEY);
+        when(mockWifiInfo.getNetworkKey()).thenReturn(TEST_WIFI_NETWORK_KEY);
         final LinkProperties prop = new LinkProperties();
         prop.setInterfaceName(TEST_IFACE);
         final NetworkCapabilities networkCapabilities = new NetworkCapabilities.Builder()
@@ -2145,7 +2099,7 @@
     }
 
     private void verifyAdvisePersistThreshold() throws Exception {
-        verify(mStatsService).advisePersistThreshold(anyLong());
+        verify(mStatsManager).setDefaultGlobalAlert(anyLong());
     }
 
     private static class TestAbstractFuture<T> extends AbstractFuture<T> {
diff --git a/services/tests/servicestests/src/com/android/server/wm/OWNERS b/services/tests/servicestests/src/com/android/server/wm/OWNERS
new file mode 100644
index 0000000..361760d
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/OWNERS
@@ -0,0 +1 @@
+include platform/frameworks/base:/services/core/java/com/android/server/wm/OWNERS
diff --git a/services/wallpapereffectsgeneration/OWNERS b/services/wallpapereffectsgeneration/OWNERS
new file mode 100644
index 0000000..d2d3e2c0
--- /dev/null
+++ b/services/wallpapereffectsgeneration/OWNERS
@@ -0,0 +1,4 @@
+susharon@google.com
+shanh@google.com
+huiwu@google.com
+srazdan@google.com
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index b109c46..9a764a0 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -2459,6 +2459,10 @@
      *
      * Note: If {@code *} is specified for the original code, any ImsReasonInfo with the matching
      * {@code MESSAGE} will be remapped to {@code NEW_CODE}.
+     * If {@code *} is specified for the message, any ImsReasonInfo with the matching
+     * {@code ORIGINAL_CODE} will be remapped to {@code NEW_CODE}.
+     * The wildcard for {@code ORIGINAL_CODE} takes precedence to the wildcard for {@code MESSAGE}.
+     * A mapping with both wildcards has no effect.
      *
      * Example: "501|call completion elsewhere|1014"
      * When the {@link ImsReasonInfo#getCode()} is {@link ImsReasonInfo#CODE_USER_TERMINATED} and
@@ -4724,7 +4728,7 @@
         /**
          * A priority list of ePDG addresses to be used. Possible values are {@link
          * #EPDG_ADDRESS_STATIC}, {@link #EPDG_ADDRESS_PLMN}, {@link #EPDG_ADDRESS_PCO}, {@link
-         * #EPDG_ADDRESS_CELLULAR_LOC}
+         * #EPDG_ADDRESS_CELLULAR_LOC}, {@link #EPDG_ADDRESS_VISITED_COUNTRY}
          */
         public static final String KEY_EPDG_ADDRESS_PRIORITY_INT_ARRAY =
                 KEY_PREFIX + "epdg_address_priority_int_array";
@@ -4879,6 +4883,10 @@
         /** Specifies the PCO id for IPv4 Epdg server address */
         public static final String KEY_EPDG_PCO_ID_IPV4_INT = KEY_PREFIX + "epdg_pco_id_ipv4_int";
 
+        /** Controls if the IKE tunnel setup supports EAP-AKA fast reauth */
+        public static final String KEY_SUPPORTS_EAP_AKA_FAST_REAUTH_BOOL =
+                KEY_PREFIX + "supports_eap_aka_fast_reauth_bool";
+
         /** @hide */
         @IntDef({AUTHENTICATION_METHOD_EAP_ONLY, AUTHENTICATION_METHOD_CERT})
         public @interface AuthenticationMethodType {}
@@ -4899,7 +4907,8 @@
             EPDG_ADDRESS_STATIC,
             EPDG_ADDRESS_PLMN,
             EPDG_ADDRESS_PCO,
-            EPDG_ADDRESS_CELLULAR_LOC
+            EPDG_ADDRESS_CELLULAR_LOC,
+            EPDG_ADDRESS_VISITED_COUNTRY
         })
         public @interface EpdgAddressType {}
 
@@ -4913,6 +4922,8 @@
         public static final int EPDG_ADDRESS_PCO = 2;
         /** Use cellular location to chose epdg server */
         public static final int EPDG_ADDRESS_CELLULAR_LOC = 3;
+        /* Use Visited Country FQDN rule*/
+        public static final int EPDG_ADDRESS_VISITED_COUNTRY = 4;
 
         /** @hide */
         @IntDef({ID_TYPE_FQDN, ID_TYPE_RFC822_ADDR, ID_TYPE_KEY_ID})
@@ -5022,6 +5033,7 @@
             defaults.putBoolean(KEY_ADD_KE_TO_CHILD_SESSION_REKEY_BOOL, false);
             defaults.putInt(KEY_EPDG_PCO_ID_IPV6_INT, 0);
             defaults.putInt(KEY_EPDG_PCO_ID_IPV4_INT, 0);
+            defaults.putBoolean(KEY_SUPPORTS_EAP_AKA_FAST_REAUTH_BOOL, false);
 
             return defaults;
         }
@@ -5846,10 +5858,10 @@
         /* Default value is 2 seconds. */
         sDefaults.putLong(KEY_OPPORTUNISTIC_NETWORK_5G_DATA_SWITCH_EXIT_HYSTERESIS_TIME_LONG, 2000);
         sDefaults.putBoolean(KEY_ENABLE_4G_OPPORTUNISTIC_NETWORK_SCAN_BOOL, true);
-        sDefaults.putInt(KEY_TIME_TO_SWITCH_BACK_TO_PRIMARY_IF_OPPORTUNISTIC_OOS_LONG, 60000);
-        sDefaults.putInt(
+        sDefaults.putLong(KEY_TIME_TO_SWITCH_BACK_TO_PRIMARY_IF_OPPORTUNISTIC_OOS_LONG, 60000L);
+        sDefaults.putLong(
                 KEY_OPPORTUNISTIC_TIME_TO_SCAN_AFTER_CAPABILITY_SWITCH_TO_PRIMARY_LONG,
-                120000);
+                120000L);
         sDefaults.putAll(ImsServiceEntitlement.getDefaults());
         sDefaults.putAll(Gps.getDefaults());
         sDefaults.putIntArray(KEY_CDMA_ENHANCED_ROAMING_INDICATOR_FOR_HOME_NETWORK_INT_ARRAY,
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index f728324..4e32a55 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -3820,6 +3820,11 @@
      * {@link #PHONE_NUMBER_SOURCE_UICC UICC} and decide if the previously set phone number
      * of source {@link #PHONE_NUMBER_SOURCE_CARRIER carrier} should be updated.
      *
+     * <p>The API provides no guarantees of what format the number is in: the format can vary
+     * depending on the {@code source} and the network etc. Programmatic parsing should be done
+     * cautiously, for example, after formatting the number to a consistent format with
+     * {@link android.telephony.PhoneNumberUtils#formatNumberToE164(String, String)}.
+     *
      * <p>Note the assumption is that one subscription (which usually means one SIM) has
      * only one phone number. The multiple sources backup each other so hopefully at least one
      * is availavle. For example, for a carrier that doesn't typically set phone numbers
@@ -3878,6 +3883,11 @@
      * from available sources in the following order: {@link #PHONE_NUMBER_SOURCE_CARRIER}
      * > {@link #PHONE_NUMBER_SOURCE_UICC} > {@link #PHONE_NUMBER_SOURCE_IMS}.
      *
+     * <p>The API provides no guarantees of what format the number is in: the format can vary
+     * depending on the underlying source and the network etc. Programmatic parsing should be done
+     * cautiously, for example, after formatting the number to a consistent format with
+     * {@link android.telephony.PhoneNumberUtils#formatNumberToE164(String, String)}.
+     *
      * @param subscriptionId the subscription ID, or {@link #DEFAULT_SUBSCRIPTION_ID}
      *                       for the default one.
      * @return the phone number, or an empty string if not available.
@@ -3916,6 +3926,9 @@
      * <p>The API is suitable for carrier apps to provide a phone number, for example when
      * it's not possible to update {@link #PHONE_NUMBER_SOURCE_UICC UICC} directly.
      *
+     * <p>It's recommended that the phone number is formatted to well-known formats,
+     * for example, by {@link PhoneNumberUtils} {@code formatNumber*} methods.
+     *
      * @param subscriptionId the subscription ID, or {@link #DEFAULT_SUBSCRIPTION_ID}
      *                       for the default one.
      * @param number the phone number, or an empty string to remove the previously set number.
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 9ac9d66..aab6daa 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -11487,7 +11487,11 @@
 
         private final int mErrorCode;
 
-        /** @hide */
+        /**
+         * An exception with ModemActivityInfo specific error codes.
+         *
+         * @param errorCode a ModemActivityInfoError code.
+         */
         public ModemActivityInfoException(@ModemActivityInfoError int errorCode) {
             mErrorCode = errorCode;
         }
diff --git a/telephony/java/android/telephony/ims/RcsUceAdapter.java b/telephony/java/android/telephony/ims/RcsUceAdapter.java
index 61de3ac..154bb11 100644
--- a/telephony/java/android/telephony/ims/RcsUceAdapter.java
+++ b/telephony/java/android/telephony/ims/RcsUceAdapter.java
@@ -268,6 +268,13 @@
     @SystemApi
     public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_NR5G_VOPS_ENABLED = 11;
 
+    /**
+     * A capability update has been requested due to IMS being registered over INTERNET PDN.
+     * @hide
+     */
+    @SystemApi
+    public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_INTERNET_PDN = 12;
+
     /**@hide*/
     @Retention(RetentionPolicy.SOURCE)
     @IntDef(prefix = "ERROR_", value = {
@@ -282,7 +289,8 @@
             CAPABILITY_UPDATE_TRIGGER_MOVE_TO_WLAN,
             CAPABILITY_UPDATE_TRIGGER_MOVE_TO_IWLAN,
             CAPABILITY_UPDATE_TRIGGER_MOVE_TO_NR5G_VOPS_DISABLED,
-            CAPABILITY_UPDATE_TRIGGER_MOVE_TO_NR5G_VOPS_ENABLED
+            CAPABILITY_UPDATE_TRIGGER_MOVE_TO_NR5G_VOPS_ENABLED,
+            CAPABILITY_UPDATE_TRIGGER_MOVE_TO_INTERNET_PDN
     })
     public @interface StackPublishTriggerType {}
 
diff --git a/telephony/java/com/android/internal/telephony/DctConstants.java b/telephony/java/com/android/internal/telephony/DctConstants.java
index 409c838..2470887 100644
--- a/telephony/java/com/android/internal/telephony/DctConstants.java
+++ b/telephony/java/com/android/internal/telephony/DctConstants.java
@@ -114,6 +114,7 @@
     public static final int EVENT_CARRIER_CONFIG_CHANGED = BASE + 54;
     public static final int EVENT_SIM_STATE_UPDATED = BASE + 55;
     public static final int EVENT_APN_UNTHROTTLED = BASE + 56;
+    public static final int EVENT_TRAFFIC_DESCRIPTORS_UPDATED = BASE + 57;
 
     /***** Constants *****/
 
diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java
index ba95841..39ab7eb 100644
--- a/telephony/java/com/android/internal/telephony/RILConstants.java
+++ b/telephony/java/com/android/internal/telephony/RILConstants.java
@@ -592,6 +592,7 @@
     int RIL_UNSOL_UNTHROTTLE_APN = 1052;
     int RIL_UNSOL_RESPONSE_SIM_PHONEBOOK_CHANGED = 1053;
     int RIL_UNSOL_RESPONSE_SIM_PHONEBOOK_RECORDS_RECEIVED = 1054;
+    int RIL_UNSOL_SLICING_CONFIG_CHANGED = 1055;
 
     /* The following unsols are not defined in RIL.h */
     int RIL_UNSOL_HAL_NON_RIL_BASE = 1100;
diff --git a/test-base/Android.bp b/test-base/Android.bp
index 97ebba6..8be7324 100644
--- a/test-base/Android.bp
+++ b/test-base/Android.bp
@@ -26,7 +26,19 @@
     // to get the below license kinds:
     //   SPDX-license-identifier-Apache-2.0
     //   SPDX-license-identifier-CPL-1.0
-    default_applicable_licenses: ["frameworks_base_license"],
+    default_applicable_licenses: ["frameworks_base_test-base_license"],
+}
+
+license {
+    name: "frameworks_base_test-base_license",
+    visibility: [":__subpackages__"],
+    license_kinds: [
+        "SPDX-license-identifier-Apache-2.0",
+        "SPDX-license-identifier-CPL-1.0",
+    ],
+    license_text: [
+        "src/junit/cpl-v10.html",
+    ],
 }
 
 java_sdk_library {
diff --git a/test-runner/Android.bp b/test-runner/Android.bp
index 0f56bb3..2a19af9 100644
--- a/test-runner/Android.bp
+++ b/test-runner/Android.bp
@@ -18,12 +18,19 @@
 // =====================================
 package {
     // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "frameworks_base_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    //   SPDX-license-identifier-CPL-1.0
-    default_applicable_licenses: ["frameworks_base_license"],
+    default_applicable_licenses: ["frameworks_base_test-runner_license"],
+}
+
+license {
+    name: "frameworks_base_test-runner_license",
+    visibility: [":__subpackages__"],
+    license_kinds: [
+        "SPDX-license-identifier-Apache-2.0",
+        "SPDX-license-identifier-CPL-1.0",
+    ],
+    license_text: [
+        "src/junit/cpl-v10.html",
+    ],
 }
 
 java_sdk_library {
diff --git a/tests/DataIdleTest/src/com/android/tests/dataidle/DataIdleTest.java b/tests/DataIdleTest/src/com/android/tests/dataidle/DataIdleTest.java
index 4ec86b186..56848b8 100644
--- a/tests/DataIdleTest/src/com/android/tests/dataidle/DataIdleTest.java
+++ b/tests/DataIdleTest/src/com/android/tests/dataidle/DataIdleTest.java
@@ -15,20 +15,19 @@
  */
 package com.android.tests.dataidle;
 
+import static android.net.NetworkStats.METERED_YES;
+
+import android.app.usage.NetworkStats;
+import android.app.usage.NetworkStatsManager;
 import android.content.Context;
-import android.net.INetworkStatsService;
-import android.net.INetworkStatsSession;
-import android.net.NetworkStats;
-import android.net.NetworkStats.Entry;
 import android.net.NetworkTemplate;
-import android.net.TrafficStats;
 import android.os.Bundle;
-import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.telephony.TelephonyManager;
 import android.test.InstrumentationTestCase;
 import android.util.Log;
 
+import java.util.Set;
+
 /**
  * A test that dumps data usage to instrumentation out, used for measuring data usage for idle
  * devices.
@@ -36,7 +35,7 @@
 public class DataIdleTest extends InstrumentationTestCase {
 
     private TelephonyManager mTelephonyManager;
-    private INetworkStatsService mStatsService;
+    private NetworkStatsManager mStatsManager;
 
     private static final String LOG_TAG = "DataIdleTest";
     private final static int INSTRUMENTATION_IN_PROGRESS = 2;
@@ -44,8 +43,7 @@
     protected void setUp() throws Exception {
         super.setUp();
         Context c = getInstrumentation().getTargetContext();
-        mStatsService = INetworkStatsService.Stub.asInterface(
-                ServiceManager.getService(Context.NETWORK_STATS_SERVICE));
+        mStatsManager = c.getSystemService(NetworkStatsManager.class);
         mTelephonyManager = (TelephonyManager) c.getSystemService(Context.TELEPHONY_SERVICE);
     }
 
@@ -53,7 +51,9 @@
      * Test that dumps all the data usage metrics for wifi to instrumentation out.
      */
     public void testWifiIdle() {
-        NetworkTemplate template = NetworkTemplate.buildTemplateWifiWildcard();
+        final NetworkTemplate template = new NetworkTemplate
+                .Builder(NetworkTemplate.MATCH_WIFI)
+                .build();
         fetchStats(template);
     }
 
@@ -61,8 +61,11 @@
      * Test that dumps all the data usage metrics for all mobile to instrumentation out.
      */
     public void testMobile() {
-        String subscriberId = mTelephonyManager.getSubscriberId();
-        NetworkTemplate template = NetworkTemplate.buildTemplateMobileAll(subscriberId);
+        final String subscriberId = mTelephonyManager.getSubscriberId();
+        NetworkTemplate template = new NetworkTemplate
+                .Builder(NetworkTemplate.MATCH_MOBILE)
+                .setMeteredness(METERED_YES)
+                .setSubscriberIds(Set.of(subscriberId)).build();
         fetchStats(template);
     }
 
@@ -72,49 +75,26 @@
      * @param template {@link NetworkTemplate} to match.
      */
     private void fetchStats(NetworkTemplate template) {
-        INetworkStatsSession session = null;
         try {
-            mStatsService.forceUpdate();
-            session = mStatsService.openSession();
-            final NetworkStats stats = session.getSummaryForAllUid(
-                    template, Long.MIN_VALUE, Long.MAX_VALUE, false);
-            reportStats(stats);
-        } catch (RemoteException e) {
+            mStatsManager.forceUpdate();
+            final NetworkStats.Bucket bucket =
+                    mStatsManager.querySummaryForDevice(template, Long.MIN_VALUE, Long.MAX_VALUE);
+            reportStats(bucket);
+        } catch (RuntimeException e) {
             Log.w(LOG_TAG, "Failed to fetch network stats.");
-        } finally {
-            TrafficStats.closeQuietly(session);
         }
     }
 
     /**
      * Print network data usage stats to instrumentation out
-     * @param stats {@link NetworkorStats} to print
+     * @param bucket {@link NetworkStats} to print
      */
-    void reportStats(NetworkStats stats) {
+    void reportStats(NetworkStats.Bucket bucket) {
         Bundle result = new Bundle();
-        long rxBytes = 0;
-        long txBytes = 0;
-        long rxPackets = 0;
-        long txPackets = 0;
-        for (int i = 0; i < stats.size(); ++i) {
-            // Label will be iface_uid_tag_set
-            Entry  statsEntry = stats.getValues(i, null);
-            // Debugging use.
-            /*
-            String labelTemplate = String.format("%s_%d_%d_%d", statsEntry.iface, statsEntry.uid,
-                    statsEntry.tag, statsEntry.set) + "_%s";
-            result.putLong(String.format(labelTemplate, "rxBytes"), statsEntry.rxBytes);
-            result.putLong(String.format(labelTemplate, "txBytes"), statsEntry.txBytes);
-            */
-            rxPackets += statsEntry.rxPackets;
-            rxBytes += statsEntry.rxBytes;
-            txPackets += statsEntry.txPackets;
-            txBytes += statsEntry.txBytes;
-        }
-        result.putLong("Total rx Bytes", rxBytes);
-        result.putLong("Total tx Bytes", txBytes);
-        result.putLong("Total rx Packets", rxPackets);
-        result.putLong("Total tx Packets", txPackets);
+        result.putLong("Total rx Bytes", bucket.getRxBytes());
+        result.putLong("Total tx Bytes", bucket.getTxBytes());
+        result.putLong("Total rx Packets", bucket.getRxPackets());
+        result.putLong("Total tx Packets", bucket.getTxPackets());
         getInstrumentation().sendStatus(INSTRUMENTATION_IN_PROGRESS, result);
 
     }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/close/OWNERS b/tests/FlickerTests/src/com/android/server/wm/flicker/close/OWNERS
new file mode 100644
index 0000000..f7c0a87
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/close/OWNERS
@@ -0,0 +1,2 @@
+# window manager > animations/transitions
+# Bug component: 316275
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OWNERS b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OWNERS
new file mode 100644
index 0000000..301fafa
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OWNERS
@@ -0,0 +1,2 @@
+# ime
+# Bug component: 34867
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OWNERS b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OWNERS
new file mode 100644
index 0000000..2c414a2
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OWNERS
@@ -0,0 +1,4 @@
+# System UI > ... > Overview (recent apps) > UI
+# Bug template url: https://b.corp.google.com/issues/new?component=807991&template=1390280 = per-file *Overview*
+# window manager > animations/transitions
+# Bug template url: https://b.corp.google.com/issues/new?component=316275&template=1018192
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/OWNERS b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/OWNERS
new file mode 100644
index 0000000..897fe5d
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/OWNERS
@@ -0,0 +1,2 @@
+# System UI > ... > Launcher > Gesture nav
+# Bug component: 565144
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/OWNERS b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/OWNERS
new file mode 100644
index 0000000..f7c0a87
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/OWNERS
@@ -0,0 +1,2 @@
+# window manager > animations/transitions
+# Bug component: 316275
diff --git a/tests/vcn/java/android/net/vcn/VcnCellUnderlyingNetworkTemplateTest.java b/tests/vcn/java/android/net/vcn/VcnCellUnderlyingNetworkTemplateTest.java
index 4a724b7..2fbcf9d 100644
--- a/tests/vcn/java/android/net/vcn/VcnCellUnderlyingNetworkTemplateTest.java
+++ b/tests/vcn/java/android/net/vcn/VcnCellUnderlyingNetworkTemplateTest.java
@@ -18,25 +18,29 @@
 import static android.net.vcn.VcnUnderlyingNetworkTemplate.MATCH_ANY;
 import static android.net.vcn.VcnUnderlyingNetworkTemplate.MATCH_FORBIDDEN;
 import static android.net.vcn.VcnUnderlyingNetworkTemplate.MATCH_REQUIRED;
-import static android.net.vcn.VcnUnderlyingNetworkTemplate.NETWORK_QUALITY_ANY;
-import static android.net.vcn.VcnUnderlyingNetworkTemplate.NETWORK_QUALITY_OK;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
 
 import org.junit.Test;
 
 import java.util.HashSet;
 import java.util.Set;
 
-public class VcnCellUnderlyingNetworkTemplateTest {
+public class VcnCellUnderlyingNetworkTemplateTest extends VcnUnderlyingNetworkTemplateTestBase {
     private static final Set<String> ALLOWED_PLMN_IDS = new HashSet<>();
     private static final Set<Integer> ALLOWED_CARRIER_IDS = new HashSet<>();
 
     // Package private for use in VcnGatewayConnectionConfigTest
     static VcnCellUnderlyingNetworkTemplate getTestNetworkTemplate() {
         return new VcnCellUnderlyingNetworkTemplate.Builder()
-                .setNetworkQuality(NETWORK_QUALITY_OK)
                 .setMetered(MATCH_FORBIDDEN)
+                .setMinUpstreamBandwidthKbps(
+                        TEST_MIN_ENTRY_UPSTREAM_BANDWIDTH_KBPS,
+                        TEST_MIN_EXIT_UPSTREAM_BANDWIDTH_KBPS)
+                .setMinDownstreamBandwidthKbps(
+                        TEST_MIN_ENTRY_DOWNSTREAM_BANDWIDTH_KBPS,
+                        TEST_MIN_EXIT_DOWNSTREAM_BANDWIDTH_KBPS)
                 .setOperatorPlmnIds(ALLOWED_PLMN_IDS)
                 .setSimSpecificCarrierIds(ALLOWED_CARRIER_IDS)
                 .setRoaming(MATCH_FORBIDDEN)
@@ -47,8 +51,19 @@
     @Test
     public void testBuilderAndGetters() {
         final VcnCellUnderlyingNetworkTemplate networkPriority = getTestNetworkTemplate();
-        assertEquals(NETWORK_QUALITY_OK, networkPriority.getNetworkQuality());
         assertEquals(MATCH_FORBIDDEN, networkPriority.getMetered());
+        assertEquals(
+                TEST_MIN_ENTRY_UPSTREAM_BANDWIDTH_KBPS,
+                networkPriority.getMinEntryUpstreamBandwidthKbps());
+        assertEquals(
+                TEST_MIN_EXIT_UPSTREAM_BANDWIDTH_KBPS,
+                networkPriority.getMinExitUpstreamBandwidthKbps());
+        assertEquals(
+                TEST_MIN_ENTRY_DOWNSTREAM_BANDWIDTH_KBPS,
+                networkPriority.getMinEntryDownstreamBandwidthKbps());
+        assertEquals(
+                TEST_MIN_EXIT_DOWNSTREAM_BANDWIDTH_KBPS,
+                networkPriority.getMinExitDownstreamBandwidthKbps());
         assertEquals(ALLOWED_PLMN_IDS, networkPriority.getOperatorPlmnIds());
         assertEquals(ALLOWED_CARRIER_IDS, networkPriority.getSimSpecificCarrierIds());
         assertEquals(MATCH_FORBIDDEN, networkPriority.getRoaming());
@@ -59,8 +74,14 @@
     public void testBuilderAndGettersForDefaultValues() {
         final VcnCellUnderlyingNetworkTemplate networkPriority =
                 new VcnCellUnderlyingNetworkTemplate.Builder().build();
-        assertEquals(NETWORK_QUALITY_ANY, networkPriority.getNetworkQuality());
         assertEquals(MATCH_ANY, networkPriority.getMetered());
+
+        // Explicitly expect 0, as documented in Javadoc on setter methods.
+        assertEquals(0, networkPriority.getMinEntryUpstreamBandwidthKbps());
+        assertEquals(0, networkPriority.getMinExitUpstreamBandwidthKbps());
+        assertEquals(0, networkPriority.getMinEntryDownstreamBandwidthKbps());
+        assertEquals(0, networkPriority.getMinExitDownstreamBandwidthKbps());
+
         assertEquals(new HashSet<String>(), networkPriority.getOperatorPlmnIds());
         assertEquals(new HashSet<Integer>(), networkPriority.getSimSpecificCarrierIds());
         assertEquals(MATCH_ANY, networkPriority.getRoaming());
@@ -68,6 +89,29 @@
     }
 
     @Test
+    public void testBuilderRequiresStricterEntryCriteria() {
+        try {
+            new VcnCellUnderlyingNetworkTemplate.Builder()
+                    .setMinUpstreamBandwidthKbps(
+                            TEST_MIN_EXIT_UPSTREAM_BANDWIDTH_KBPS,
+                            TEST_MIN_ENTRY_UPSTREAM_BANDWIDTH_KBPS);
+
+            fail("Expected IAE for exit threshold > entry threshold");
+        } catch (IllegalArgumentException expected) {
+        }
+
+        try {
+            new VcnCellUnderlyingNetworkTemplate.Builder()
+                    .setMinDownstreamBandwidthKbps(
+                            TEST_MIN_EXIT_DOWNSTREAM_BANDWIDTH_KBPS,
+                            TEST_MIN_ENTRY_DOWNSTREAM_BANDWIDTH_KBPS);
+
+            fail("Expected IAE for exit threshold > entry threshold");
+        } catch (IllegalArgumentException expected) {
+        }
+    }
+
+    @Test
     public void testPersistableBundle() {
         final VcnCellUnderlyingNetworkTemplate networkPriority = getTestNetworkTemplate();
         assertEquals(
diff --git a/tests/vcn/java/android/net/vcn/VcnUnderlyingNetworkTemplateTestBase.java b/tests/vcn/java/android/net/vcn/VcnUnderlyingNetworkTemplateTestBase.java
new file mode 100644
index 0000000..399e136
--- /dev/null
+++ b/tests/vcn/java/android/net/vcn/VcnUnderlyingNetworkTemplateTestBase.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.net.vcn;
+
+public class VcnUnderlyingNetworkTemplateTestBase {
+    // Public for use in NetworkPriorityClassifierTest
+    public static final int TEST_MIN_ENTRY_UPSTREAM_BANDWIDTH_KBPS = 200;
+    public static final int TEST_MIN_EXIT_UPSTREAM_BANDWIDTH_KBPS = 100;
+    public static final int TEST_MIN_ENTRY_DOWNSTREAM_BANDWIDTH_KBPS = 400;
+    public static final int TEST_MIN_EXIT_DOWNSTREAM_BANDWIDTH_KBPS = 300;
+}
diff --git a/tests/vcn/java/android/net/vcn/VcnWifiUnderlyingNetworkTemplateTest.java b/tests/vcn/java/android/net/vcn/VcnWifiUnderlyingNetworkTemplateTest.java
index cb5b47b..4063178 100644
--- a/tests/vcn/java/android/net/vcn/VcnWifiUnderlyingNetworkTemplateTest.java
+++ b/tests/vcn/java/android/net/vcn/VcnWifiUnderlyingNetworkTemplateTest.java
@@ -17,8 +17,6 @@
 
 import static android.net.vcn.VcnUnderlyingNetworkTemplate.MATCH_ANY;
 import static android.net.vcn.VcnUnderlyingNetworkTemplate.MATCH_FORBIDDEN;
-import static android.net.vcn.VcnUnderlyingNetworkTemplate.NETWORK_QUALITY_ANY;
-import static android.net.vcn.VcnUnderlyingNetworkTemplate.NETWORK_QUALITY_OK;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
@@ -28,15 +26,19 @@
 
 import java.util.Set;
 
-public class VcnWifiUnderlyingNetworkTemplateTest {
+public class VcnWifiUnderlyingNetworkTemplateTest extends VcnUnderlyingNetworkTemplateTestBase {
     private static final String SSID = "TestWifi";
-    private static final int INVALID_NETWORK_QUALITY = -1;
 
     // Package private for use in VcnGatewayConnectionConfigTest
     static VcnWifiUnderlyingNetworkTemplate getTestNetworkTemplate() {
         return new VcnWifiUnderlyingNetworkTemplate.Builder()
-                .setNetworkQuality(NETWORK_QUALITY_OK)
                 .setMetered(MATCH_FORBIDDEN)
+                .setMinUpstreamBandwidthKbps(
+                        TEST_MIN_ENTRY_UPSTREAM_BANDWIDTH_KBPS,
+                        TEST_MIN_EXIT_UPSTREAM_BANDWIDTH_KBPS)
+                .setMinDownstreamBandwidthKbps(
+                        TEST_MIN_ENTRY_DOWNSTREAM_BANDWIDTH_KBPS,
+                        TEST_MIN_EXIT_DOWNSTREAM_BANDWIDTH_KBPS)
                 .setSsids(Set.of(SSID))
                 .build();
     }
@@ -44,8 +46,19 @@
     @Test
     public void testBuilderAndGetters() {
         final VcnWifiUnderlyingNetworkTemplate networkPriority = getTestNetworkTemplate();
-        assertEquals(NETWORK_QUALITY_OK, networkPriority.getNetworkQuality());
         assertEquals(MATCH_FORBIDDEN, networkPriority.getMetered());
+        assertEquals(
+                TEST_MIN_ENTRY_UPSTREAM_BANDWIDTH_KBPS,
+                networkPriority.getMinEntryUpstreamBandwidthKbps());
+        assertEquals(
+                TEST_MIN_EXIT_UPSTREAM_BANDWIDTH_KBPS,
+                networkPriority.getMinExitUpstreamBandwidthKbps());
+        assertEquals(
+                TEST_MIN_ENTRY_DOWNSTREAM_BANDWIDTH_KBPS,
+                networkPriority.getMinEntryDownstreamBandwidthKbps());
+        assertEquals(
+                TEST_MIN_EXIT_DOWNSTREAM_BANDWIDTH_KBPS,
+                networkPriority.getMinExitDownstreamBandwidthKbps());
         assertEquals(Set.of(SSID), networkPriority.getSsids());
     }
 
@@ -53,18 +66,37 @@
     public void testBuilderAndGettersForDefaultValues() {
         final VcnWifiUnderlyingNetworkTemplate networkPriority =
                 new VcnWifiUnderlyingNetworkTemplate.Builder().build();
-        assertEquals(NETWORK_QUALITY_ANY, networkPriority.getNetworkQuality());
         assertEquals(MATCH_ANY, networkPriority.getMetered());
+
+        // Explicitly expect 0, as documented in Javadoc on setter methods..
+        assertEquals(0, networkPriority.getMinEntryUpstreamBandwidthKbps());
+        assertEquals(0, networkPriority.getMinExitUpstreamBandwidthKbps());
+        assertEquals(0, networkPriority.getMinEntryDownstreamBandwidthKbps());
+        assertEquals(0, networkPriority.getMinExitDownstreamBandwidthKbps());
+
         assertTrue(networkPriority.getSsids().isEmpty());
     }
 
     @Test
-    public void testBuildWithInvalidNetworkQuality() {
+    public void testBuilderRequiresStricterEntryCriteria() {
         try {
             new VcnWifiUnderlyingNetworkTemplate.Builder()
-                    .setNetworkQuality(INVALID_NETWORK_QUALITY);
-            fail("Expected to fail due to the invalid network quality");
-        } catch (Exception expected) {
+                    .setMinUpstreamBandwidthKbps(
+                            TEST_MIN_EXIT_UPSTREAM_BANDWIDTH_KBPS,
+                            TEST_MIN_ENTRY_UPSTREAM_BANDWIDTH_KBPS);
+
+            fail("Expected IAE for exit threshold > entry threshold");
+        } catch (IllegalArgumentException expected) {
+        }
+
+        try {
+            new VcnWifiUnderlyingNetworkTemplate.Builder()
+                    .setMinDownstreamBandwidthKbps(
+                            TEST_MIN_EXIT_DOWNSTREAM_BANDWIDTH_KBPS,
+                            TEST_MIN_ENTRY_DOWNSTREAM_BANDWIDTH_KBPS);
+
+            fail("Expected IAE for exit threshold > entry threshold");
+        } catch (IllegalArgumentException expected) {
         }
     }
 
diff --git a/tests/vcn/java/com/android/server/vcn/VcnTest.java b/tests/vcn/java/com/android/server/vcn/VcnTest.java
index 5d2f9d7..6d26968 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnTest.java
@@ -58,6 +58,7 @@
 import com.android.server.VcnManagementService.VcnCallback;
 import com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionSnapshot;
 import com.android.server.vcn.Vcn.VcnGatewayStatusCallback;
+import com.android.server.vcn.Vcn.VcnUserMobileDataStateListener;
 import com.android.server.vcn.VcnNetworkProvider.NetworkRequestListener;
 
 import org.junit.Before;
@@ -208,6 +209,13 @@
     }
 
     @Test
+    public void testMobileDataStateListenersRegistered() {
+        // Validate state from setUp()
+        verify(mTelephonyManager, times(3))
+                .registerTelephonyCallback(any(), any(VcnUserMobileDataStateListener.class));
+    }
+
+    @Test
     public void testMobileDataStateCheckedOnInitialization_enabled() {
         // Validate state from setUp()
         assertTrue(mVcn.isMobileDataEnabled());
@@ -263,6 +271,24 @@
         assertFalse(mVcn.isMobileDataEnabled());
     }
 
+    @Test
+    public void testSubscriptionSnapshotUpdatesMobileDataStateListeners() {
+        final TelephonySubscriptionSnapshot updatedSnapshot =
+                mock(TelephonySubscriptionSnapshot.class);
+
+        doReturn(new ArraySet<>(Arrays.asList(2, 4)))
+                .when(updatedSnapshot)
+                .getAllSubIdsInGroup(any());
+
+        mVcn.updateSubscriptionSnapshot(updatedSnapshot);
+        mTestLooper.dispatchAll();
+
+        verify(mTelephonyManager, times(4))
+                .registerTelephonyCallback(any(), any(VcnUserMobileDataStateListener.class));
+        verify(mTelephonyManager, times(2))
+                .unregisterTelephonyCallback(any(VcnUserMobileDataStateListener.class));
+    }
+
     private void triggerVcnRequestListeners(NetworkRequestListener requestListener) {
         for (final int[] caps : TEST_CAPS) {
             startVcnGatewayWithCapabilities(requestListener, caps);
@@ -402,24 +428,17 @@
         verify(mVcnNetworkProvider).resendAllRequests(requestListener);
     }
 
-    private void verifyMobileDataToggled(boolean startingToggleState, boolean endingToggleState) {
-        final ArgumentCaptor<ContentObserver> captor =
-                ArgumentCaptor.forClass(ContentObserver.class);
-        verify(mContentResolver).registerContentObserver(any(), anyBoolean(), captor.capture());
-        final ContentObserver contentObserver = captor.getValue();
-
+    private void setupForMobileDataTest(boolean startingToggleState) {
         // Start VcnGatewayConnections
         final NetworkRequestListener requestListener = verifyAndGetRequestListener();
         mVcn.setMobileDataEnabled(startingToggleState);
         triggerVcnRequestListeners(requestListener);
-        final Map<VcnGatewayConnectionConfig, VcnGatewayConnection> gateways =
-                mVcn.getVcnGatewayConnectionConfigMap();
+    }
 
-        // Trigger data toggle change.
-        doReturn(endingToggleState).when(mTelephonyManager).isDataEnabled();
-        contentObserver.onChange(false /* selfChange, ignored */);
-        mTestLooper.dispatchAll();
-
+    private void verifyMobileDataToggledUpdatesGatewayConnections(
+            boolean startingToggleState,
+            boolean endingToggleState,
+            Map<VcnGatewayConnectionConfig, VcnGatewayConnection> gateways) {
         // Verify that data toggle changes restart ONLY INTERNET or DUN networks, and only if the
         // toggle state changed.
         for (Entry<VcnGatewayConnectionConfig, VcnGatewayConnection> entry : gateways.entrySet()) {
@@ -433,29 +452,98 @@
             }
         }
 
+        final NetworkRequestListener requestListener = verifyAndGetRequestListener();
         if (startingToggleState != endingToggleState) {
             verify(mVcnNetworkProvider).resendAllRequests(requestListener);
         }
         assertEquals(endingToggleState, mVcn.isMobileDataEnabled());
     }
 
-    @Test
-    public void testMobileDataEnabled() {
-        verifyMobileDataToggled(false /* startingToggleState */, true /* endingToggleState */);
+    private void verifyGlobalMobileDataToggled(
+            boolean startingToggleState, boolean endingToggleState) {
+        setupForMobileDataTest(startingToggleState);
+        final Map<VcnGatewayConnectionConfig, VcnGatewayConnection> gateways =
+                mVcn.getVcnGatewayConnectionConfigMap();
+
+        // Trigger data toggle change
+        final ArgumentCaptor<ContentObserver> captor =
+                ArgumentCaptor.forClass(ContentObserver.class);
+        verify(mContentResolver).registerContentObserver(any(), anyBoolean(), captor.capture());
+        final ContentObserver contentObserver = captor.getValue();
+
+        doReturn(endingToggleState).when(mTelephonyManager).isDataEnabled();
+        contentObserver.onChange(false /* selfChange, ignored */);
+        mTestLooper.dispatchAll();
+
+        // Verify resultant behavior
+        verifyMobileDataToggledUpdatesGatewayConnections(
+                startingToggleState, endingToggleState, gateways);
     }
 
     @Test
-    public void testMobileDataDisabled() {
-        verifyMobileDataToggled(true /* startingToggleState */, false /* endingToggleState */);
+    public void testGlobalMobileDataEnabled() {
+        verifyGlobalMobileDataToggled(
+                false /* startingToggleState */, true /* endingToggleState */);
     }
 
     @Test
-    public void testMobileDataObserverFiredWithoutChanges_dataEnabled() {
-        verifyMobileDataToggled(false /* startingToggleState */, false /* endingToggleState */);
+    public void testGlobalMobileDataDisabled() {
+        verifyGlobalMobileDataToggled(
+                true /* startingToggleState */, false /* endingToggleState */);
     }
 
     @Test
-    public void testMobileDataObserverFiredWithoutChanges_dataDisabled() {
-        verifyMobileDataToggled(true /* startingToggleState */, true /* endingToggleState */);
+    public void testGlobalMobileDataObserverFiredWithoutChanges_dataEnabled() {
+        verifyGlobalMobileDataToggled(
+                false /* startingToggleState */, false /* endingToggleState */);
+    }
+
+    @Test
+    public void testGlobalMobileDataObserverFiredWithoutChanges_dataDisabled() {
+        verifyGlobalMobileDataToggled(true /* startingToggleState */, true /* endingToggleState */);
+    }
+
+    private void verifySubscriptionMobileDataToggled(
+            boolean startingToggleState, boolean endingToggleState) {
+        setupForMobileDataTest(startingToggleState);
+        final Map<VcnGatewayConnectionConfig, VcnGatewayConnection> gateways =
+                mVcn.getVcnGatewayConnectionConfigMap();
+
+        // Trigger data toggle change.
+        final ArgumentCaptor<VcnUserMobileDataStateListener> captor =
+                ArgumentCaptor.forClass(VcnUserMobileDataStateListener.class);
+        verify(mTelephonyManager, times(3)).registerTelephonyCallback(any(), captor.capture());
+        final VcnUserMobileDataStateListener listener = captor.getValue();
+
+        doReturn(endingToggleState).when(mTelephonyManager).isDataEnabled();
+        listener.onUserMobileDataStateChanged(false /* enabled, ignored */);
+        mTestLooper.dispatchAll();
+
+        // Verify resultant behavior
+        verifyMobileDataToggledUpdatesGatewayConnections(
+                startingToggleState, endingToggleState, gateways);
+    }
+
+    @Test
+    public void testSubscriptionMobileDataEnabled() {
+        verifyGlobalMobileDataToggled(
+                false /* startingToggleState */, true /* endingToggleState */);
+    }
+
+    @Test
+    public void testSubscriptionMobileDataDisabled() {
+        verifyGlobalMobileDataToggled(
+                true /* startingToggleState */, false /* endingToggleState */);
+    }
+
+    @Test
+    public void testSubscriptionMobileDataListenerFiredWithoutChanges_dataEnabled() {
+        verifyGlobalMobileDataToggled(
+                false /* startingToggleState */, false /* endingToggleState */);
+    }
+
+    @Test
+    public void testSubscriptionMobileDataListenerFiredWithoutChanges_dataDisabled() {
+        verifyGlobalMobileDataToggled(true /* startingToggleState */, true /* endingToggleState */);
     }
 }
diff --git a/tests/vcn/java/com/android/server/vcn/routeselection/NetworkPriorityClassifierTest.java b/tests/vcn/java/com/android/server/vcn/routeselection/NetworkPriorityClassifierTest.java
index 4bb7de8..6c849b5 100644
--- a/tests/vcn/java/com/android/server/vcn/routeselection/NetworkPriorityClassifierTest.java
+++ b/tests/vcn/java/com/android/server/vcn/routeselection/NetworkPriorityClassifierTest.java
@@ -18,7 +18,10 @@
 
 import static android.net.vcn.VcnUnderlyingNetworkTemplate.MATCH_FORBIDDEN;
 import static android.net.vcn.VcnUnderlyingNetworkTemplate.MATCH_REQUIRED;
-import static android.net.vcn.VcnUnderlyingNetworkTemplate.NETWORK_QUALITY_OK;
+import static android.net.vcn.VcnUnderlyingNetworkTemplateTestBase.TEST_MIN_ENTRY_DOWNSTREAM_BANDWIDTH_KBPS;
+import static android.net.vcn.VcnUnderlyingNetworkTemplateTestBase.TEST_MIN_ENTRY_UPSTREAM_BANDWIDTH_KBPS;
+import static android.net.vcn.VcnUnderlyingNetworkTemplateTestBase.TEST_MIN_EXIT_DOWNSTREAM_BANDWIDTH_KBPS;
+import static android.net.vcn.VcnUnderlyingNetworkTemplateTestBase.TEST_MIN_EXIT_UPSTREAM_BANDWIDTH_KBPS;
 
 import static com.android.server.vcn.VcnTestUtils.setupSystemService;
 import static com.android.server.vcn.routeselection.NetworkPriorityClassifier.PRIORITY_ANY;
@@ -76,6 +79,12 @@
     private static final int CARRIER_ID = 1;
     private static final int CARRIER_ID_OTHER = 2;
 
+    private static final int LINK_UPSTREAM_BANDWIDTH_KBPS = 1024;
+    private static final int LINK_DOWNSTREAM_BANDWIDTH_KBPS = 2048;
+
+    private static final int TEST_MIN_UPSTREAM_BANDWIDTH_KBPS = 100;
+    private static final int TEST_MIN_DOWNSTREAM_BANDWIDTH_KBPS = 200;
+
     private static final ParcelUuid SUB_GROUP = new ParcelUuid(new UUID(0, 0));
 
     private static final NetworkCapabilities WIFI_NETWORK_CAPABILITIES =
@@ -83,6 +92,8 @@
                     .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
                     .setSignalStrength(WIFI_RSSI)
                     .setSsid(SSID)
+                    .setLinkUpstreamBandwidthKbps(LINK_UPSTREAM_BANDWIDTH_KBPS)
+                    .setLinkDownstreamBandwidthKbps(LINK_DOWNSTREAM_BANDWIDTH_KBPS)
                     .build();
 
     private static final TelephonyNetworkSpecifier TEL_NETWORK_SPECIFIER =
@@ -93,6 +104,8 @@
                     .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
                     .setSubscriptionIds(Set.of(SUB_ID))
                     .setNetworkSpecifier(TEL_NETWORK_SPECIFIER)
+                    .setLinkUpstreamBandwidthKbps(LINK_UPSTREAM_BANDWIDTH_KBPS)
+                    .setLinkDownstreamBandwidthKbps(LINK_DOWNSTREAM_BANDWIDTH_KBPS)
                     .build();
 
     private static final LinkProperties LINK_PROPERTIES = getLinkPropertiesWithName("test_iface");
@@ -146,7 +159,6 @@
     public void testMatchWithoutNotMeteredBit() {
         final VcnWifiUnderlyingNetworkTemplate wifiNetworkPriority =
                 new VcnWifiUnderlyingNetworkTemplate.Builder()
-                        .setNetworkQuality(NETWORK_QUALITY_OK)
                         .setMetered(MATCH_FORBIDDEN)
                         .build();
 
@@ -161,11 +173,133 @@
                         null /* carrierConfig */));
     }
 
+    private void verifyMatchesPriorityRuleForUpstreamBandwidth(
+            int entryUpstreamBandwidth,
+            int exitUpstreamBandwidth,
+            UnderlyingNetworkRecord currentlySelected,
+            boolean expectMatch) {
+        final VcnWifiUnderlyingNetworkTemplate wifiNetworkPriority =
+                new VcnWifiUnderlyingNetworkTemplate.Builder()
+                        .setMinUpstreamBandwidthKbps(entryUpstreamBandwidth, exitUpstreamBandwidth)
+                        .build();
+
+        assertEquals(
+                expectMatch,
+                checkMatchesPriorityRule(
+                        mVcnContext,
+                        wifiNetworkPriority,
+                        mWifiNetworkRecord,
+                        SUB_GROUP,
+                        mSubscriptionSnapshot,
+                        currentlySelected,
+                        null /* carrierConfig */));
+    }
+
+    private void verifyMatchesPriorityRuleForDownstreamBandwidth(
+            int entryDownstreamBandwidth,
+            int exitDownstreamBandwidth,
+            UnderlyingNetworkRecord currentlySelected,
+            boolean expectMatch) {
+        final VcnWifiUnderlyingNetworkTemplate wifiNetworkPriority =
+                new VcnWifiUnderlyingNetworkTemplate.Builder()
+                        .setMinDownstreamBandwidthKbps(
+                                entryDownstreamBandwidth, exitDownstreamBandwidth)
+                        .build();
+
+        assertEquals(
+                expectMatch,
+                checkMatchesPriorityRule(
+                        mVcnContext,
+                        wifiNetworkPriority,
+                        mWifiNetworkRecord,
+                        SUB_GROUP,
+                        mSubscriptionSnapshot,
+                        currentlySelected,
+                        null /* carrierConfig */));
+    }
+
+    @Test
+    public void testMatchWithEntryUpstreamBandwidthEquals() {
+        verifyMatchesPriorityRuleForUpstreamBandwidth(
+                TEST_MIN_ENTRY_UPSTREAM_BANDWIDTH_KBPS,
+                TEST_MIN_EXIT_UPSTREAM_BANDWIDTH_KBPS,
+                null /* currentlySelected */,
+                true);
+    }
+
+    @Test
+    public void testMatchWithEntryUpstreamBandwidthTooLow() {
+        verifyMatchesPriorityRuleForUpstreamBandwidth(
+                LINK_UPSTREAM_BANDWIDTH_KBPS + 1,
+                LINK_UPSTREAM_BANDWIDTH_KBPS + 1,
+                null /* currentlySelected */,
+                false);
+    }
+
+    @Test
+    public void testMatchWithEntryDownstreamBandwidthEquals() {
+        verifyMatchesPriorityRuleForDownstreamBandwidth(
+                TEST_MIN_ENTRY_DOWNSTREAM_BANDWIDTH_KBPS,
+                TEST_MIN_EXIT_DOWNSTREAM_BANDWIDTH_KBPS,
+                null /* currentlySelected */,
+                true);
+    }
+
+    @Test
+    public void testMatchWithEntryDownstreamBandwidthTooLow() {
+        verifyMatchesPriorityRuleForDownstreamBandwidth(
+                LINK_DOWNSTREAM_BANDWIDTH_KBPS + 1,
+                LINK_DOWNSTREAM_BANDWIDTH_KBPS + 1,
+                null /* currentlySelected */,
+                false);
+    }
+
+    @Test
+    public void testMatchWithExitUpstreamBandwidthEquals() {
+        verifyMatchesPriorityRuleForUpstreamBandwidth(
+                TEST_MIN_EXIT_UPSTREAM_BANDWIDTH_KBPS,
+                TEST_MIN_EXIT_UPSTREAM_BANDWIDTH_KBPS,
+                mWifiNetworkRecord,
+                true);
+    }
+
+    @Test
+    public void testMatchWithExitUpstreamBandwidthTooLow() {
+        verifyMatchesPriorityRuleForUpstreamBandwidth(
+                LINK_UPSTREAM_BANDWIDTH_KBPS + 1,
+                LINK_UPSTREAM_BANDWIDTH_KBPS + 1,
+                mWifiNetworkRecord,
+                false);
+    }
+
+    @Test
+    public void testMatchWithExitDownstreamBandwidthEquals() {
+        verifyMatchesPriorityRuleForDownstreamBandwidth(
+                TEST_MIN_EXIT_DOWNSTREAM_BANDWIDTH_KBPS,
+                TEST_MIN_EXIT_DOWNSTREAM_BANDWIDTH_KBPS,
+                mWifiNetworkRecord,
+                true);
+    }
+
+    @Test
+    public void testMatchWithExitDownstreamBandwidthTooLow() {
+        verifyMatchesPriorityRuleForDownstreamBandwidth(
+                LINK_DOWNSTREAM_BANDWIDTH_KBPS + 1,
+                LINK_DOWNSTREAM_BANDWIDTH_KBPS + 1,
+                mWifiNetworkRecord,
+                false);
+    }
+
     private void verifyMatchWifi(
             boolean isSelectedNetwork, PersistableBundle carrierConfig, boolean expectMatch) {
         final VcnWifiUnderlyingNetworkTemplate wifiNetworkPriority =
                 new VcnWifiUnderlyingNetworkTemplate.Builder()
-                        .setNetworkQuality(NETWORK_QUALITY_OK)
+                        .setMinUpstreamBandwidthKbps(
+                                TEST_MIN_ENTRY_UPSTREAM_BANDWIDTH_KBPS,
+                                TEST_MIN_EXIT_UPSTREAM_BANDWIDTH_KBPS)
+                        .setMinDownstreamBandwidthKbps(
+                                TEST_MIN_ENTRY_DOWNSTREAM_BANDWIDTH_KBPS,
+                                TEST_MIN_EXIT_DOWNSTREAM_BANDWIDTH_KBPS)
                         .build();
         final UnderlyingNetworkRecord selectedNetworkRecord =
                 isSelectedNetwork ? mWifiNetworkRecord : null;
@@ -214,7 +348,12 @@
         final String nwPrioritySsid = useMatchedSsid ? SSID : SSID_OTHER;
         final VcnWifiUnderlyingNetworkTemplate wifiNetworkPriority =
                 new VcnWifiUnderlyingNetworkTemplate.Builder()
-                        .setNetworkQuality(NETWORK_QUALITY_OK)
+                        .setMinUpstreamBandwidthKbps(
+                                TEST_MIN_ENTRY_UPSTREAM_BANDWIDTH_KBPS,
+                                TEST_MIN_EXIT_UPSTREAM_BANDWIDTH_KBPS)
+                        .setMinDownstreamBandwidthKbps(
+                                TEST_MIN_ENTRY_DOWNSTREAM_BANDWIDTH_KBPS,
+                                TEST_MIN_EXIT_DOWNSTREAM_BANDWIDTH_KBPS)
                         .setSsids(Set.of(nwPrioritySsid))
                         .build();
 
@@ -238,7 +377,13 @@
     }
 
     private static VcnCellUnderlyingNetworkTemplate.Builder getCellNetworkPriorityBuilder() {
-        return new VcnCellUnderlyingNetworkTemplate.Builder().setNetworkQuality(NETWORK_QUALITY_OK);
+        return new VcnCellUnderlyingNetworkTemplate.Builder()
+                .setMinUpstreamBandwidthKbps(
+                        TEST_MIN_ENTRY_UPSTREAM_BANDWIDTH_KBPS,
+                        TEST_MIN_EXIT_UPSTREAM_BANDWIDTH_KBPS)
+                .setMinDownstreamBandwidthKbps(
+                        TEST_MIN_ENTRY_DOWNSTREAM_BANDWIDTH_KBPS,
+                        TEST_MIN_EXIT_DOWNSTREAM_BANDWIDTH_KBPS);
     }
 
     @Test
diff --git a/tools/aosp/aosp_sha.sh b/tools/aosp/aosp_sha.sh
index 36bea57..95b43cd 100755
--- a/tools/aosp/aosp_sha.sh
+++ b/tools/aosp/aosp_sha.sh
@@ -1,7 +1,7 @@
 #!/bin/bash
 LOCAL_DIR="$( dirname "${BASH_SOURCE}" )"
 
-if git branch -vv | grep -q -E "^\*[^\[]+\[aosp/"; then
+if git log -n 1 --format='%D' HEAD@{upstream} | grep -q aosp/; then
     # Change appears to be in AOSP
     exit 0
 elif git log -n 1 --format='%B' $1 | grep -q -E "^Ignore-AOSP-First: .+" ; then
diff --git a/tools/sdkparcelables/Android.bp b/tools/sdkparcelables/Android.bp
index 9d773e4..ec2bffd 100644
--- a/tools/sdkparcelables/Android.bp
+++ b/tools/sdkparcelables/Android.bp
@@ -14,7 +14,7 @@
         "src/**/*.kt",
     ],
     static_libs: [
-        "asm-6.0",
+        "asm-7.0",
     ],
 }
 
diff --git a/tools/sdkparcelables/src/com/android/sdkparcelables/Main.kt b/tools/sdkparcelables/src/com/android/sdkparcelables/Main.kt
index 22e8d78..0fb062f 100644
--- a/tools/sdkparcelables/src/com/android/sdkparcelables/Main.kt
+++ b/tools/sdkparcelables/src/com/android/sdkparcelables/Main.kt
@@ -39,7 +39,7 @@
         kotlin.system.exitProcess(2)
     }
 
-    val ancestorCollector = AncestorCollector(Opcodes.ASM6, null)
+    val ancestorCollector = AncestorCollector(Opcodes.ASM7, null)
 
     for (entry in zipFile.entries()) {
         if (entry.name.endsWith(".class")) {
