diff --git a/Android.bp b/Android.bp
index 457752c..60ec7e2 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: [
@@ -148,6 +144,7 @@
         "framework-minus-apex",
         "framework-appsearch.impl",
         "framework-connectivity.impl",
+        "framework-connectivity-tiramisu.impl",
         "framework-graphics.impl",
         "framework-mediaprovider.impl",
         "framework-permission.impl",
@@ -275,6 +272,7 @@
     defaults: ["framework-aidl-export-defaults"],
     srcs: [
         ":framework-non-updatable-sources",
+        ":framework-bluetooth-sources", // TODO(b/214988855) : Remove once framework-bluetooth jar is ready
         "core/java/**/*.logtags",
         ":apex-info-list",
     ],
@@ -505,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"],
@@ -513,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)
@@ -545,15 +542,6 @@
         "android.hardware.usb.gadget-V1.0-java",
         "android.hardware.vibrator-V1.3-java",
         "framework-protos",
-        "art.module.public.api",
-        "sdk_module-lib_current_framework-tethering",
-        // There are a few classes from modules used by the core that
-        // need to be resolved by metalava. We use a prebuilt stub of the
-        // full sdk to ensure we can resolve them. If a new class gets added,
-        // the prebuilts/sdk/current needs to be updated.
-        "sdk_system_current_android",
-        // NOTE: The below can be removed once the prebuilt stub contains IKE.
-        "sdk_system_current_android.net.ipsec.ike",
     ],
     filter_packages: packages_to_document,
     high_mem: true, // Lots of sources => high memory use, see b/170701554
@@ -565,6 +553,33 @@
     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",
+        "sdk_public_current_framework-bluetooth",
+        // There are a few classes from modules used by the core that
+        // need to be resolved by metalava. We use a prebuilt stub of the
+        // full sdk to ensure we can resolve them. If a new class gets added,
+        // the prebuilts/sdk/current needs to be updated.
+        "sdk_system_current_android",
+        // NOTE: The below can be removed once the prebuilt stub contains IKE.
+        "sdk_system_current_android.net.ipsec.ike",
+    ],
+    defaults_visibility: ["//visibility:private"],
+}
+
 build = [
     "StubLibraries.bp",
     "ApiDocs.bp",
diff --git a/ApiDocs.bp b/ApiDocs.bp
index 4b5f473..5595e95 100644
--- a/ApiDocs.bp
+++ b/ApiDocs.bp
@@ -55,6 +55,7 @@
     "android-support-multidex-instrumentation",
 ]
 
+// These defaults enable doc-stub generation, api lint database generation and sdk value generation.
 stubs_defaults {
     name: "android-non-updatable-doc-stubs-defaults",
     defaults: ["android-non-updatable-stubs-defaults"],
@@ -69,47 +70,10 @@
     write_sdk_values: true,
 }
 
-stubs_defaults {
-    name: "framework-doc-stubs-default",
-    srcs: [
-        ":android-non-updatable-stub-sources",
-
-        // 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.
 stubs_defaults {
     name: "framework-doc-stubs-sources-default",
-    defaults: ["framework-doc-stubs-default"],
+    defaults: ["android-non-updatable-doc-stubs-defaults"],
     srcs: [
         ":art.module.public.api{.public.stubs.source}",
         ":conscrypt.module.public.api{.public.stubs.source}",
@@ -117,6 +81,8 @@
 
         ":framework-appsearch-sources",
         ":framework-connectivity-sources",
+        ":framework-bluetooth-sources",
+        ":framework-connectivity-tiramisu-updatable-sources",
         ":framework-graphics-srcs",
         ":framework-mediaprovider-sources",
         ":framework-permission-sources",
@@ -133,13 +99,19 @@
 
 droidstubs {
     name: "android-non-updatable-doc-stubs",
-    defaults: ["android-non-updatable-doc-stubs-defaults"],
+    defaults: [
+        "android-non-updatable-doc-stubs-defaults",
+        "module-classpath-stubs-defaults",
+    ],
     args: metalava_framework_docs_args,
 }
 
 droidstubs {
     name: "android-non-updatable-doc-stubs-system",
-    defaults: ["android-non-updatable-doc-stubs-defaults"],
+    defaults: [
+        "android-non-updatable-doc-stubs-defaults",
+        "module-classpath-stubs-defaults",
+    ],
     args: metalava_framework_docs_args +
         " --show-annotation android.annotation.SystemApi\\(client=android.annotation.SystemApi.Client.PRIVILEGED_APPS\\) ",
 }
@@ -149,14 +121,24 @@
     defaults: ["framework-doc-stubs-sources-default"],
     args: metalava_framework_docs_args +
         " --show-annotation android.annotation.SystemApi\\(client=android.annotation.SystemApi.Client.PRIVILEGED_APPS\\) ",
+    api_levels_annotations_enabled: true,
+    api_levels_annotations_dirs: [
+        "sdk-dir",
+        "api-versions-jars-dir",
+    ],
     api_levels_sdk_type: "system",
 }
 
 droidstubs {
     name: "framework-doc-stubs",
-    defaults: ["framework-doc-stubs-default"],
+    defaults: ["android-non-updatable-doc-stubs-defaults"],
     srcs: [":all-modules-public-stubs-source"],
     args: metalava_framework_docs_args,
+    api_levels_annotations_enabled: true,
+    api_levels_annotations_dirs: [
+        "sdk-dir",
+        "api-versions-jars-dir",
+    ],
     aidl: {
         local_include_dirs: [
             "apex/media/aidl/stable",
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 14da6fb..5cb0a78 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: {
@@ -206,44 +207,6 @@
 // from stub sources
 /////////////////////////////////////////////////////////////////////
 
-modules_public_stubs = [
-    "android.net.ipsec.ike.stubs",
-    "art.module.public.api.stubs",
-    "conscrypt.module.public.api.stubs",
-    "framework-appsearch.stubs",
-    "framework-connectivity.stubs",
-    "framework-graphics.stubs",
-    "framework-media.stubs",
-    "framework-mediaprovider.stubs",
-    "framework-permission.stubs",
-    "framework-permission-s.stubs",
-    "framework-scheduling.stubs",
-    "framework-sdkextensions.stubs",
-    "framework-statsd.stubs",
-    "framework-tethering.stubs",
-    "framework-wifi.stubs",
-    "i18n.module.public.api.stubs",
-]
-
-modules_system_stubs = [
-    "android.net.ipsec.ike.stubs.system",
-    "art.module.public.api.stubs.system",
-    "conscrypt.module.public.api.stubs", // Only has public stubs
-    "framework-appsearch.stubs.system",
-    "framework-connectivity.stubs.system",
-    "framework-graphics.stubs.system",
-    "framework-media.stubs.system",
-    "framework-mediaprovider.stubs.system",
-    "framework-permission.stubs.system",
-    "framework-permission-s.stubs.system",
-    "framework-scheduling.stubs.system",
-    "framework-sdkextensions.stubs.system",
-    "framework-statsd.stubs.system",
-    "framework-tethering.stubs.system",
-    "framework-wifi.stubs.system",
-    "i18n.module.public.api.stubs", // Only has public stubs
-]
-
 java_defaults {
     name: "android-non-updatable_defaults_stubs_current",
     libs: ["stub-annotations"],
@@ -265,7 +228,7 @@
     name: "android-non-updatable.stubs",
     defaults: ["android-non-updatable_defaults_stubs_current"],
     srcs: [":api-stubs-docs-non-updatable"],
-    libs: modules_public_stubs,
+    libs: ["all-modules-public-stubs"],
     dist: {
         dir: "apistubs/android/public",
     },
@@ -275,7 +238,7 @@
     name: "android-non-updatable.stubs.system",
     defaults: ["android-non-updatable_defaults_stubs_current"],
     srcs: [":system-api-stubs-docs-non-updatable"],
-    libs: modules_system_stubs,
+    libs: ["all-modules-system-stubs"],
     dist: {
         dir: "apistubs/android/system",
     },
@@ -287,6 +250,8 @@
     srcs: [":module-lib-api-stubs-docs-non-updatable"],
     libs: [
         "sdk_module-lib_current_framework-tethering",
+        "sdk_public_current_framework-bluetooth",
+        // NOTE: The below can be removed once the prebuilt stub contains bluetooth.
         "sdk_system_current_android",
         // NOTE: The below can be removed once the prebuilt stub contains IKE.
         "sdk_system_current_android.net.ipsec.ike",
@@ -300,7 +265,7 @@
     name: "android-non-updatable.stubs.test",
     defaults: ["android-non-updatable_defaults_stubs_current"],
     srcs: [":test-api-stubs-docs-non-updatable"],
-    libs: modules_system_stubs,
+    libs: ["all-modules-system-stubs"],
     dist: {
         dir: "apistubs/android/test",
     },
@@ -318,7 +283,8 @@
 
 java_library {
     name: "android_stubs_current",
-    static_libs: modules_public_stubs + [
+    static_libs: [
+        "all-modules-public-stubs",
         "android-non-updatable.stubs",
         "private-stub-annotations-jar",
     ],
@@ -327,7 +293,8 @@
 
 java_library {
     name: "android_system_stubs_current",
-    static_libs: modules_system_stubs + [
+    static_libs: [
+        "all-modules-system-stubs",
         "android-non-updatable.stubs.system",
         "private-stub-annotations-jar",
     ],
@@ -352,7 +319,8 @@
     name: "android_test_stubs_current",
     // Modules do not have test APIs, but we want to include their SystemApis, like we include
     // the SystemApi of framework-non-updatable-sources.
-    static_libs: modules_system_stubs + [
+    static_libs: [
+        "all-modules-system-stubs",
         "android-non-updatable.stubs.test",
         "private-stub-annotations-jar",
     ],
diff --git a/api/Android.bp b/api/Android.bp
index d5d2105..15356bd 100644
--- a/api/Android.bp
+++ b/api/Android.bp
@@ -110,7 +110,9 @@
         "art.module.public.api",
         "conscrypt.module.public.api",
         "framework-appsearch",
+        "framework-bluetooth",
         "framework-connectivity",
+        "framework-connectivity-tiramisu",
         "framework-graphics",
         "framework-media",
         "framework-mediaprovider",
diff --git a/api/api.go b/api/api.go
index 4b6ebc1..aa9e399e 100644
--- a/api/api.go
+++ b/api/api.go
@@ -27,6 +27,7 @@
 const art = "art.module.public.api"
 const conscrypt = "conscrypt.module.public.api"
 const i18n = "i18n.module.public.api"
+var modules_with_only_public_scope = []string{i18n, conscrypt}
 
 // 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
@@ -183,6 +184,27 @@
 	ctx.CreateModule(genrule.GenRuleFactory, &props)
 }
 
+func createMergedPublicStubs(ctx android.LoadHookContext, modules []string) {
+	props := libraryProps{}
+	props.Name = proptools.StringPtr("all-modules-public-stubs")
+	props.Static_libs = transformArray(modules, "", ".stubs")
+	props.Sdk_version = proptools.StringPtr("module_current")
+	props.Visibility = []string{"//frameworks/base"}
+	ctx.CreateModule(java.LibraryFactory, &props)
+}
+
+func createMergedSystemStubs(ctx android.LoadHookContext, modules []string) {
+	props := libraryProps{}
+	modules_with_system_stubs := removeAll(modules, modules_with_only_public_scope)
+	props.Name = proptools.StringPtr("all-modules-system-stubs")
+	props.Static_libs = append(
+		transformArray(modules_with_only_public_scope, "", ".stubs"),
+		transformArray(modules_with_system_stubs, "", ".stubs.system")...)
+	props.Sdk_version = proptools.StringPtr("module_current")
+	props.Visibility = []string{"//frameworks/base"}
+	ctx.CreateModule(java.LibraryFactory, &props)
+}
+
 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})
@@ -205,7 +227,7 @@
 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})
+	bcpWithSystemApi := removeAll(bootclasspath, modules_with_only_public_scope)
 
 	tagSuffix := []string{".api.txt}", ".removed-api.txt}"}
 	for i, f := range []string{"current.txt", "removed.txt"} {
@@ -253,6 +275,8 @@
 
 	createMergedStubsSrcjar(ctx, bootclasspath)
 
+	createMergedPublicStubs(ctx, bootclasspath)
+	createMergedSystemStubs(ctx, bootclasspath)
 	createMergedModuleLibStubs(ctx, bootclasspath)
 
 	createMergedAnnotations(ctx, bootclasspath)
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 d696bc7..a32a3a9 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
@@ -8616,1317 +8644,6 @@
 
 }
 
-package android.bluetooth {
-
-  public final class BluetoothA2dp implements android.bluetooth.BluetoothProfile {
-    method public void finalize();
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices();
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int getConnectionState(android.bluetooth.BluetoothDevice);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public java.util.List<android.bluetooth.BluetoothDevice> getDevicesMatchingConnectionStates(int[]);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean isA2dpPlaying(android.bluetooth.BluetoothDevice);
-    field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.a2dp.profile.action.CONNECTION_STATE_CHANGED";
-    field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_PLAYING_STATE_CHANGED = "android.bluetooth.a2dp.profile.action.PLAYING_STATE_CHANGED";
-    field public static final int STATE_NOT_PLAYING = 11; // 0xb
-    field public static final int STATE_PLAYING = 10; // 0xa
-  }
-
-  public final class BluetoothAdapter {
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public boolean cancelDiscovery();
-    method public static boolean checkBluetoothAddress(String);
-    method public void closeProfileProxy(int, android.bluetooth.BluetoothProfile);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean disable();
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean enable();
-    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, "android.permission.LOCAL_MAC_ADDRESS"}) public String getAddress();
-    method public android.bluetooth.le.BluetoothLeAdvertiser getBluetoothLeAdvertiser();
-    method public android.bluetooth.le.BluetoothLeScanner getBluetoothLeScanner();
-    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 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);
-    method public android.bluetooth.BluetoothDevice getRemoteDevice(String);
-    method public android.bluetooth.BluetoothDevice getRemoteDevice(byte[]);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public int getScanMode();
-    method public int getState();
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public boolean isDiscovering();
-    method public boolean isEnabled();
-    method public boolean isLe2MPhySupported();
-    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();
-    method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public android.bluetooth.BluetoothServerSocket listenUsingInsecureL2capChannel() throws java.io.IOException;
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public android.bluetooth.BluetoothServerSocket listenUsingInsecureRfcommWithServiceRecord(String, java.util.UUID) throws java.io.IOException;
-    method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public android.bluetooth.BluetoothServerSocket listenUsingL2capChannel() throws java.io.IOException;
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public android.bluetooth.BluetoothServerSocket listenUsingRfcommWithServiceRecord(String, java.util.UUID) throws java.io.IOException;
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean setName(String);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public boolean startDiscovery();
-    method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public boolean startLeScan(android.bluetooth.BluetoothAdapter.LeScanCallback);
-    method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public boolean startLeScan(java.util.UUID[], android.bluetooth.BluetoothAdapter.LeScanCallback);
-    method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public void stopLeScan(android.bluetooth.BluetoothAdapter.LeScanCallback);
-    field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.adapter.action.CONNECTION_STATE_CHANGED";
-    field @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public static final String ACTION_DISCOVERY_FINISHED = "android.bluetooth.adapter.action.DISCOVERY_FINISHED";
-    field @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public static final String ACTION_DISCOVERY_STARTED = "android.bluetooth.adapter.action.DISCOVERY_STARTED";
-    field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_LOCAL_NAME_CHANGED = "android.bluetooth.adapter.action.LOCAL_NAME_CHANGED";
-    field @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) public static final String ACTION_REQUEST_DISCOVERABLE = "android.bluetooth.adapter.action.REQUEST_DISCOVERABLE";
-    field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_REQUEST_ENABLE = "android.bluetooth.adapter.action.REQUEST_ENABLE";
-    field @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public static final String ACTION_SCAN_MODE_CHANGED = "android.bluetooth.adapter.action.SCAN_MODE_CHANGED";
-    field public static final String ACTION_STATE_CHANGED = "android.bluetooth.adapter.action.STATE_CHANGED";
-    field public static final int ERROR = -2147483648; // 0x80000000
-    field public static final String EXTRA_CONNECTION_STATE = "android.bluetooth.adapter.extra.CONNECTION_STATE";
-    field public static final String EXTRA_DISCOVERABLE_DURATION = "android.bluetooth.adapter.extra.DISCOVERABLE_DURATION";
-    field public static final String EXTRA_LOCAL_NAME = "android.bluetooth.adapter.extra.LOCAL_NAME";
-    field public static final String EXTRA_PREVIOUS_CONNECTION_STATE = "android.bluetooth.adapter.extra.PREVIOUS_CONNECTION_STATE";
-    field public static final String EXTRA_PREVIOUS_SCAN_MODE = "android.bluetooth.adapter.extra.PREVIOUS_SCAN_MODE";
-    field public static final String EXTRA_PREVIOUS_STATE = "android.bluetooth.adapter.extra.PREVIOUS_STATE";
-    field public static final String EXTRA_SCAN_MODE = "android.bluetooth.adapter.extra.SCAN_MODE";
-    field public static final String EXTRA_STATE = "android.bluetooth.adapter.extra.STATE";
-    field public static final int SCAN_MODE_CONNECTABLE = 21; // 0x15
-    field public static final int SCAN_MODE_CONNECTABLE_DISCOVERABLE = 23; // 0x17
-    field public static final int SCAN_MODE_NONE = 20; // 0x14
-    field public static final int STATE_CONNECTED = 2; // 0x2
-    field public static final int STATE_CONNECTING = 1; // 0x1
-    field public static final int STATE_DISCONNECTED = 0; // 0x0
-    field public static final int STATE_DISCONNECTING = 3; // 0x3
-    field public static final int STATE_OFF = 10; // 0xa
-    field public static final int STATE_ON = 12; // 0xc
-    field public static final int STATE_TURNING_OFF = 13; // 0xd
-    field public static final int STATE_TURNING_ON = 11; // 0xb
-  }
-
-  public static interface BluetoothAdapter.LeScanCallback {
-    method public void onLeScan(android.bluetooth.BluetoothDevice, int, byte[]);
-  }
-
-  public class BluetoothAssignedNumbers {
-    field public static final int AAMP_OF_AMERICA = 190; // 0xbe
-    field public static final int ACCEL_SEMICONDUCTOR = 74; // 0x4a
-    field public static final int ACE_SENSOR = 188; // 0xbc
-    field public static final int ADIDAS = 195; // 0xc3
-    field public static final int ADVANCED_PANMOBIL_SYSTEMS = 145; // 0x91
-    field public static final int AIROHA_TECHNOLOGY = 148; // 0x94
-    field public static final int ALCATEL = 36; // 0x24
-    field public static final int ALPWISE = 154; // 0x9a
-    field public static final int AMICCOM_ELECTRONICS = 192; // 0xc0
-    field public static final int APLIX = 189; // 0xbd
-    field public static final int APPLE = 76; // 0x4c
-    field public static final int APT_LICENSING = 79; // 0x4f
-    field public static final int ARCHOS = 207; // 0xcf
-    field public static final int ARP_DEVICES = 168; // 0xa8
-    field public static final int ATHEROS_COMMUNICATIONS = 69; // 0x45
-    field public static final int ATMEL = 19; // 0x13
-    field public static final int AUSTCO_COMMUNICATION_SYSTEMS = 213; // 0xd5
-    field public static final int AUTONET_MOBILE = 127; // 0x7f
-    field public static final int AVAGO = 78; // 0x4e
-    field public static final int AVM_BERLIN = 31; // 0x1f
-    field public static final int A_AND_D_ENGINEERING = 105; // 0x69
-    field public static final int A_AND_R_CAMBRIDGE = 124; // 0x7c
-    field public static final int BANDSPEED = 32; // 0x20
-    field public static final int BAND_XI_INTERNATIONAL = 100; // 0x64
-    field public static final int BDE_TECHNOLOGY = 180; // 0xb4
-    field public static final int BEATS_ELECTRONICS = 204; // 0xcc
-    field public static final int BEAUTIFUL_ENTERPRISE = 108; // 0x6c
-    field public static final int BEKEY = 178; // 0xb2
-    field public static final int BELKIN_INTERNATIONAL = 92; // 0x5c
-    field public static final int BINAURIC = 203; // 0xcb
-    field public static final int BIOSENTRONICS = 219; // 0xdb
-    field public static final int BLUEGIGA = 71; // 0x47
-    field public static final int BLUERADIOS = 133; // 0x85
-    field public static final int BLUETOOTH_SIG = 63; // 0x3f
-    field public static final int BLUETREK_TECHNOLOGIES = 151; // 0x97
-    field public static final int BOSE = 158; // 0x9e
-    field public static final int BRIARTEK = 109; // 0x6d
-    field public static final int BROADCOM = 15; // 0xf
-    field public static final int CAEN_RFID = 170; // 0xaa
-    field public static final int CAMBRIDGE_SILICON_RADIO = 10; // 0xa
-    field public static final int CATC = 52; // 0x34
-    field public static final int CINETIX = 175; // 0xaf
-    field public static final int CLARINOX_TECHNOLOGIES = 179; // 0xb3
-    field public static final int COLORFY = 156; // 0x9c
-    field public static final int COMMIL = 51; // 0x33
-    field public static final int CONEXANT_SYSTEMS = 28; // 0x1c
-    field public static final int CONNECTBLUE = 113; // 0x71
-    field public static final int CONTINENTAL_AUTOMOTIVE = 75; // 0x4b
-    field public static final int CONWISE_TECHNOLOGY = 66; // 0x42
-    field public static final int CREATIVE_TECHNOLOGY = 118; // 0x76
-    field public static final int C_TECHNOLOGIES = 38; // 0x26
-    field public static final int DANLERS = 225; // 0xe1
-    field public static final int DELORME_PUBLISHING_COMPANY = 128; // 0x80
-    field public static final int DEXCOM = 208; // 0xd0
-    field public static final int DIALOG_SEMICONDUCTOR = 210; // 0xd2
-    field public static final int DIGIANSWER = 12; // 0xc
-    field public static final int ECLIPSE = 53; // 0x35
-    field public static final int ECOTEST = 136; // 0x88
-    field public static final int ELGATO_SYSTEMS = 206; // 0xce
-    field public static final int EM_MICROELECTRONIC_MARIN = 90; // 0x5a
-    field public static final int EQUINOX_AG = 134; // 0x86
-    field public static final int ERICSSON_TECHNOLOGY = 0; // 0x0
-    field public static final int EVLUMA = 201; // 0xc9
-    field public static final int FREE2MOVE = 83; // 0x53
-    field public static final int FUNAI_ELECTRIC = 144; // 0x90
-    field public static final int GARMIN_INTERNATIONAL = 135; // 0x87
-    field public static final int GCT_SEMICONDUCTOR = 45; // 0x2d
-    field public static final int GELO = 200; // 0xc8
-    field public static final int GENEQ = 194; // 0xc2
-    field public static final int GENERAL_MOTORS = 104; // 0x68
-    field public static final int GENNUM = 59; // 0x3b
-    field public static final int GEOFORCE = 157; // 0x9d
-    field public static final int GIBSON_GUITARS = 98; // 0x62
-    field public static final int GN_NETCOM = 103; // 0x67
-    field public static final int GN_RESOUND = 137; // 0x89
-    field public static final int GOOGLE = 224; // 0xe0
-    field public static final int GREEN_THROTTLE_GAMES = 172; // 0xac
-    field public static final int GROUP_SENSE = 115; // 0x73
-    field public static final int HANLYNN_TECHNOLOGIES = 123; // 0x7b
-    field public static final int HARMAN_INTERNATIONAL = 87; // 0x57
-    field public static final int HEWLETT_PACKARD = 101; // 0x65
-    field public static final int HITACHI = 41; // 0x29
-    field public static final int HOSIDEN = 221; // 0xdd
-    field public static final int IBM = 3; // 0x3
-    field public static final int INFINEON_TECHNOLOGIES = 9; // 0x9
-    field public static final int INGENIEUR_SYSTEMGRUPPE_ZAHN = 171; // 0xab
-    field public static final int INTEGRATED_SILICON_SOLUTION = 65; // 0x41
-    field public static final int INTEGRATED_SYSTEM_SOLUTION = 57; // 0x39
-    field public static final int INTEL = 2; // 0x2
-    field public static final int INVENTEL = 30; // 0x1e
-    field public static final int IPEXTREME = 61; // 0x3d
-    field public static final int I_TECH_DYNAMIC_GLOBAL_DISTRIBUTION = 153; // 0x99
-    field public static final int JAWBONE = 138; // 0x8a
-    field public static final int JIANGSU_TOPPOWER_AUTOMOTIVE_ELECTRONICS = 155; // 0x9b
-    field public static final int JOHNSON_CONTROLS = 185; // 0xb9
-    field public static final int J_AND_M = 82; // 0x52
-    field public static final int KAWANTECH = 212; // 0xd4
-    field public static final int KC_TECHNOLOGY = 22; // 0x16
-    field public static final int KENSINGTON_COMPUTER_PRODUCTS_GROUP = 160; // 0xa0
-    field public static final int LAIRD_TECHNOLOGIES = 119; // 0x77
-    field public static final int LESSWIRE = 121; // 0x79
-    field public static final int LG_ELECTRONICS = 196; // 0xc4
-    field public static final int LINAK = 164; // 0xa4
-    field public static final int LUCENT = 7; // 0x7
-    field public static final int LUDUS_HELSINKI = 132; // 0x84
-    field public static final int MACRONIX = 44; // 0x2c
-    field public static final int MAGNETI_MARELLI = 169; // 0xa9
-    field public static final int MANSELLA = 33; // 0x21
-    field public static final int MARVELL = 72; // 0x48
-    field public static final int MATSUSHITA_ELECTRIC = 58; // 0x3a
-    field public static final int MC10 = 202; // 0xca
-    field public static final int MEDIATEK = 70; // 0x46
-    field public static final int MESO_INTERNATIONAL = 182; // 0xb6
-    field public static final int META_WATCH = 163; // 0xa3
-    field public static final int MEWTEL_TECHNOLOGY = 47; // 0x2f
-    field public static final int MICOMMAND = 99; // 0x63
-    field public static final int MICROCHIP_TECHNOLOGY = 205; // 0xcd
-    field public static final int MICROSOFT = 6; // 0x6
-    field public static final int MINDTREE = 106; // 0x6a
-    field public static final int MISFIT_WEARABLES = 223; // 0xdf
-    field public static final int MITEL_SEMICONDUCTOR = 16; // 0x10
-    field public static final int MITSUBISHI_ELECTRIC = 20; // 0x14
-    field public static final int MOBILIAN_CORPORATION = 55; // 0x37
-    field public static final int MONSTER = 112; // 0x70
-    field public static final int MOTOROLA = 8; // 0x8
-    field public static final int MSTAR_SEMICONDUCTOR = 122; // 0x7a
-    field public static final int MUZIK = 222; // 0xde
-    field public static final int NEC = 34; // 0x22
-    field public static final int NEC_LIGHTING = 149; // 0x95
-    field public static final int NEWLOGIC = 23; // 0x17
-    field public static final int NIKE = 120; // 0x78
-    field public static final int NINE_SOLUTIONS = 102; // 0x66
-    field public static final int NOKIA_MOBILE_PHONES = 1; // 0x1
-    field public static final int NORDIC_SEMICONDUCTOR = 89; // 0x59
-    field public static final int NORWOOD_SYSTEMS = 46; // 0x2e
-    field public static final int ODM_TECHNOLOGY = 150; // 0x96
-    field public static final int OMEGAWAVE = 174; // 0xae
-    field public static final int ONSET_COMPUTER = 197; // 0xc5
-    field public static final int OPEN_INTERFACE = 39; // 0x27
-    field public static final int OTL_DYNAMICS = 165; // 0xa5
-    field public static final int PANDA_OCEAN = 166; // 0xa6
-    field public static final int PARROT = 67; // 0x43
-    field public static final int PARTHUS_TECHNOLOGIES = 14; // 0xe
-    field public static final int PASSIF_SEMICONDUCTOR = 176; // 0xb0
-    field public static final int PETER_SYSTEMTECHNIK = 173; // 0xad
-    field public static final int PHILIPS_SEMICONDUCTORS = 37; // 0x25
-    field public static final int PLANTRONICS = 85; // 0x55
-    field public static final int POLAR_ELECTRO = 107; // 0x6b
-    field public static final int POLAR_ELECTRO_EUROPE = 209; // 0xd1
-    field public static final int PROCTER_AND_GAMBLE = 220; // 0xdc
-    field public static final int QUALCOMM = 29; // 0x1d
-    field public static final int QUALCOMM_CONNECTED_EXPERIENCES = 216; // 0xd8
-    field public static final int QUALCOMM_INNOVATION_CENTER = 184; // 0xb8
-    field public static final int QUALCOMM_LABS = 140; // 0x8c
-    field public static final int QUALCOMM_TECHNOLOGIES = 215; // 0xd7
-    field public static final int QUINTIC = 142; // 0x8e
-    field public static final int QUUPPA = 199; // 0xc7
-    field public static final int RALINK_TECHNOLOGY = 91; // 0x5b
-    field public static final int RDA_MICROELECTRONICS = 97; // 0x61
-    field public static final int REALTEK_SEMICONDUCTOR = 93; // 0x5d
-    field public static final int RED_M = 50; // 0x32
-    field public static final int RENESAS_TECHNOLOGY = 54; // 0x36
-    field public static final int RESEARCH_IN_MOTION = 60; // 0x3c
-    field public static final int RF_MICRO_DEVICES = 40; // 0x28
-    field public static final int RIVIERAWAVES = 96; // 0x60
-    field public static final int ROHDE_AND_SCHWARZ = 25; // 0x19
-    field public static final int RTX_TELECOM = 21; // 0x15
-    field public static final int SAMSUNG_ELECTRONICS = 117; // 0x75
-    field public static final int SARIS_CYCLING_GROUP = 177; // 0xb1
-    field public static final int SEERS_TECHNOLOGY = 125; // 0x7d
-    field public static final int SEIKO_EPSON = 64; // 0x40
-    field public static final int SELFLY = 198; // 0xc6
-    field public static final int SEMILINK = 226; // 0xe2
-    field public static final int SENNHEISER_COMMUNICATIONS = 130; // 0x82
-    field public static final int SHANGHAI_SUPER_SMART_ELECTRONICS = 114; // 0x72
-    field public static final int SHENZHEN_EXCELSECU_DATA_TECHNOLOGY = 193; // 0xc1
-    field public static final int SIGNIA_TECHNOLOGIES = 27; // 0x1b
-    field public static final int SILICON_WAVE = 11; // 0xb
-    field public static final int SIRF_TECHNOLOGY = 80; // 0x50
-    field public static final int SOCKET_MOBILE = 68; // 0x44
-    field public static final int SONY_ERICSSON = 86; // 0x56
-    field public static final int SOUND_ID = 111; // 0x6f
-    field public static final int SPORTS_TRACKING_TECHNOLOGIES = 126; // 0x7e
-    field public static final int SR_MEDIZINELEKTRONIK = 161; // 0xa1
-    field public static final int STACCATO_COMMUNICATIONS = 77; // 0x4d
-    field public static final int STALMART_TECHNOLOGY = 191; // 0xbf
-    field public static final int STARKEY_LABORATORIES = 186; // 0xba
-    field public static final int STOLLMAN_E_PLUS_V = 143; // 0x8f
-    field public static final int STONESTREET_ONE = 94; // 0x5e
-    field public static final int ST_MICROELECTRONICS = 48; // 0x30
-    field public static final int SUMMIT_DATA_COMMUNICATIONS = 110; // 0x6e
-    field public static final int SUUNTO = 159; // 0x9f
-    field public static final int SWIRL_NETWORKS = 181; // 0xb5
-    field public static final int SYMBOL_TECHNOLOGIES = 42; // 0x2a
-    field public static final int SYNOPSYS = 49; // 0x31
-    field public static final int SYSTEMS_AND_CHIPS = 62; // 0x3e
-    field public static final int S_POWER_ELECTRONICS = 187; // 0xbb
-    field public static final int TAIXINGBANG_TECHNOLOGY = 211; // 0xd3
-    field public static final int TENOVIS = 43; // 0x2b
-    field public static final int TERAX = 56; // 0x38
-    field public static final int TEXAS_INSTRUMENTS = 13; // 0xd
-    field public static final int THINKOPTICS = 146; // 0x92
-    field public static final int THREECOM = 5; // 0x5
-    field public static final int THREE_DIJOY = 84; // 0x54
-    field public static final int THREE_DSP = 73; // 0x49
-    field public static final int TIMEKEEPING_SYSTEMS = 131; // 0x83
-    field public static final int TIMEX_GROUP_USA = 214; // 0xd6
-    field public static final int TOPCORN_POSITIONING_SYSTEMS = 139; // 0x8b
-    field public static final int TOSHIBA = 4; // 0x4
-    field public static final int TRANSILICA = 24; // 0x18
-    field public static final int TRELAB = 183; // 0xb7
-    field public static final int TTPCOM = 26; // 0x1a
-    field public static final int TXTR = 218; // 0xda
-    field public static final int TZERO_TECHNOLOGIES = 81; // 0x51
-    field public static final int UNIVERSAL_ELECTRONICS = 147; // 0x93
-    field public static final int VERTU = 162; // 0xa2
-    field public static final int VISTEON = 167; // 0xa7
-    field public static final int VIZIO = 88; // 0x58
-    field public static final int VOYETRA_TURTLE_BEACH = 217; // 0xd9
-    field public static final int WAVEPLUS_TECHNOLOGY = 35; // 0x23
-    field public static final int WICENTRIC = 95; // 0x5f
-    field public static final int WIDCOMM = 17; // 0x11
-    field public static final int WUXI_VIMICRO = 129; // 0x81
-    field public static final int ZEEVO = 18; // 0x12
-    field public static final int ZER01_TV = 152; // 0x98
-    field public static final int ZOMM = 116; // 0x74
-    field public static final int ZSCAN_SOFTWARE = 141; // 0x8d
-  }
-
-  public final class BluetoothClass implements android.os.Parcelable {
-    method public int describeContents();
-    method public int getDeviceClass();
-    method public int getMajorDeviceClass();
-    method public boolean hasService(int);
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BluetoothClass> CREATOR;
-  }
-
-  public static class BluetoothClass.Device {
-    ctor public BluetoothClass.Device();
-    field public static final int AUDIO_VIDEO_CAMCORDER = 1076; // 0x434
-    field public static final int AUDIO_VIDEO_CAR_AUDIO = 1056; // 0x420
-    field public static final int AUDIO_VIDEO_HANDSFREE = 1032; // 0x408
-    field public static final int AUDIO_VIDEO_HEADPHONES = 1048; // 0x418
-    field public static final int AUDIO_VIDEO_HIFI_AUDIO = 1064; // 0x428
-    field public static final int AUDIO_VIDEO_LOUDSPEAKER = 1044; // 0x414
-    field public static final int AUDIO_VIDEO_MICROPHONE = 1040; // 0x410
-    field public static final int AUDIO_VIDEO_PORTABLE_AUDIO = 1052; // 0x41c
-    field public static final int AUDIO_VIDEO_SET_TOP_BOX = 1060; // 0x424
-    field public static final int AUDIO_VIDEO_UNCATEGORIZED = 1024; // 0x400
-    field public static final int AUDIO_VIDEO_VCR = 1068; // 0x42c
-    field public static final int AUDIO_VIDEO_VIDEO_CAMERA = 1072; // 0x430
-    field public static final int AUDIO_VIDEO_VIDEO_CONFERENCING = 1088; // 0x440
-    field public static final int AUDIO_VIDEO_VIDEO_DISPLAY_AND_LOUDSPEAKER = 1084; // 0x43c
-    field public static final int AUDIO_VIDEO_VIDEO_GAMING_TOY = 1096; // 0x448
-    field public static final int AUDIO_VIDEO_VIDEO_MONITOR = 1080; // 0x438
-    field public static final int AUDIO_VIDEO_WEARABLE_HEADSET = 1028; // 0x404
-    field public static final int COMPUTER_DESKTOP = 260; // 0x104
-    field public static final int COMPUTER_HANDHELD_PC_PDA = 272; // 0x110
-    field public static final int COMPUTER_LAPTOP = 268; // 0x10c
-    field public static final int COMPUTER_PALM_SIZE_PC_PDA = 276; // 0x114
-    field public static final int COMPUTER_SERVER = 264; // 0x108
-    field public static final int COMPUTER_UNCATEGORIZED = 256; // 0x100
-    field public static final int COMPUTER_WEARABLE = 280; // 0x118
-    field public static final int HEALTH_BLOOD_PRESSURE = 2308; // 0x904
-    field public static final int HEALTH_DATA_DISPLAY = 2332; // 0x91c
-    field public static final int HEALTH_GLUCOSE = 2320; // 0x910
-    field public static final int HEALTH_PULSE_OXIMETER = 2324; // 0x914
-    field public static final int HEALTH_PULSE_RATE = 2328; // 0x918
-    field public static final int HEALTH_THERMOMETER = 2312; // 0x908
-    field public static final int HEALTH_UNCATEGORIZED = 2304; // 0x900
-    field public static final int HEALTH_WEIGHING = 2316; // 0x90c
-    field public static final int PHONE_CELLULAR = 516; // 0x204
-    field public static final int PHONE_CORDLESS = 520; // 0x208
-    field public static final int PHONE_ISDN = 532; // 0x214
-    field public static final int PHONE_MODEM_OR_GATEWAY = 528; // 0x210
-    field public static final int PHONE_SMART = 524; // 0x20c
-    field public static final int PHONE_UNCATEGORIZED = 512; // 0x200
-    field public static final int TOY_CONTROLLER = 2064; // 0x810
-    field public static final int TOY_DOLL_ACTION_FIGURE = 2060; // 0x80c
-    field public static final int TOY_GAME = 2068; // 0x814
-    field public static final int TOY_ROBOT = 2052; // 0x804
-    field public static final int TOY_UNCATEGORIZED = 2048; // 0x800
-    field public static final int TOY_VEHICLE = 2056; // 0x808
-    field public static final int WEARABLE_GLASSES = 1812; // 0x714
-    field public static final int WEARABLE_HELMET = 1808; // 0x710
-    field public static final int WEARABLE_JACKET = 1804; // 0x70c
-    field public static final int WEARABLE_PAGER = 1800; // 0x708
-    field public static final int WEARABLE_UNCATEGORIZED = 1792; // 0x700
-    field public static final int WEARABLE_WRIST_WATCH = 1796; // 0x704
-  }
-
-  public static class BluetoothClass.Device.Major {
-    ctor public BluetoothClass.Device.Major();
-    field public static final int AUDIO_VIDEO = 1024; // 0x400
-    field public static final int COMPUTER = 256; // 0x100
-    field public static final int HEALTH = 2304; // 0x900
-    field public static final int IMAGING = 1536; // 0x600
-    field public static final int MISC = 0; // 0x0
-    field public static final int NETWORKING = 768; // 0x300
-    field public static final int PERIPHERAL = 1280; // 0x500
-    field public static final int PHONE = 512; // 0x200
-    field public static final int TOY = 2048; // 0x800
-    field public static final int UNCATEGORIZED = 7936; // 0x1f00
-    field public static final int WEARABLE = 1792; // 0x700
-  }
-
-  public static final class BluetoothClass.Service {
-    ctor public BluetoothClass.Service();
-    field public static final int AUDIO = 2097152; // 0x200000
-    field public static final int CAPTURE = 524288; // 0x80000
-    field public static final int INFORMATION = 8388608; // 0x800000
-    field public static final int LE_AUDIO = 16384; // 0x4000
-    field public static final int LIMITED_DISCOVERABILITY = 8192; // 0x2000
-    field public static final int NETWORKING = 131072; // 0x20000
-    field public static final int OBJECT_TRANSFER = 1048576; // 0x100000
-    field public static final int POSITIONING = 65536; // 0x10000
-    field public static final int RENDER = 262144; // 0x40000
-    field public static final int TELEPHONY = 4194304; // 0x400000
-  }
-
-  public final class BluetoothCodecConfig implements android.os.Parcelable {
-    ctor public BluetoothCodecConfig(int);
-    method public int describeContents();
-    method public int getBitsPerSample();
-    method public int getChannelMode();
-    method public int getCodecPriority();
-    method public long getCodecSpecific1();
-    method public long getCodecSpecific2();
-    method public long getCodecSpecific3();
-    method public long getCodecSpecific4();
-    method public int getCodecType();
-    method public static int getMaxCodecType();
-    method public int getSampleRate();
-    method public void writeToParcel(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 = 4; // 0x4
-    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.BluetoothCodecConfig> CREATOR;
-    field public static final int SAMPLE_RATE_176400 = 16; // 0x10
-    field public static final int SAMPLE_RATE_192000 = 32; // 0x20
-    field public static final int SAMPLE_RATE_44100 = 1; // 0x1
-    field public static final int SAMPLE_RATE_48000 = 2; // 0x2
-    field public static final int SAMPLE_RATE_88200 = 4; // 0x4
-    field public static final int SAMPLE_RATE_96000 = 8; // 0x8
-    field public static final int SAMPLE_RATE_NONE = 0; // 0x0
-    field public static final int SOURCE_CODEC_TYPE_AAC = 1; // 0x1
-    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_LDAC = 4; // 0x4
-    field public static final int SOURCE_CODEC_TYPE_SBC = 0; // 0x0
-  }
-
-  public static final class BluetoothCodecConfig.Builder {
-    ctor public BluetoothCodecConfig.Builder();
-    method @NonNull public android.bluetooth.BluetoothCodecConfig build();
-    method @NonNull public android.bluetooth.BluetoothCodecConfig.Builder setBitsPerSample(int);
-    method @NonNull public android.bluetooth.BluetoothCodecConfig.Builder setChannelMode(int);
-    method @NonNull public android.bluetooth.BluetoothCodecConfig.Builder setCodecPriority(int);
-    method @NonNull public android.bluetooth.BluetoothCodecConfig.Builder setCodecSpecific1(long);
-    method @NonNull public android.bluetooth.BluetoothCodecConfig.Builder setCodecSpecific2(long);
-    method @NonNull public android.bluetooth.BluetoothCodecConfig.Builder setCodecSpecific3(long);
-    method @NonNull public android.bluetooth.BluetoothCodecConfig.Builder setCodecSpecific4(long);
-    method @NonNull public android.bluetooth.BluetoothCodecConfig.Builder setCodecType(int);
-    method @NonNull public android.bluetooth.BluetoothCodecConfig.Builder setSampleRate(int);
-  }
-
-  public final class BluetoothCodecStatus implements android.os.Parcelable {
-    ctor public BluetoothCodecStatus(@Nullable android.bluetooth.BluetoothCodecConfig, @Nullable java.util.List<android.bluetooth.BluetoothCodecConfig>, @Nullable java.util.List<android.bluetooth.BluetoothCodecConfig>);
-    method public int describeContents();
-    method @Nullable public android.bluetooth.BluetoothCodecConfig getCodecConfig();
-    method @NonNull public java.util.List<android.bluetooth.BluetoothCodecConfig> getCodecsLocalCapabilities();
-    method @NonNull public java.util.List<android.bluetooth.BluetoothCodecConfig> getCodecsSelectableCapabilities();
-    method public boolean isCodecConfigSelectable(@Nullable android.bluetooth.BluetoothCodecConfig);
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BluetoothCodecStatus> CREATOR;
-    field public static final String EXTRA_CODEC_STATUS = "android.bluetooth.extra.CODEC_STATUS";
-  }
-
-  public final class BluetoothCsipSetCoordinator implements java.lang.AutoCloseable android.bluetooth.BluetoothProfile {
-    method public void close();
-    method protected void finalize();
-    method @NonNull public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices();
-    method public int getConnectionState(@Nullable android.bluetooth.BluetoothDevice);
-    method @NonNull public java.util.List<android.bluetooth.BluetoothDevice> getDevicesMatchingConnectionStates(@NonNull int[]);
-    field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_CSIS_CONNECTION_STATE_CHANGED = "android.bluetooth.action.CSIS_CONNECTION_STATE_CHANGED";
-  }
-
-  public final class BluetoothDevice implements android.os.Parcelable {
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public android.bluetooth.BluetoothGatt connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public android.bluetooth.BluetoothGatt connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback, int);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public android.bluetooth.BluetoothGatt connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback, int, int);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public android.bluetooth.BluetoothGatt connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback, int, int, android.os.Handler);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean createBond();
-    method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public android.bluetooth.BluetoothSocket createInsecureL2capChannel(int) throws java.io.IOException;
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public android.bluetooth.BluetoothSocket createInsecureRfcommSocketToServiceRecord(java.util.UUID) throws java.io.IOException;
-    method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public android.bluetooth.BluetoothSocket createL2capChannel(int) throws java.io.IOException;
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public android.bluetooth.BluetoothSocket createRfcommSocketToServiceRecord(java.util.UUID) throws java.io.IOException;
-    method public int describeContents();
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean fetchUuidsWithSdp();
-    method public String getAddress();
-    method @Nullable @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public String getAlias();
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public android.bluetooth.BluetoothClass getBluetoothClass();
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int getBondState();
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public String getName();
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int getType();
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public android.os.ParcelUuid[] getUuids();
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int setAlias(@Nullable String);
-    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setPairingConfirmation(boolean);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean setPin(byte[]);
-    method public void writeToParcel(android.os.Parcel, int);
-    field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_ACL_CONNECTED = "android.bluetooth.device.action.ACL_CONNECTED";
-    field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_ACL_DISCONNECTED = "android.bluetooth.device.action.ACL_DISCONNECTED";
-    field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_ACL_DISCONNECT_REQUESTED = "android.bluetooth.device.action.ACL_DISCONNECT_REQUESTED";
-    field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_ALIAS_CHANGED = "android.bluetooth.device.action.ALIAS_CHANGED";
-    field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_BOND_STATE_CHANGED = "android.bluetooth.device.action.BOND_STATE_CHANGED";
-    field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_CLASS_CHANGED = "android.bluetooth.device.action.CLASS_CHANGED";
-    field @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public static final String ACTION_FOUND = "android.bluetooth.device.action.FOUND";
-    field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_NAME_CHANGED = "android.bluetooth.device.action.NAME_CHANGED";
-    field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_PAIRING_REQUEST = "android.bluetooth.device.action.PAIRING_REQUEST";
-    field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_UUID = "android.bluetooth.device.action.UUID";
-    field public static final int ADDRESS_TYPE_PUBLIC = 0; // 0x0
-    field public static final int ADDRESS_TYPE_RANDOM = 1; // 0x1
-    field public static final int BOND_BONDED = 12; // 0xc
-    field public static final int BOND_BONDING = 11; // 0xb
-    field public static final int BOND_NONE = 10; // 0xa
-    field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BluetoothDevice> CREATOR;
-    field public static final int DEVICE_TYPE_CLASSIC = 1; // 0x1
-    field public static final int DEVICE_TYPE_DUAL = 3; // 0x3
-    field public static final int DEVICE_TYPE_LE = 2; // 0x2
-    field public static final int DEVICE_TYPE_UNKNOWN = 0; // 0x0
-    field public static final int ERROR = -2147483648; // 0x80000000
-    field public static final String EXTRA_BOND_STATE = "android.bluetooth.device.extra.BOND_STATE";
-    field public static final String EXTRA_CLASS = "android.bluetooth.device.extra.CLASS";
-    field public static final String EXTRA_DEVICE = "android.bluetooth.device.extra.DEVICE";
-    field public static final String EXTRA_IS_COORDINATED_SET_MEMBER = "android.bluetooth.extra.IS_COORDINATED_SET_MEMBER";
-    field public static final String EXTRA_NAME = "android.bluetooth.device.extra.NAME";
-    field public static final String EXTRA_PAIRING_KEY = "android.bluetooth.device.extra.PAIRING_KEY";
-    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_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
-    field public static final int PHY_LE_1M = 1; // 0x1
-    field public static final int PHY_LE_1M_MASK = 1; // 0x1
-    field public static final int PHY_LE_2M = 2; // 0x2
-    field public static final int PHY_LE_2M_MASK = 2; // 0x2
-    field public static final int PHY_LE_CODED = 3; // 0x3
-    field public static final int PHY_LE_CODED_MASK = 4; // 0x4
-    field public static final int PHY_OPTION_NO_PREFERRED = 0; // 0x0
-    field public static final int PHY_OPTION_S2 = 1; // 0x1
-    field public static final int PHY_OPTION_S8 = 2; // 0x2
-    field public static final int TRANSPORT_AUTO = 0; // 0x0
-    field public static final int TRANSPORT_BREDR = 1; // 0x1
-    field public static final int TRANSPORT_LE = 2; // 0x2
-  }
-
-  public final class BluetoothGatt implements android.bluetooth.BluetoothProfile {
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public void abortReliableWrite();
-    method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public void abortReliableWrite(android.bluetooth.BluetoothDevice);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean beginReliableWrite();
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public void close();
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean connect();
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public void disconnect();
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean discoverServices();
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean executeReliableWrite();
-    method @Deprecated public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices();
-    method @Deprecated public int getConnectionState(android.bluetooth.BluetoothDevice);
-    method public android.bluetooth.BluetoothDevice getDevice();
-    method @Deprecated public java.util.List<android.bluetooth.BluetoothDevice> getDevicesMatchingConnectionStates(int[]);
-    method public android.bluetooth.BluetoothGattService getService(java.util.UUID);
-    method public java.util.List<android.bluetooth.BluetoothGattService> getServices();
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean readCharacteristic(android.bluetooth.BluetoothGattCharacteristic);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean readDescriptor(android.bluetooth.BluetoothGattDescriptor);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public void readPhy();
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean readRemoteRssi();
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean requestConnectionPriority(int);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean requestMtu(int);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean setCharacteristicNotification(android.bluetooth.BluetoothGattCharacteristic, boolean);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public void setPreferredPhy(int, int, int);
-    method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean writeCharacteristic(android.bluetooth.BluetoothGattCharacteristic);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int writeCharacteristic(@NonNull android.bluetooth.BluetoothGattCharacteristic, @NonNull byte[], int);
-    method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean writeDescriptor(android.bluetooth.BluetoothGattDescriptor);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int writeDescriptor(@NonNull android.bluetooth.BluetoothGattDescriptor, @NonNull byte[]);
-    field public static final int CONNECTION_PRIORITY_BALANCED = 0; // 0x0
-    field public static final int CONNECTION_PRIORITY_HIGH = 1; // 0x1
-    field public static final int CONNECTION_PRIORITY_LOW_POWER = 2; // 0x2
-    field public static final int GATT_CONNECTION_CONGESTED = 143; // 0x8f
-    field public static final int GATT_FAILURE = 257; // 0x101
-    field public static final int GATT_INSUFFICIENT_AUTHENTICATION = 5; // 0x5
-    field public static final int GATT_INSUFFICIENT_AUTHORIZATION = 8; // 0x8
-    field public static final int GATT_INSUFFICIENT_ENCRYPTION = 15; // 0xf
-    field public static final int GATT_INVALID_ATTRIBUTE_LENGTH = 13; // 0xd
-    field public static final int GATT_INVALID_OFFSET = 7; // 0x7
-    field public static final int GATT_READ_NOT_PERMITTED = 2; // 0x2
-    field public static final int GATT_REQUEST_NOT_SUPPORTED = 6; // 0x6
-    field public static final int GATT_SUCCESS = 0; // 0x0
-    field public static final int GATT_WRITE_NOT_PERMITTED = 3; // 0x3
-  }
-
-  public abstract class BluetoothGattCallback {
-    ctor public BluetoothGattCallback();
-    method @Deprecated public void onCharacteristicChanged(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattCharacteristic);
-    method public void onCharacteristicChanged(@NonNull android.bluetooth.BluetoothGatt, @NonNull android.bluetooth.BluetoothGattCharacteristic, @NonNull byte[]);
-    method @Deprecated public void onCharacteristicRead(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattCharacteristic, int);
-    method public void onCharacteristicRead(@NonNull android.bluetooth.BluetoothGatt, @NonNull android.bluetooth.BluetoothGattCharacteristic, @NonNull byte[], int);
-    method public void onCharacteristicWrite(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattCharacteristic, int);
-    method public void onConnectionStateChange(android.bluetooth.BluetoothGatt, int, int);
-    method @Deprecated public void onDescriptorRead(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattDescriptor, int);
-    method public void onDescriptorRead(@NonNull android.bluetooth.BluetoothGatt, @NonNull android.bluetooth.BluetoothGattDescriptor, int, @NonNull byte[]);
-    method public void onDescriptorWrite(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattDescriptor, int);
-    method public void onMtuChanged(android.bluetooth.BluetoothGatt, int, int);
-    method public void onPhyRead(android.bluetooth.BluetoothGatt, int, int, int);
-    method public void onPhyUpdate(android.bluetooth.BluetoothGatt, int, int, int);
-    method public void onReadRemoteRssi(android.bluetooth.BluetoothGatt, int, int);
-    method public void onReliableWriteCompleted(android.bluetooth.BluetoothGatt, int);
-    method public void onServiceChanged(@NonNull android.bluetooth.BluetoothGatt);
-    method public void onServicesDiscovered(android.bluetooth.BluetoothGatt, int);
-  }
-
-  public class BluetoothGattCharacteristic implements android.os.Parcelable {
-    ctor public BluetoothGattCharacteristic(java.util.UUID, int, int);
-    method public boolean addDescriptor(android.bluetooth.BluetoothGattDescriptor);
-    method public int describeContents();
-    method public android.bluetooth.BluetoothGattDescriptor getDescriptor(java.util.UUID);
-    method public java.util.List<android.bluetooth.BluetoothGattDescriptor> getDescriptors();
-    method @Deprecated public Float getFloatValue(int, int);
-    method public int getInstanceId();
-    method @Deprecated public Integer getIntValue(int, int);
-    method public int getPermissions();
-    method public int getProperties();
-    method public android.bluetooth.BluetoothGattService getService();
-    method @Deprecated public String getStringValue(int);
-    method public java.util.UUID getUuid();
-    method @Deprecated public byte[] getValue();
-    method public int getWriteType();
-    method @Deprecated public boolean setValue(byte[]);
-    method @Deprecated public boolean setValue(int, int, int);
-    method @Deprecated public boolean setValue(int, int, int, int);
-    method @Deprecated public boolean setValue(String);
-    method public void setWriteType(int);
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BluetoothGattCharacteristic> CREATOR;
-    field public static final int FORMAT_FLOAT = 52; // 0x34
-    field public static final int FORMAT_SFLOAT = 50; // 0x32
-    field public static final int FORMAT_SINT16 = 34; // 0x22
-    field public static final int FORMAT_SINT32 = 36; // 0x24
-    field public static final int FORMAT_SINT8 = 33; // 0x21
-    field public static final int FORMAT_UINT16 = 18; // 0x12
-    field public static final int FORMAT_UINT32 = 20; // 0x14
-    field public static final int FORMAT_UINT8 = 17; // 0x11
-    field public static final int PERMISSION_READ = 1; // 0x1
-    field public static final int PERMISSION_READ_ENCRYPTED = 2; // 0x2
-    field public static final int PERMISSION_READ_ENCRYPTED_MITM = 4; // 0x4
-    field public static final int PERMISSION_WRITE = 16; // 0x10
-    field public static final int PERMISSION_WRITE_ENCRYPTED = 32; // 0x20
-    field public static final int PERMISSION_WRITE_ENCRYPTED_MITM = 64; // 0x40
-    field public static final int PERMISSION_WRITE_SIGNED = 128; // 0x80
-    field public static final int PERMISSION_WRITE_SIGNED_MITM = 256; // 0x100
-    field public static final int PROPERTY_BROADCAST = 1; // 0x1
-    field public static final int PROPERTY_EXTENDED_PROPS = 128; // 0x80
-    field public static final int PROPERTY_INDICATE = 32; // 0x20
-    field public static final int PROPERTY_NOTIFY = 16; // 0x10
-    field public static final int PROPERTY_READ = 2; // 0x2
-    field public static final int PROPERTY_SIGNED_WRITE = 64; // 0x40
-    field public static final int PROPERTY_WRITE = 8; // 0x8
-    field public static final int PROPERTY_WRITE_NO_RESPONSE = 4; // 0x4
-    field public static final int WRITE_TYPE_DEFAULT = 2; // 0x2
-    field public static final int WRITE_TYPE_NO_RESPONSE = 1; // 0x1
-    field public static final int WRITE_TYPE_SIGNED = 4; // 0x4
-    field protected java.util.List<android.bluetooth.BluetoothGattDescriptor> mDescriptors;
-  }
-
-  public class BluetoothGattDescriptor implements android.os.Parcelable {
-    ctor public BluetoothGattDescriptor(java.util.UUID, int);
-    method public int describeContents();
-    method public android.bluetooth.BluetoothGattCharacteristic getCharacteristic();
-    method public int getPermissions();
-    method public java.util.UUID getUuid();
-    method @Deprecated public byte[] getValue();
-    method @Deprecated public boolean setValue(byte[]);
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BluetoothGattDescriptor> CREATOR;
-    field public static final byte[] DISABLE_NOTIFICATION_VALUE;
-    field public static final byte[] ENABLE_INDICATION_VALUE;
-    field public static final byte[] ENABLE_NOTIFICATION_VALUE;
-    field public static final int PERMISSION_READ = 1; // 0x1
-    field public static final int PERMISSION_READ_ENCRYPTED = 2; // 0x2
-    field public static final int PERMISSION_READ_ENCRYPTED_MITM = 4; // 0x4
-    field public static final int PERMISSION_WRITE = 16; // 0x10
-    field public static final int PERMISSION_WRITE_ENCRYPTED = 32; // 0x20
-    field public static final int PERMISSION_WRITE_ENCRYPTED_MITM = 64; // 0x40
-    field public static final int PERMISSION_WRITE_SIGNED = 128; // 0x80
-    field public static final int PERMISSION_WRITE_SIGNED_MITM = 256; // 0x100
-  }
-
-  public final class BluetoothGattServer implements android.bluetooth.BluetoothProfile {
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean addService(android.bluetooth.BluetoothGattService);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public void cancelConnection(android.bluetooth.BluetoothDevice);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public void clearServices();
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public void close();
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean connect(android.bluetooth.BluetoothDevice, boolean);
-    method public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices();
-    method public int getConnectionState(android.bluetooth.BluetoothDevice);
-    method public java.util.List<android.bluetooth.BluetoothDevice> getDevicesMatchingConnectionStates(int[]);
-    method public android.bluetooth.BluetoothGattService getService(java.util.UUID);
-    method public java.util.List<android.bluetooth.BluetoothGattService> getServices();
-    method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean notifyCharacteristicChanged(android.bluetooth.BluetoothDevice, android.bluetooth.BluetoothGattCharacteristic, boolean);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int notifyCharacteristicChanged(@NonNull android.bluetooth.BluetoothDevice, @NonNull android.bluetooth.BluetoothGattCharacteristic, boolean, @NonNull byte[]);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public void readPhy(android.bluetooth.BluetoothDevice);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean removeService(android.bluetooth.BluetoothGattService);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean sendResponse(android.bluetooth.BluetoothDevice, int, int, int, byte[]);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public void setPreferredPhy(android.bluetooth.BluetoothDevice, int, int, int);
-  }
-
-  public abstract class BluetoothGattServerCallback {
-    ctor public BluetoothGattServerCallback();
-    method public void onCharacteristicReadRequest(android.bluetooth.BluetoothDevice, int, int, android.bluetooth.BluetoothGattCharacteristic);
-    method public void onCharacteristicWriteRequest(android.bluetooth.BluetoothDevice, int, android.bluetooth.BluetoothGattCharacteristic, boolean, boolean, int, byte[]);
-    method public void onConnectionStateChange(android.bluetooth.BluetoothDevice, int, int);
-    method public void onDescriptorReadRequest(android.bluetooth.BluetoothDevice, int, int, android.bluetooth.BluetoothGattDescriptor);
-    method public void onDescriptorWriteRequest(android.bluetooth.BluetoothDevice, int, android.bluetooth.BluetoothGattDescriptor, boolean, boolean, int, byte[]);
-    method public void onExecuteWrite(android.bluetooth.BluetoothDevice, int, boolean);
-    method public void onMtuChanged(android.bluetooth.BluetoothDevice, int);
-    method public void onNotificationSent(android.bluetooth.BluetoothDevice, int);
-    method public void onPhyRead(android.bluetooth.BluetoothDevice, int, int, int);
-    method public void onPhyUpdate(android.bluetooth.BluetoothDevice, int, int, int);
-    method public void onServiceAdded(int, android.bluetooth.BluetoothGattService);
-  }
-
-  public class BluetoothGattService implements android.os.Parcelable {
-    ctor public BluetoothGattService(java.util.UUID, int);
-    method public boolean addCharacteristic(android.bluetooth.BluetoothGattCharacteristic);
-    method public boolean addService(android.bluetooth.BluetoothGattService);
-    method public int describeContents();
-    method public android.bluetooth.BluetoothGattCharacteristic getCharacteristic(java.util.UUID);
-    method public java.util.List<android.bluetooth.BluetoothGattCharacteristic> getCharacteristics();
-    method public java.util.List<android.bluetooth.BluetoothGattService> getIncludedServices();
-    method public int getInstanceId();
-    method public int getType();
-    method public java.util.UUID getUuid();
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BluetoothGattService> CREATOR;
-    field public static final int SERVICE_TYPE_PRIMARY = 0; // 0x0
-    field public static final int SERVICE_TYPE_SECONDARY = 1; // 0x1
-    field protected java.util.List<android.bluetooth.BluetoothGattCharacteristic> mCharacteristics;
-    field protected java.util.List<android.bluetooth.BluetoothGattService> mIncludedServices;
-  }
-
-  public final class BluetoothHeadset implements android.bluetooth.BluetoothProfile {
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices();
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int getConnectionState(android.bluetooth.BluetoothDevice);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public java.util.List<android.bluetooth.BluetoothDevice> getDevicesMatchingConnectionStates(int[]);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean isAudioConnected(android.bluetooth.BluetoothDevice);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean isNoiseReductionSupported(@NonNull android.bluetooth.BluetoothDevice);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean isVoiceRecognitionSupported(@NonNull android.bluetooth.BluetoothDevice);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean sendVendorSpecificResultCode(android.bluetooth.BluetoothDevice, String, String);
-    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.MODIFY_PHONE_STATE}) public boolean startVoiceRecognition(android.bluetooth.BluetoothDevice);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean stopVoiceRecognition(android.bluetooth.BluetoothDevice);
-    field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_AUDIO_STATE_CHANGED = "android.bluetooth.headset.profile.action.AUDIO_STATE_CHANGED";
-    field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.headset.profile.action.CONNECTION_STATE_CHANGED";
-    field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_VENDOR_SPECIFIC_HEADSET_EVENT = "android.bluetooth.headset.action.VENDOR_SPECIFIC_HEADSET_EVENT";
-    field public static final int AT_CMD_TYPE_ACTION = 4; // 0x4
-    field public static final int AT_CMD_TYPE_BASIC = 3; // 0x3
-    field public static final int AT_CMD_TYPE_READ = 0; // 0x0
-    field public static final int AT_CMD_TYPE_SET = 2; // 0x2
-    field public static final int AT_CMD_TYPE_TEST = 1; // 0x1
-    field public static final String EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_ARGS = "android.bluetooth.headset.extra.VENDOR_SPECIFIC_HEADSET_EVENT_ARGS";
-    field public static final String EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD = "android.bluetooth.headset.extra.VENDOR_SPECIFIC_HEADSET_EVENT_CMD";
-    field public static final String EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE = "android.bluetooth.headset.extra.VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE";
-    field public static final int STATE_AUDIO_CONNECTED = 12; // 0xc
-    field public static final int STATE_AUDIO_CONNECTING = 11; // 0xb
-    field public static final int STATE_AUDIO_DISCONNECTED = 10; // 0xa
-    field public static final String VENDOR_RESULT_CODE_COMMAND_ANDROID = "+ANDROID";
-    field public static final String VENDOR_SPECIFIC_HEADSET_EVENT_COMPANY_ID_CATEGORY = "android.bluetooth.headset.intent.category.companyid";
-  }
-
-  @Deprecated public final class BluetoothHealth implements android.bluetooth.BluetoothProfile {
-    method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean connectChannelToSource(android.bluetooth.BluetoothDevice, android.bluetooth.BluetoothHealthAppConfiguration);
-    method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean disconnectChannel(android.bluetooth.BluetoothDevice, android.bluetooth.BluetoothHealthAppConfiguration, int);
-    method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices();
-    method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int getConnectionState(android.bluetooth.BluetoothDevice);
-    method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public java.util.List<android.bluetooth.BluetoothDevice> getDevicesMatchingConnectionStates(int[]);
-    method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public android.os.ParcelFileDescriptor getMainChannelFd(android.bluetooth.BluetoothDevice, android.bluetooth.BluetoothHealthAppConfiguration);
-    method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean registerSinkAppConfiguration(String, int, android.bluetooth.BluetoothHealthCallback);
-    method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean unregisterAppConfiguration(android.bluetooth.BluetoothHealthAppConfiguration);
-    field @Deprecated public static final int APP_CONFIG_REGISTRATION_FAILURE = 1; // 0x1
-    field @Deprecated public static final int APP_CONFIG_REGISTRATION_SUCCESS = 0; // 0x0
-    field @Deprecated public static final int APP_CONFIG_UNREGISTRATION_FAILURE = 3; // 0x3
-    field @Deprecated public static final int APP_CONFIG_UNREGISTRATION_SUCCESS = 2; // 0x2
-    field @Deprecated public static final int CHANNEL_TYPE_RELIABLE = 10; // 0xa
-    field @Deprecated public static final int CHANNEL_TYPE_STREAMING = 11; // 0xb
-    field @Deprecated public static final int SINK_ROLE = 2; // 0x2
-    field @Deprecated public static final int SOURCE_ROLE = 1; // 0x1
-    field @Deprecated public static final int STATE_CHANNEL_CONNECTED = 2; // 0x2
-    field @Deprecated public static final int STATE_CHANNEL_CONNECTING = 1; // 0x1
-    field @Deprecated public static final int STATE_CHANNEL_DISCONNECTED = 0; // 0x0
-    field @Deprecated public static final int STATE_CHANNEL_DISCONNECTING = 3; // 0x3
-  }
-
-  @Deprecated public final class BluetoothHealthAppConfiguration implements android.os.Parcelable {
-    method @Deprecated public int describeContents();
-    method @Deprecated public int getDataType();
-    method @Deprecated public String getName();
-    method @Deprecated public int getRole();
-    method @Deprecated public void writeToParcel(android.os.Parcel, int);
-    field @Deprecated @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BluetoothHealthAppConfiguration> CREATOR;
-  }
-
-  @Deprecated public abstract class BluetoothHealthCallback {
-    ctor @Deprecated public BluetoothHealthCallback();
-    method @Deprecated @BinderThread public void onHealthAppConfigurationStatusChange(android.bluetooth.BluetoothHealthAppConfiguration, int);
-    method @Deprecated @BinderThread public void onHealthChannelStateChange(android.bluetooth.BluetoothHealthAppConfiguration, android.bluetooth.BluetoothDevice, int, int, android.os.ParcelFileDescriptor, int);
-  }
-
-  public final class BluetoothHearingAid implements android.bluetooth.BluetoothProfile {
-    method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices();
-    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[]);
-    field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.hearingaid.profile.action.CONNECTION_STATE_CHANGED";
-  }
-
-  public final class BluetoothHidDevice implements android.bluetooth.BluetoothProfile {
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean connect(android.bluetooth.BluetoothDevice);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean disconnect(android.bluetooth.BluetoothDevice);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices();
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int getConnectionState(android.bluetooth.BluetoothDevice);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public java.util.List<android.bluetooth.BluetoothDevice> getDevicesMatchingConnectionStates(int[]);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean registerApp(android.bluetooth.BluetoothHidDeviceAppSdpSettings, android.bluetooth.BluetoothHidDeviceAppQosSettings, android.bluetooth.BluetoothHidDeviceAppQosSettings, java.util.concurrent.Executor, android.bluetooth.BluetoothHidDevice.Callback);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean replyReport(android.bluetooth.BluetoothDevice, byte, byte, byte[]);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean reportError(android.bluetooth.BluetoothDevice, byte);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean sendReport(android.bluetooth.BluetoothDevice, int, byte[]);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean unregisterApp();
-    field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.hiddevice.profile.action.CONNECTION_STATE_CHANGED";
-    field public static final byte ERROR_RSP_INVALID_PARAM = 4; // 0x4
-    field public static final byte ERROR_RSP_INVALID_RPT_ID = 2; // 0x2
-    field public static final byte ERROR_RSP_NOT_READY = 1; // 0x1
-    field public static final byte ERROR_RSP_SUCCESS = 0; // 0x0
-    field public static final byte ERROR_RSP_UNKNOWN = 14; // 0xe
-    field public static final byte ERROR_RSP_UNSUPPORTED_REQ = 3; // 0x3
-    field public static final byte PROTOCOL_BOOT_MODE = 0; // 0x0
-    field public static final byte PROTOCOL_REPORT_MODE = 1; // 0x1
-    field public static final byte REPORT_TYPE_FEATURE = 3; // 0x3
-    field public static final byte REPORT_TYPE_INPUT = 1; // 0x1
-    field public static final byte REPORT_TYPE_OUTPUT = 2; // 0x2
-    field public static final byte SUBCLASS1_COMBO = -64; // 0xffffffc0
-    field public static final byte SUBCLASS1_KEYBOARD = 64; // 0x40
-    field public static final byte SUBCLASS1_MOUSE = -128; // 0xffffff80
-    field public static final byte SUBCLASS1_NONE = 0; // 0x0
-    field public static final byte SUBCLASS2_CARD_READER = 6; // 0x6
-    field public static final byte SUBCLASS2_DIGITIZER_TABLET = 5; // 0x5
-    field public static final byte SUBCLASS2_GAMEPAD = 2; // 0x2
-    field public static final byte SUBCLASS2_JOYSTICK = 1; // 0x1
-    field public static final byte SUBCLASS2_REMOTE_CONTROL = 3; // 0x3
-    field public static final byte SUBCLASS2_SENSING_DEVICE = 4; // 0x4
-    field public static final byte SUBCLASS2_UNCATEGORIZED = 0; // 0x0
-  }
-
-  public abstract static class BluetoothHidDevice.Callback {
-    ctor public BluetoothHidDevice.Callback();
-    method public void onAppStatusChanged(android.bluetooth.BluetoothDevice, boolean);
-    method public void onConnectionStateChanged(android.bluetooth.BluetoothDevice, int);
-    method public void onGetReport(android.bluetooth.BluetoothDevice, byte, byte, int);
-    method public void onInterruptData(android.bluetooth.BluetoothDevice, byte, byte[]);
-    method public void onSetProtocol(android.bluetooth.BluetoothDevice, byte);
-    method public void onSetReport(android.bluetooth.BluetoothDevice, byte, byte, byte[]);
-    method public void onVirtualCableUnplug(android.bluetooth.BluetoothDevice);
-  }
-
-  public final class BluetoothHidDeviceAppQosSettings implements android.os.Parcelable {
-    ctor public BluetoothHidDeviceAppQosSettings(int, int, int, int, int, int);
-    method public int describeContents();
-    method public int getDelayVariation();
-    method public int getLatency();
-    method public int getPeakBandwidth();
-    method public int getServiceType();
-    method public int getTokenBucketSize();
-    method public int getTokenRate();
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BluetoothHidDeviceAppQosSettings> CREATOR;
-    field public static final int MAX = -1; // 0xffffffff
-    field public static final int SERVICE_BEST_EFFORT = 1; // 0x1
-    field public static final int SERVICE_GUARANTEED = 2; // 0x2
-    field public static final int SERVICE_NO_TRAFFIC = 0; // 0x0
-  }
-
-  public final class BluetoothHidDeviceAppSdpSettings implements android.os.Parcelable {
-    ctor public BluetoothHidDeviceAppSdpSettings(String, String, String, byte, byte[]);
-    method public int describeContents();
-    method public String getDescription();
-    method public byte[] getDescriptors();
-    method public String getName();
-    method public String getProvider();
-    method public byte getSubclass();
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BluetoothHidDeviceAppSdpSettings> CREATOR;
-  }
-
-  public final class BluetoothLeAudio implements java.lang.AutoCloseable android.bluetooth.BluetoothProfile {
-    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 @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 {
-    method @NonNull public String getCodecName();
-    method public int getCodecType();
-    method public static int getMaxCodecType();
-    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();
-    method @NonNull public android.bluetooth.BluetoothLeAudioCodecConfig build();
-    method @NonNull public android.bluetooth.BluetoothLeAudioCodecConfig.Builder setCodecType(int);
-  }
-
-  public final class BluetoothManager {
-    method public android.bluetooth.BluetoothAdapter getAdapter();
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices(int);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int getConnectionState(android.bluetooth.BluetoothDevice, int);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public java.util.List<android.bluetooth.BluetoothDevice> getDevicesMatchingConnectionStates(int, int[]);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public android.bluetooth.BluetoothGattServer openGattServer(android.content.Context, android.bluetooth.BluetoothGattServerCallback);
-  }
-
-  public interface BluetoothProfile {
-    method public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices();
-    method public int getConnectionState(android.bluetooth.BluetoothDevice);
-    method public java.util.List<android.bluetooth.BluetoothDevice> getDevicesMatchingConnectionStates(int[]);
-    field public static final int A2DP = 2; // 0x2
-    field public static final int CSIP_SET_COORDINATOR = 25; // 0x19
-    field public static final String EXTRA_PREVIOUS_STATE = "android.bluetooth.profile.extra.PREVIOUS_STATE";
-    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 HEADSET = 1; // 0x1
-    field @Deprecated public static final int HEALTH = 3; // 0x3
-    field public static final int HEARING_AID = 21; // 0x15
-    field public static final int HID_DEVICE = 19; // 0x13
-    field public static final int LE_AUDIO = 22; // 0x16
-    field public static final int SAP = 10; // 0xa
-    field public static final int STATE_CONNECTED = 2; // 0x2
-    field public static final int STATE_CONNECTING = 1; // 0x1
-    field public static final int STATE_DISCONNECTED = 0; // 0x0
-    field public static final int STATE_DISCONNECTING = 3; // 0x3
-  }
-
-  public static interface BluetoothProfile.ServiceListener {
-    method public void onServiceConnected(int, android.bluetooth.BluetoothProfile);
-    method public void onServiceDisconnected(int);
-  }
-
-  public final class BluetoothServerSocket implements java.io.Closeable {
-    method public android.bluetooth.BluetoothSocket accept() throws java.io.IOException;
-    method public android.bluetooth.BluetoothSocket accept(int) throws java.io.IOException;
-    method public void close() throws java.io.IOException;
-    method public int getPsm();
-  }
-
-  public final class BluetoothSocket implements java.io.Closeable {
-    method public void close() throws java.io.IOException;
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public void connect() throws java.io.IOException;
-    method public int getConnectionType();
-    method public java.io.InputStream getInputStream() throws java.io.IOException;
-    method public int getMaxReceivePacketSize();
-    method public int getMaxTransmitPacketSize();
-    method public java.io.OutputStream getOutputStream() throws java.io.IOException;
-    method public android.bluetooth.BluetoothDevice getRemoteDevice();
-    method public boolean isConnected();
-    field public static final int TYPE_L2CAP = 3; // 0x3
-    field public static final int TYPE_RFCOMM = 1; // 0x1
-    field public static final int TYPE_SCO = 2; // 0x2
-  }
-
-  public final class BluetoothStatusCodes {
-    field public static final int ERROR_BLUETOOTH_NOT_ALLOWED = 2; // 0x2
-    field public static final int ERROR_BLUETOOTH_NOT_ENABLED = 1; // 0x1
-    field public static final int ERROR_DEVICE_NOT_BONDED = 3; // 0x3
-    field public static final int ERROR_FEATURE_NOT_SUPPORTED = 10; // 0xa
-    field public static final int ERROR_GATT_WRITE_NOT_ALLOWED = 101; // 0x65
-    field public static final int ERROR_GATT_WRITE_REQUEST_BUSY = 102; // 0x66
-    field public static final int ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION = 6; // 0x6
-    field public static final int ERROR_MISSING_BLUETOOTH_PRIVILEGED_PERMISSION = 8; // 0x8
-    field public static final int ERROR_PROFILE_SERVICE_NOT_BOUND = 9; // 0x9
-    field public static final int ERROR_UNKNOWN = 2147483647; // 0x7fffffff
-    field public static final int SUCCESS = 0; // 0x0
-  }
-
-}
-
-package android.bluetooth.le {
-
-  public abstract class AdvertiseCallback {
-    ctor public AdvertiseCallback();
-    method public void onStartFailure(int);
-    method public void onStartSuccess(android.bluetooth.le.AdvertiseSettings);
-    field public static final int ADVERTISE_FAILED_ALREADY_STARTED = 3; // 0x3
-    field public static final int ADVERTISE_FAILED_DATA_TOO_LARGE = 1; // 0x1
-    field public static final int ADVERTISE_FAILED_FEATURE_UNSUPPORTED = 5; // 0x5
-    field public static final int ADVERTISE_FAILED_INTERNAL_ERROR = 4; // 0x4
-    field public static final int ADVERTISE_FAILED_TOO_MANY_ADVERTISERS = 2; // 0x2
-  }
-
-  public final class AdvertiseData implements android.os.Parcelable {
-    method public int describeContents();
-    method public boolean getIncludeDeviceName();
-    method public boolean getIncludeTxPowerLevel();
-    method public android.util.SparseArray<byte[]> getManufacturerSpecificData();
-    method public java.util.Map<android.os.ParcelUuid,byte[]> getServiceData();
-    method @NonNull public java.util.List<android.os.ParcelUuid> getServiceSolicitationUuids();
-    method public java.util.List<android.os.ParcelUuid> getServiceUuids();
-    method @NonNull public java.util.List<android.bluetooth.le.TransportDiscoveryData> getTransportDiscoveryData();
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.le.AdvertiseData> CREATOR;
-  }
-
-  public static final class AdvertiseData.Builder {
-    ctor public AdvertiseData.Builder();
-    method public android.bluetooth.le.AdvertiseData.Builder addManufacturerData(int, byte[]);
-    method public android.bluetooth.le.AdvertiseData.Builder addServiceData(android.os.ParcelUuid, byte[]);
-    method @NonNull public android.bluetooth.le.AdvertiseData.Builder addServiceSolicitationUuid(@NonNull android.os.ParcelUuid);
-    method public android.bluetooth.le.AdvertiseData.Builder addServiceUuid(android.os.ParcelUuid);
-    method @NonNull public android.bluetooth.le.AdvertiseData.Builder addTransportDiscoveryData(@NonNull android.bluetooth.le.TransportDiscoveryData);
-    method public android.bluetooth.le.AdvertiseData build();
-    method public android.bluetooth.le.AdvertiseData.Builder setIncludeDeviceName(boolean);
-    method public android.bluetooth.le.AdvertiseData.Builder setIncludeTxPowerLevel(boolean);
-  }
-
-  public final class AdvertiseSettings implements android.os.Parcelable {
-    method public int describeContents();
-    method public int getMode();
-    method public int getTimeout();
-    method public int getTxPowerLevel();
-    method public boolean isConnectable();
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final int ADVERTISE_MODE_BALANCED = 1; // 0x1
-    field public static final int ADVERTISE_MODE_LOW_LATENCY = 2; // 0x2
-    field public static final int ADVERTISE_MODE_LOW_POWER = 0; // 0x0
-    field public static final int ADVERTISE_TX_POWER_HIGH = 3; // 0x3
-    field public static final int ADVERTISE_TX_POWER_LOW = 1; // 0x1
-    field public static final int ADVERTISE_TX_POWER_MEDIUM = 2; // 0x2
-    field public static final int ADVERTISE_TX_POWER_ULTRA_LOW = 0; // 0x0
-    field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.le.AdvertiseSettings> CREATOR;
-  }
-
-  public static final class AdvertiseSettings.Builder {
-    ctor public AdvertiseSettings.Builder();
-    method public android.bluetooth.le.AdvertiseSettings build();
-    method public android.bluetooth.le.AdvertiseSettings.Builder setAdvertiseMode(int);
-    method public android.bluetooth.le.AdvertiseSettings.Builder setConnectable(boolean);
-    method public android.bluetooth.le.AdvertiseSettings.Builder setTimeout(int);
-    method public android.bluetooth.le.AdvertiseSettings.Builder setTxPowerLevel(int);
-  }
-
-  public final class AdvertisingSet {
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) public void enableAdvertising(boolean, int, int);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) public void setAdvertisingData(android.bluetooth.le.AdvertiseData);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) public void setAdvertisingParameters(android.bluetooth.le.AdvertisingSetParameters);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) public void setPeriodicAdvertisingData(android.bluetooth.le.AdvertiseData);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) public void setPeriodicAdvertisingEnabled(boolean);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) public void setPeriodicAdvertisingParameters(android.bluetooth.le.PeriodicAdvertisingParameters);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) public void setScanResponseData(android.bluetooth.le.AdvertiseData);
-  }
-
-  public abstract class AdvertisingSetCallback {
-    ctor public AdvertisingSetCallback();
-    method public void onAdvertisingDataSet(android.bluetooth.le.AdvertisingSet, int);
-    method public void onAdvertisingEnabled(android.bluetooth.le.AdvertisingSet, boolean, int);
-    method public void onAdvertisingParametersUpdated(android.bluetooth.le.AdvertisingSet, int, int);
-    method public void onAdvertisingSetStarted(android.bluetooth.le.AdvertisingSet, int, int);
-    method public void onAdvertisingSetStopped(android.bluetooth.le.AdvertisingSet);
-    method public void onPeriodicAdvertisingDataSet(android.bluetooth.le.AdvertisingSet, int);
-    method public void onPeriodicAdvertisingEnabled(android.bluetooth.le.AdvertisingSet, boolean, int);
-    method public void onPeriodicAdvertisingParametersUpdated(android.bluetooth.le.AdvertisingSet, int);
-    method public void onScanResponseDataSet(android.bluetooth.le.AdvertisingSet, int);
-    field public static final int ADVERTISE_FAILED_ALREADY_STARTED = 3; // 0x3
-    field public static final int ADVERTISE_FAILED_DATA_TOO_LARGE = 1; // 0x1
-    field public static final int ADVERTISE_FAILED_FEATURE_UNSUPPORTED = 5; // 0x5
-    field public static final int ADVERTISE_FAILED_INTERNAL_ERROR = 4; // 0x4
-    field public static final int ADVERTISE_FAILED_TOO_MANY_ADVERTISERS = 2; // 0x2
-    field public static final int ADVERTISE_SUCCESS = 0; // 0x0
-  }
-
-  public final class AdvertisingSetParameters implements android.os.Parcelable {
-    method public int describeContents();
-    method public int getInterval();
-    method public int getPrimaryPhy();
-    method public int getSecondaryPhy();
-    method public int getTxPowerLevel();
-    method public boolean includeTxPower();
-    method public boolean isAnonymous();
-    method public boolean isConnectable();
-    method public boolean isLegacy();
-    method public boolean isScannable();
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.le.AdvertisingSetParameters> CREATOR;
-    field public static final int INTERVAL_HIGH = 1600; // 0x640
-    field public static final int INTERVAL_LOW = 160; // 0xa0
-    field public static final int INTERVAL_MAX = 16777215; // 0xffffff
-    field public static final int INTERVAL_MEDIUM = 400; // 0x190
-    field public static final int INTERVAL_MIN = 160; // 0xa0
-    field public static final int TX_POWER_HIGH = 1; // 0x1
-    field public static final int TX_POWER_LOW = -15; // 0xfffffff1
-    field public static final int TX_POWER_MAX = 1; // 0x1
-    field public static final int TX_POWER_MEDIUM = -7; // 0xfffffff9
-    field public static final int TX_POWER_MIN = -127; // 0xffffff81
-    field public static final int TX_POWER_ULTRA_LOW = -21; // 0xffffffeb
-  }
-
-  public static final class AdvertisingSetParameters.Builder {
-    ctor public AdvertisingSetParameters.Builder();
-    method public android.bluetooth.le.AdvertisingSetParameters build();
-    method public android.bluetooth.le.AdvertisingSetParameters.Builder setAnonymous(boolean);
-    method public android.bluetooth.le.AdvertisingSetParameters.Builder setConnectable(boolean);
-    method public android.bluetooth.le.AdvertisingSetParameters.Builder setIncludeTxPower(boolean);
-    method public android.bluetooth.le.AdvertisingSetParameters.Builder setInterval(int);
-    method public android.bluetooth.le.AdvertisingSetParameters.Builder setLegacyMode(boolean);
-    method public android.bluetooth.le.AdvertisingSetParameters.Builder setPrimaryPhy(int);
-    method public android.bluetooth.le.AdvertisingSetParameters.Builder setScannable(boolean);
-    method public android.bluetooth.le.AdvertisingSetParameters.Builder setSecondaryPhy(int);
-    method public android.bluetooth.le.AdvertisingSetParameters.Builder setTxPowerLevel(int);
-  }
-
-  public final class BluetoothLeAdvertiser {
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) public void startAdvertising(android.bluetooth.le.AdvertiseSettings, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseCallback);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) public void startAdvertising(android.bluetooth.le.AdvertiseSettings, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseCallback);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) public void startAdvertisingSet(android.bluetooth.le.AdvertisingSetParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.PeriodicAdvertisingParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertisingSetCallback);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) public void startAdvertisingSet(android.bluetooth.le.AdvertisingSetParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.PeriodicAdvertisingParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertisingSetCallback, android.os.Handler);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) public void startAdvertisingSet(android.bluetooth.le.AdvertisingSetParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.PeriodicAdvertisingParameters, android.bluetooth.le.AdvertiseData, int, int, android.bluetooth.le.AdvertisingSetCallback);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) public void startAdvertisingSet(android.bluetooth.le.AdvertisingSetParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.PeriodicAdvertisingParameters, android.bluetooth.le.AdvertiseData, int, int, android.bluetooth.le.AdvertisingSetCallback, android.os.Handler);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) public void stopAdvertising(android.bluetooth.le.AdvertiseCallback);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) public void stopAdvertisingSet(android.bluetooth.le.AdvertisingSetCallback);
-  }
-
-  public final class BluetoothLeScanner {
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public void flushPendingScanResults(android.bluetooth.le.ScanCallback);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public void startScan(android.bluetooth.le.ScanCallback);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public void startScan(java.util.List<android.bluetooth.le.ScanFilter>, android.bluetooth.le.ScanSettings, android.bluetooth.le.ScanCallback);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public int startScan(@Nullable java.util.List<android.bluetooth.le.ScanFilter>, @Nullable android.bluetooth.le.ScanSettings, @NonNull android.app.PendingIntent);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public void stopScan(android.bluetooth.le.ScanCallback);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public void stopScan(android.app.PendingIntent);
-    field public static final String EXTRA_CALLBACK_TYPE = "android.bluetooth.le.extra.CALLBACK_TYPE";
-    field public static final String EXTRA_ERROR_CODE = "android.bluetooth.le.extra.ERROR_CODE";
-    field public static final String EXTRA_LIST_SCAN_RESULT = "android.bluetooth.le.extra.LIST_SCAN_RESULT";
-  }
-
-  public final class PeriodicAdvertisingParameters implements android.os.Parcelable {
-    method public int describeContents();
-    method public boolean getIncludeTxPower();
-    method public int getInterval();
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final android.os.Parcelable.Creator<android.bluetooth.le.PeriodicAdvertisingParameters> CREATOR;
-  }
-
-  public static final class PeriodicAdvertisingParameters.Builder {
-    ctor public PeriodicAdvertisingParameters.Builder();
-    method public android.bluetooth.le.PeriodicAdvertisingParameters build();
-    method public android.bluetooth.le.PeriodicAdvertisingParameters.Builder setIncludeTxPower(boolean);
-    method public android.bluetooth.le.PeriodicAdvertisingParameters.Builder setInterval(int);
-  }
-
-  public abstract class ScanCallback {
-    ctor public ScanCallback();
-    method public void onBatchScanResults(java.util.List<android.bluetooth.le.ScanResult>);
-    method public void onScanFailed(int);
-    method public void onScanResult(int, android.bluetooth.le.ScanResult);
-    field public static final int SCAN_FAILED_ALREADY_STARTED = 1; // 0x1
-    field public static final int SCAN_FAILED_APPLICATION_REGISTRATION_FAILED = 2; // 0x2
-    field public static final int SCAN_FAILED_FEATURE_UNSUPPORTED = 4; // 0x4
-    field public static final int SCAN_FAILED_INTERNAL_ERROR = 3; // 0x3
-  }
-
-  public final class ScanFilter implements android.os.Parcelable {
-    method public int describeContents();
-    method @Nullable public String getDeviceAddress();
-    method @Nullable public String getDeviceName();
-    method @Nullable public byte[] getManufacturerData();
-    method @Nullable public byte[] getManufacturerDataMask();
-    method public int getManufacturerId();
-    method @Nullable public byte[] getServiceData();
-    method @Nullable public byte[] getServiceDataMask();
-    method @Nullable public android.os.ParcelUuid getServiceDataUuid();
-    method @Nullable public android.os.ParcelUuid getServiceSolicitationUuid();
-    method @Nullable public android.os.ParcelUuid getServiceSolicitationUuidMask();
-    method @Nullable public android.os.ParcelUuid getServiceUuid();
-    method @Nullable public android.os.ParcelUuid getServiceUuidMask();
-    method public boolean matches(android.bluetooth.le.ScanResult);
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.le.ScanFilter> CREATOR;
-  }
-
-  public static final class ScanFilter.Builder {
-    ctor public ScanFilter.Builder();
-    method public android.bluetooth.le.ScanFilter build();
-    method public android.bluetooth.le.ScanFilter.Builder setDeviceAddress(String);
-    method public android.bluetooth.le.ScanFilter.Builder setDeviceName(String);
-    method public android.bluetooth.le.ScanFilter.Builder setManufacturerData(int, byte[]);
-    method public android.bluetooth.le.ScanFilter.Builder setManufacturerData(int, byte[], byte[]);
-    method public android.bluetooth.le.ScanFilter.Builder setServiceData(android.os.ParcelUuid, byte[]);
-    method public android.bluetooth.le.ScanFilter.Builder setServiceData(android.os.ParcelUuid, byte[], byte[]);
-    method @NonNull public android.bluetooth.le.ScanFilter.Builder setServiceSolicitationUuid(@Nullable android.os.ParcelUuid);
-    method @NonNull public android.bluetooth.le.ScanFilter.Builder setServiceSolicitationUuid(@Nullable android.os.ParcelUuid, @Nullable android.os.ParcelUuid);
-    method public android.bluetooth.le.ScanFilter.Builder setServiceUuid(android.os.ParcelUuid);
-    method public android.bluetooth.le.ScanFilter.Builder setServiceUuid(android.os.ParcelUuid, android.os.ParcelUuid);
-  }
-
-  public final class ScanRecord {
-    method public int getAdvertiseFlags();
-    method public byte[] getBytes();
-    method @Nullable public String getDeviceName();
-    method public android.util.SparseArray<byte[]> getManufacturerSpecificData();
-    method @Nullable public byte[] getManufacturerSpecificData(int);
-    method public java.util.Map<android.os.ParcelUuid,byte[]> getServiceData();
-    method @Nullable public byte[] getServiceData(android.os.ParcelUuid);
-    method @NonNull public java.util.List<android.os.ParcelUuid> getServiceSolicitationUuids();
-    method public java.util.List<android.os.ParcelUuid> getServiceUuids();
-    method public int getTxPowerLevel();
-  }
-
-  public final class ScanResult implements android.os.Parcelable {
-    ctor @Deprecated public ScanResult(android.bluetooth.BluetoothDevice, android.bluetooth.le.ScanRecord, int, long);
-    ctor public ScanResult(android.bluetooth.BluetoothDevice, int, int, int, int, int, int, int, android.bluetooth.le.ScanRecord, long);
-    method public int describeContents();
-    method public int getAdvertisingSid();
-    method public int getDataStatus();
-    method public android.bluetooth.BluetoothDevice getDevice();
-    method public int getPeriodicAdvertisingInterval();
-    method public int getPrimaryPhy();
-    method public int getRssi();
-    method @Nullable public android.bluetooth.le.ScanRecord getScanRecord();
-    method public int getSecondaryPhy();
-    method public long getTimestampNanos();
-    method public int getTxPower();
-    method public boolean isConnectable();
-    method public boolean isLegacy();
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.le.ScanResult> CREATOR;
-    field public static final int DATA_COMPLETE = 0; // 0x0
-    field public static final int DATA_TRUNCATED = 2; // 0x2
-    field public static final int PERIODIC_INTERVAL_NOT_PRESENT = 0; // 0x0
-    field public static final int PHY_UNUSED = 0; // 0x0
-    field public static final int SID_NOT_PRESENT = 255; // 0xff
-    field public static final int TX_POWER_NOT_PRESENT = 127; // 0x7f
-  }
-
-  public final class ScanSettings implements android.os.Parcelable {
-    method public int describeContents();
-    method public int getCallbackType();
-    method public boolean getLegacy();
-    method public int getPhy();
-    method public long getReportDelayMillis();
-    method public int getScanMode();
-    method public int getScanResultType();
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final int CALLBACK_TYPE_ALL_MATCHES = 1; // 0x1
-    field public static final int CALLBACK_TYPE_FIRST_MATCH = 2; // 0x2
-    field public static final int CALLBACK_TYPE_MATCH_LOST = 4; // 0x4
-    field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.le.ScanSettings> CREATOR;
-    field public static final int MATCH_MODE_AGGRESSIVE = 1; // 0x1
-    field public static final int MATCH_MODE_STICKY = 2; // 0x2
-    field public static final int MATCH_NUM_FEW_ADVERTISEMENT = 2; // 0x2
-    field public static final int MATCH_NUM_MAX_ADVERTISEMENT = 3; // 0x3
-    field public static final int MATCH_NUM_ONE_ADVERTISEMENT = 1; // 0x1
-    field public static final int PHY_LE_ALL_SUPPORTED = 255; // 0xff
-    field public static final int SCAN_MODE_BALANCED = 1; // 0x1
-    field public static final int SCAN_MODE_LOW_LATENCY = 2; // 0x2
-    field public static final int SCAN_MODE_LOW_POWER = 0; // 0x0
-    field public static final int SCAN_MODE_OPPORTUNISTIC = -1; // 0xffffffff
-  }
-
-  public static final class ScanSettings.Builder {
-    ctor public ScanSettings.Builder();
-    method public android.bluetooth.le.ScanSettings build();
-    method public android.bluetooth.le.ScanSettings.Builder setCallbackType(int);
-    method public android.bluetooth.le.ScanSettings.Builder setLegacy(boolean);
-    method public android.bluetooth.le.ScanSettings.Builder setMatchMode(int);
-    method public android.bluetooth.le.ScanSettings.Builder setNumOfMatches(int);
-    method public android.bluetooth.le.ScanSettings.Builder setPhy(int);
-    method public android.bluetooth.le.ScanSettings.Builder setReportDelay(long);
-    method public android.bluetooth.le.ScanSettings.Builder setScanMode(int);
-  }
-
-  public final class TransportBlock implements android.os.Parcelable {
-    ctor public TransportBlock(int, int, int, @Nullable byte[]);
-    method public int describeContents();
-    method public int getOrgId();
-    method public int getTdsFlags();
-    method @Nullable public byte[] getTransportData();
-    method public int getTransportDataLength();
-    method @Nullable public byte[] toByteArray();
-    method public int totalBytes();
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.le.TransportBlock> CREATOR;
-  }
-
-  public final class TransportDiscoveryData implements android.os.Parcelable {
-    ctor public TransportDiscoveryData(int, @NonNull java.util.List<android.bluetooth.le.TransportBlock>);
-    ctor public TransportDiscoveryData(@NonNull byte[]);
-    method public int describeContents();
-    method @NonNull public java.util.List<android.bluetooth.le.TransportBlock> getTransportBlocks();
-    method public int getTransportDataType();
-    method @Nullable public byte[] toByteArray();
-    method public int totalBytes();
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.le.TransportDiscoveryData> CREATOR;
-  }
-
-}
-
 package android.companion {
 
   public final class AssociationRequest implements android.os.Parcelable {
@@ -21881,9 +20598,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
@@ -21916,10 +20635,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";
@@ -22003,11 +20724,14 @@
     field public static final int AVCProfileHigh422 = 32; // 0x20
     field public static final int AVCProfileHigh444 = 64; // 0x40
     field public static final int AVCProfileMain = 2; // 0x2
+    field public static final int DolbyVisionLevel8k30 = 1024; // 0x400
+    field public static final int DolbyVisionLevel8k60 = 2048; // 0x800
     field public static final int DolbyVisionLevelFhd24 = 4; // 0x4
     field public static final int DolbyVisionLevelFhd30 = 8; // 0x8
     field public static final int DolbyVisionLevelFhd60 = 16; // 0x10
     field public static final int DolbyVisionLevelHd24 = 1; // 0x1
     field public static final int DolbyVisionLevelHd30 = 2; // 0x2
+    field public static final int DolbyVisionLevelUhd120 = 512; // 0x200
     field public static final int DolbyVisionLevelUhd24 = 32; // 0x20
     field public static final int DolbyVisionLevelUhd30 = 64; // 0x40
     field public static final int DolbyVisionLevelUhd48 = 128; // 0x80
@@ -22693,6 +21417,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";
@@ -22710,6 +21435,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";
@@ -22754,12 +21481,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 {
@@ -26483,12 +25216,14 @@
 
   public static final class Ikev2VpnProfile.Builder {
     ctor public Ikev2VpnProfile.Builder(@NonNull String, @NonNull String);
+    ctor public Ikev2VpnProfile.Builder(@NonNull android.net.ipsec.ike.IkeTunnelConnectionParams);
     method @NonNull public android.net.Ikev2VpnProfile build();
     method @NonNull public android.net.Ikev2VpnProfile.Builder setAllowedAlgorithms(@NonNull java.util.List<java.lang.String>);
     method @NonNull public android.net.Ikev2VpnProfile.Builder setAuthDigitalSignature(@NonNull java.security.cert.X509Certificate, @NonNull java.security.PrivateKey, @Nullable java.security.cert.X509Certificate);
     method @NonNull public android.net.Ikev2VpnProfile.Builder setAuthPsk(@NonNull byte[]);
     method @NonNull public android.net.Ikev2VpnProfile.Builder setAuthUsernamePassword(@NonNull String, @NonNull String, @Nullable java.security.cert.X509Certificate);
     method @NonNull public android.net.Ikev2VpnProfile.Builder setBypassable(boolean);
+    method @NonNull public android.net.Ikev2VpnProfile.Builder setExcludeLocalRoutes(boolean);
     method @NonNull public android.net.Ikev2VpnProfile.Builder setMaxMtu(int);
     method @NonNull public android.net.Ikev2VpnProfile.Builder setMetered(boolean);
     method @NonNull public android.net.Ikev2VpnProfile.Builder setProxy(@Nullable android.net.ProxyInfo);
@@ -26634,6 +25369,7 @@
   }
 
   public abstract class PlatformVpnProfile {
+    method public final boolean getExcludeLocalRoutes();
     method public final int getType();
     method @NonNull public final String getTypeString();
     field public static final int TYPE_IKEV2_IPSEC_PSK = 7; // 0x7
@@ -26984,65 +25720,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 {
@@ -41349,6 +40026,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 b380e6d..32c711b 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -54,7 +54,24 @@
 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 public static int getCollapsedRatType(int);
     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);
+    field public static final int NETWORK_TYPE_5G_NSA = -2; // 0xfffffffe
+  }
+
+  public abstract static class NetworkStatsManager.UsageCallback {
+    method public void onThresholdReached(@NonNull android.net.NetworkTemplate);
   }
 
 }
@@ -201,10 +218,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();
@@ -221,11 +234,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);
   }
@@ -246,6 +291,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();
@@ -256,6 +339,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
@@ -301,6 +385,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();
@@ -344,6 +433,7 @@
   }
 
   public class Process {
+    field public static final int NFC_UID = 1027; // 0x403
     field public static final int VPN_UID = 1016; // 0x3f8
   }
 
@@ -375,6 +465,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 a8ef47e..61b4ada 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -316,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 {
@@ -1850,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);
   }
@@ -1913,423 +1916,6 @@
 
 }
 
-package android.bluetooth {
-
-  public final class BluetoothA2dp implements android.bluetooth.BluetoothProfile {
-    method @Nullable @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public android.bluetooth.BufferConstraints getBufferConstraints();
-    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 getDynamicBufferSupport();
-    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setBufferLengthMillis(int, int);
-    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int);
-    field public static final int DYNAMIC_BUFFER_SUPPORT_A2DP_OFFLOAD = 1; // 0x1
-    field public static final int DYNAMIC_BUFFER_SUPPORT_A2DP_SOFTWARE_ENCODING = 2; // 0x2
-    field public static final int DYNAMIC_BUFFER_SUPPORT_NONE = 0; // 0x0
-    field public static final int OPTIONAL_CODECS_NOT_SUPPORTED = 0; // 0x0
-    field public static final int OPTIONAL_CODECS_PREF_DISABLED = 0; // 0x0
-    field public static final int OPTIONAL_CODECS_PREF_ENABLED = 1; // 0x1
-    field public static final int OPTIONAL_CODECS_PREF_UNKNOWN = -1; // 0xffffffff
-    field public static final int OPTIONAL_CODECS_SUPPORTED = 1; // 0x1
-    field public static final int OPTIONAL_CODECS_SUPPORT_UNKNOWN = -1; // 0xffffffff
-  }
-
-  public final class BluetoothA2dpSink implements android.bluetooth.BluetoothProfile {
-    method public void finalize();
-    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 boolean isAudioPlaying(@NonNull android.bluetooth.BluetoothDevice);
-    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.a2dp-sink.profile.action.CONNECTION_STATE_CHANGED";
-  }
-
-  public final class BluetoothActivityEnergyInfo implements android.os.Parcelable {
-    method public int getBluetoothStackState();
-    method public long getControllerEnergyUsed();
-    method public long getControllerIdleTimeMillis();
-    method public long getControllerRxTimeMillis();
-    method public long getControllerTxTimeMillis();
-    method public long getTimestampMillis();
-    method @NonNull public java.util.List<android.bluetooth.UidTraffic> getUidTraffic();
-    method public boolean isValid();
-    field public static final int BT_STACK_STATE_INVALID = 0; // 0x0
-    field public static final int BT_STACK_STATE_STATE_ACTIVE = 1; // 0x1
-    field public static final int BT_STACK_STATE_STATE_IDLE = 3; // 0x3
-    field public static final int BT_STACK_STATE_STATE_SCANNING = 2; // 0x2
-    field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BluetoothActivityEnergyInfo> CREATOR;
-  }
-
-  public final class BluetoothAdapter {
-    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean addOnMetadataChangedListener(@NonNull android.bluetooth.BluetoothDevice, @NonNull java.util.concurrent.Executor, @NonNull android.bluetooth.BluetoothAdapter.OnMetadataChangedListener);
-    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean disable(boolean);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean disableBLE();
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean enableBLE();
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean enableNoAutoConnect();
-    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public void generateLocalOobData(int, @NonNull java.util.concurrent.Executor, @NonNull android.bluetooth.BluetoothAdapter.OobDataCallback);
-    method @NonNull @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public java.util.List<android.bluetooth.BluetoothDevice> getActiveDevices(int);
-    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public long getDiscoveryEndMillis();
-    method public boolean isBleScanAlwaysAvailable();
-    method public boolean isLeEnabled();
-    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED, android.Manifest.permission.MODIFY_PHONE_STATE}) public boolean removeActiveDevice(int);
-    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean removeOnMetadataChangedListener(@NonNull android.bluetooth.BluetoothDevice, @NonNull android.bluetooth.BluetoothAdapter.OnMetadataChangedListener);
-    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED, android.Manifest.permission.MODIFY_PHONE_STATE}) public boolean setActiveDevice(@NonNull android.bluetooth.BluetoothDevice, int);
-    field public static final String ACTION_BLE_STATE_CHANGED = "android.bluetooth.adapter.action.BLE_STATE_CHANGED";
-    field public static final String ACTION_REQUEST_BLE_SCAN_ALWAYS_AVAILABLE = "android.bluetooth.adapter.action.REQUEST_BLE_SCAN_ALWAYS_AVAILABLE";
-    field public static final int ACTIVE_DEVICE_ALL = 2; // 0x2
-    field public static final int ACTIVE_DEVICE_AUDIO = 0; // 0x0
-    field public static final int ACTIVE_DEVICE_PHONE_CALL = 1; // 0x1
-  }
-
-  public static interface BluetoothAdapter.OnMetadataChangedListener {
-    method public void onMetadataChanged(@NonNull android.bluetooth.BluetoothDevice, int, @Nullable byte[]);
-  }
-
-  public static interface BluetoothAdapter.OobDataCallback {
-    method public void onError(int);
-    method public void onOobData(int, @NonNull android.bluetooth.OobData);
-  }
-
-  public final class BluetoothCsipSetCoordinator implements java.lang.AutoCloseable android.bluetooth.BluetoothProfile {
-    method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public java.util.List<java.lang.Integer> getAllGroupIds(@Nullable android.os.ParcelUuid);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public int getConnectionPolicy(@Nullable android.bluetooth.BluetoothDevice);
-    method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public java.util.Map getGroupUuidMapByDevice(@Nullable android.bluetooth.BluetoothDevice);
-    method @Nullable @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public java.util.UUID groupLock(int, @Nullable java.util.concurrent.Executor, @Nullable android.bluetooth.BluetoothCsipSetCoordinator.ClientLockCallback);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean groupUnlock(@NonNull java.util.UUID);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setConnectionPolicy(@Nullable android.bluetooth.BluetoothDevice, int);
-    field @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public static final String ACTION_CSIS_DEVICE_AVAILABLE = "android.bluetooth.action.CSIS_DEVICE_AVAILABLE";
-    field @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public static final String ACTION_CSIS_SET_MEMBER_AVAILABLE = "android.bluetooth.action.CSIS_SET_MEMBER_AVAILABLE";
-  }
-
-  public static interface BluetoothCsipSetCoordinator.ClientLockCallback {
-    method public void onGroupLockSet(int, int, boolean);
-  }
-
-  public final class BluetoothDevice implements android.os.Parcelable {
-    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean canBondWithoutDialog();
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean cancelBondProcess();
-    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED, android.Manifest.permission.MODIFY_PHONE_STATE}) public int connect();
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean createBond(int);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean createBondOutOfBand(int, @Nullable android.bluetooth.OobData, @Nullable android.bluetooth.OobData);
-    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int disconnect();
-    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean fetchUuidsWithSdp(int);
-    method @Nullable @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public byte[] getMetadata(int);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int getSimAccessPermission();
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean isConnected();
-    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 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);
-    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setSilenceMode(boolean);
-    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setSimAccessPermission(int);
-    field public static final int ACCESS_ALLOWED = 1; // 0x1
-    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 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 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
-    field public static final int METADATA_HARDWARE_VERSION = 3; // 0x3
-    field public static final int METADATA_IS_UNTETHERED_HEADSET = 6; // 0x6
-    field public static final int METADATA_MAIN_BATTERY = 18; // 0x12
-    field public static final int METADATA_MAIN_CHARGING = 19; // 0x13
-    field public static final int METADATA_MAIN_ICON = 5; // 0x5
-    field public static final int METADATA_MAIN_LOW_BATTERY_THRESHOLD = 20; // 0x14
-    field public static final int METADATA_MANUFACTURER_NAME = 0; // 0x0
-    field public static final int METADATA_MAX_LENGTH = 2048; // 0x800
-    field public static final int METADATA_MODEL_NAME = 1; // 0x1
-    field public static final int METADATA_SOFTWARE_VERSION = 2; // 0x2
-    field public static final int METADATA_UNTETHERED_CASE_BATTERY = 12; // 0xc
-    field public static final int METADATA_UNTETHERED_CASE_CHARGING = 15; // 0xf
-    field public static final int METADATA_UNTETHERED_CASE_ICON = 9; // 0x9
-    field public static final int METADATA_UNTETHERED_CASE_LOW_BATTERY_THRESHOLD = 23; // 0x17
-    field public static final int METADATA_UNTETHERED_LEFT_BATTERY = 10; // 0xa
-    field public static final int METADATA_UNTETHERED_LEFT_CHARGING = 13; // 0xd
-    field public static final int METADATA_UNTETHERED_LEFT_ICON = 7; // 0x7
-    field public static final int METADATA_UNTETHERED_LEFT_LOW_BATTERY_THRESHOLD = 21; // 0x15
-    field public static final int METADATA_UNTETHERED_RIGHT_BATTERY = 11; // 0xb
-    field public static final int METADATA_UNTETHERED_RIGHT_CHARGING = 14; // 0xe
-    field public static final int METADATA_UNTETHERED_RIGHT_ICON = 8; // 0x8
-    field public static final int METADATA_UNTETHERED_RIGHT_LOW_BATTERY_THRESHOLD = 22; // 0x16
-  }
-
-  public final class BluetoothHeadset implements android.bluetooth.BluetoothProfile {
-    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.MODIFY_PHONE_STATE}) public boolean connect(android.bluetooth.BluetoothDevice);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean disconnect(android.bluetooth.BluetoothDevice);
-    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean isInbandRingingEnabled();
-    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED, android.Manifest.permission.MODIFY_PHONE_STATE}) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int);
-    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.MODIFY_PHONE_STATE}) public boolean startScoUsingVirtualVoiceCall();
-    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.MODIFY_PHONE_STATE}) public boolean stopScoUsingVirtualVoiceCall();
-  }
-
-  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);
-    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int);
-  }
-
-  public final class BluetoothHidDevice implements android.bluetooth.BluetoothProfile {
-    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int);
-  }
-
-  public final class BluetoothHidHost implements android.bluetooth.BluetoothProfile {
-    method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) 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(android.Manifest.permission.BLUETOOTH_CONNECT) public int getConnectionState(@NonNull android.bluetooth.BluetoothDevice);
-    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.input.profile.action.CONNECTION_STATE_CHANGED";
-  }
-
-  public final class BluetoothMap implements java.lang.AutoCloseable android.bluetooth.BluetoothProfile {
-    method public void close();
-    method protected void finalize();
-    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 boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int);
-    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 {
-    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);
-  }
-
-  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 @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";
-    field public static final String EXTRA_LOCAL_ROLE = "android.bluetooth.pan.extra.LOCAL_ROLE";
-    field public static final String EXTRA_TETHERING_STATE = "android.bluetooth.extra.TETHERING_STATE";
-    field public static final int LOCAL_NAP_ROLE = 1; // 0x1
-    field public static final int LOCAL_PANU_ROLE = 2; // 0x2
-    field public static final int PAN_ROLE_NONE = 0; // 0x0
-    field public static final int REMOTE_NAP_ROLE = 1; // 0x1
-    field public static final int REMOTE_PANU_ROLE = 2; // 0x2
-    field public static final int TETHERING_STATE_OFF = 1; // 0x1
-    field public static final int TETHERING_STATE_ON = 2; // 0x2
-  }
-
-  public class BluetoothPbap implements android.bluetooth.BluetoothProfile {
-    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getConnectionState(@NonNull android.bluetooth.BluetoothDevice);
-    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.pbap.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
-    field public static final int CONNECTION_POLICY_ALLOWED = 100; // 0x64
-    field public static final int CONNECTION_POLICY_FORBIDDEN = 0; // 0x0
-    field public static final int CONNECTION_POLICY_UNKNOWN = -1; // 0xffffffff
-    field public static final int HEADSET_CLIENT = 16; // 0x10
-    field public static final int MAP_CLIENT = 18; // 0x12
-    field public static final int PAN = 5; // 0x5
-    field public static final int PBAP_CLIENT = 17; // 0x11
-    field @Deprecated public static final int PRIORITY_OFF = 0; // 0x0
-    field @Deprecated public static final int PRIORITY_ON = 100; // 0x64
-    field public static final int VOLUME_CONTROL = 23; // 0x17
-  }
-
-  public final class BluetoothStatusCodes {
-    field public static final int ERROR_ANOTHER_ACTIVE_OOB_REQUEST = 1000; // 0x3e8
-  }
-
-  public final class BluetoothUuid {
-    method public static boolean containsAnyUuid(@Nullable android.os.ParcelUuid[], @Nullable android.os.ParcelUuid[]);
-    method @NonNull public static android.os.ParcelUuid parseUuidFrom(@Nullable byte[]);
-    field @NonNull public static final android.os.ParcelUuid A2DP_SINK;
-    field @NonNull public static final android.os.ParcelUuid A2DP_SOURCE;
-    field @NonNull public static final android.os.ParcelUuid ADV_AUDIO_DIST;
-    field @NonNull public static final android.os.ParcelUuid AVRCP_CONTROLLER;
-    field @NonNull public static final android.os.ParcelUuid AVRCP_TARGET;
-    field @NonNull public static final android.os.ParcelUuid BASE_UUID;
-    field @NonNull public static final android.os.ParcelUuid BNEP;
-    field @NonNull public static final android.os.ParcelUuid CAP;
-    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 HEARING_AID;
-    field @NonNull public static final android.os.ParcelUuid HFP;
-    field @NonNull public static final android.os.ParcelUuid HFP_AG;
-    field @NonNull public static final android.os.ParcelUuid HID;
-    field @NonNull public static final android.os.ParcelUuid HOGP;
-    field @NonNull public static final android.os.ParcelUuid HSP;
-    field @NonNull public static final android.os.ParcelUuid HSP_AG;
-    field @NonNull public static final android.os.ParcelUuid LE_AUDIO;
-    field @NonNull public static final android.os.ParcelUuid MAP;
-    field @NonNull public static final android.os.ParcelUuid MAS;
-    field @NonNull public static final android.os.ParcelUuid MEDIA_CONTROL;
-    field @NonNull public static final android.os.ParcelUuid MNS;
-    field @NonNull public static final android.os.ParcelUuid NAP;
-    field @NonNull public static final android.os.ParcelUuid OBEX_OBJECT_PUSH;
-    field @NonNull public static final android.os.ParcelUuid PANU;
-    field @NonNull public static final android.os.ParcelUuid PBAP_PCE;
-    field @NonNull public static final android.os.ParcelUuid PBAP_PSE;
-    field @NonNull public static final android.os.ParcelUuid SAP;
-    field public static final int UUID_BYTES_128_BIT = 16; // 0x10
-    field public static final int UUID_BYTES_16_BIT = 2; // 0x2
-    field public static final int UUID_BYTES_32_BIT = 4; // 0x4
-    field @NonNull public static final android.os.ParcelUuid VOLUME_CONTROL;
-  }
-
-  public final class BluetoothVolumeControl implements java.lang.AutoCloseable android.bluetooth.BluetoothProfile {
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public void close();
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) protected void finalize();
-    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 boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int);
-    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public void setVolume(@Nullable android.bluetooth.BluetoothDevice, @IntRange(from=0, to=255) int);
-    field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.volume-control.profile.action.CONNECTION_STATE_CHANGED";
-  }
-
-  public final class BufferConstraint implements android.os.Parcelable {
-    ctor public BufferConstraint(int, int, int);
-    method public int describeContents();
-    method public int getDefaultMillis();
-    method public int getMaxMillis();
-    method public int getMinMillis();
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BufferConstraint> CREATOR;
-  }
-
-  public final class BufferConstraints implements android.os.Parcelable {
-    ctor public BufferConstraints(@NonNull java.util.List<android.bluetooth.BufferConstraint>);
-    method public int describeContents();
-    method @Nullable public android.bluetooth.BufferConstraint forCodec(int);
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field public static final int BUFFER_CODEC_MAX_NUM = 32; // 0x20
-    field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BufferConstraints> CREATOR;
-  }
-
-  public final class OobData implements android.os.Parcelable {
-    method @NonNull public byte[] getClassOfDevice();
-    method @NonNull public byte[] getClassicLength();
-    method @NonNull public byte[] getConfirmationHash();
-    method @NonNull public byte[] getDeviceAddressWithType();
-    method @Nullable public byte[] getDeviceName();
-    method @Nullable public byte[] getLeAppearance();
-    method @NonNull public int getLeDeviceRole();
-    method @NonNull public int getLeFlags();
-    method @Nullable public byte[] getLeTemporaryKey();
-    method @NonNull public byte[] getRandomizerHash();
-    field public static final int CLASS_OF_DEVICE_OCTETS = 3; // 0x3
-    field public static final int CONFIRMATION_OCTETS = 16; // 0x10
-    field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.OobData> CREATOR;
-    field public static final int DEVICE_ADDRESS_OCTETS = 7; // 0x7
-    field public static final int LE_APPEARANCE_OCTETS = 2; // 0x2
-    field public static final int LE_DEVICE_FLAG_OCTETS = 1; // 0x1
-    field public static final int LE_DEVICE_ROLE_BOTH_PREFER_CENTRAL = 3; // 0x3
-    field public static final int LE_DEVICE_ROLE_BOTH_PREFER_PERIPHERAL = 2; // 0x2
-    field public static final int LE_DEVICE_ROLE_CENTRAL_ONLY = 1; // 0x1
-    field public static final int LE_DEVICE_ROLE_OCTETS = 1; // 0x1
-    field public static final int LE_DEVICE_ROLE_PERIPHERAL_ONLY = 0; // 0x0
-    field public static final int LE_FLAG_BREDR_NOT_SUPPORTED = 2; // 0x2
-    field public static final int LE_FLAG_GENERAL_DISCOVERY_MODE = 1; // 0x1
-    field public static final int LE_FLAG_LIMITED_DISCOVERY_MODE = 0; // 0x0
-    field public static final int LE_FLAG_SIMULTANEOUS_CONTROLLER = 3; // 0x3
-    field public static final int LE_FLAG_SIMULTANEOUS_HOST = 4; // 0x4
-    field public static final int LE_TK_OCTETS = 16; // 0x10
-    field public static final int OOB_LENGTH_OCTETS = 2; // 0x2
-    field public static final int RANDOMIZER_OCTETS = 16; // 0x10
-  }
-
-  public static final class OobData.ClassicBuilder {
-    ctor public OobData.ClassicBuilder(@NonNull byte[], @NonNull byte[], @NonNull byte[]);
-    method @NonNull public android.bluetooth.OobData build();
-    method @NonNull public android.bluetooth.OobData.ClassicBuilder setClassOfDevice(@NonNull byte[]);
-    method @NonNull public android.bluetooth.OobData.ClassicBuilder setDeviceName(@NonNull byte[]);
-    method @NonNull public android.bluetooth.OobData.ClassicBuilder setRandomizerHash(@NonNull byte[]);
-  }
-
-  public static final class OobData.LeBuilder {
-    ctor public OobData.LeBuilder(@NonNull byte[], @NonNull byte[], int);
-    method @NonNull public android.bluetooth.OobData build();
-    method @NonNull public android.bluetooth.OobData.LeBuilder setDeviceName(@NonNull byte[]);
-    method @NonNull public android.bluetooth.OobData.LeBuilder setLeFlags(int);
-    method @NonNull public android.bluetooth.OobData.LeBuilder setLeTemporaryKey(@NonNull byte[]);
-    method @NonNull public android.bluetooth.OobData.LeBuilder setRandomizerHash(@NonNull byte[]);
-  }
-
-  public final class UidTraffic implements java.lang.Cloneable android.os.Parcelable {
-    method public long getRxBytes();
-    method public long getTxBytes();
-    method public int getUid();
-    field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.UidTraffic> CREATOR;
-  }
-
-}
-
-package android.bluetooth.le {
-
-  public final class AdvertiseSettings implements android.os.Parcelable {
-    method public int getOwnAddressType();
-  }
-
-  public static final class AdvertiseSettings.Builder {
-    method @NonNull public android.bluetooth.le.AdvertiseSettings.Builder setOwnAddressType(int);
-  }
-
-  public final class AdvertisingSetParameters implements android.os.Parcelable {
-    method public int getOwnAddressType();
-    field public static final int ADDRESS_TYPE_DEFAULT = -1; // 0xffffffff
-    field public static final int ADDRESS_TYPE_PUBLIC = 0; // 0x0
-    field public static final int ADDRESS_TYPE_RANDOM = 1; // 0x1
-  }
-
-  public static final class AdvertisingSetParameters.Builder {
-    method @NonNull public android.bluetooth.le.AdvertisingSetParameters.Builder setOwnAddressType(int);
-  }
-
-  public final class BluetoothLeScanner {
-    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_SCAN, android.Manifest.permission.UPDATE_DEVICE_STATS}) public void startScanFromSource(android.os.WorkSource, android.bluetooth.le.ScanCallback);
-    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_SCAN, android.Manifest.permission.UPDATE_DEVICE_STATS}) public void startScanFromSource(java.util.List<android.bluetooth.le.ScanFilter>, android.bluetooth.le.ScanSettings, android.os.WorkSource, android.bluetooth.le.ScanCallback);
-    method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public void startTruncatedScan(java.util.List<android.bluetooth.le.TruncatedFilter>, android.bluetooth.le.ScanSettings, android.bluetooth.le.ScanCallback);
-  }
-
-  @Deprecated public final class ResultStorageDescriptor implements android.os.Parcelable {
-    ctor @Deprecated public ResultStorageDescriptor(int, int, int);
-    method @Deprecated public int describeContents();
-    method @Deprecated public int getLength();
-    method @Deprecated public int getOffset();
-    method @Deprecated public int getType();
-    method @Deprecated public void writeToParcel(android.os.Parcel, int);
-    field @Deprecated @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.le.ResultStorageDescriptor> CREATOR;
-  }
-
-  public final class ScanFilter implements android.os.Parcelable {
-    method public int getAddressType();
-    method @Nullable public byte[] getIrk();
-  }
-
-  public static final class ScanFilter.Builder {
-    method @NonNull public android.bluetooth.le.ScanFilter.Builder setDeviceAddress(@NonNull String, int);
-    method @NonNull public android.bluetooth.le.ScanFilter.Builder setDeviceAddress(@NonNull String, int, @NonNull byte[]);
-    field public static final int LEN_IRK_OCTETS = 16; // 0x10
-  }
-
-  public final class ScanSettings implements android.os.Parcelable {
-    field public static final int SCAN_MODE_AMBIENT_DISCOVERY = 3; // 0x3
-    field public static final int SCAN_RESULT_TYPE_ABBREVIATED = 1; // 0x1
-    field public static final int SCAN_RESULT_TYPE_FULL = 0; // 0x0
-  }
-
-  public static final class ScanSettings.Builder {
-    method public android.bluetooth.le.ScanSettings.Builder setScanResultType(int);
-  }
-
-  @Deprecated public final class TruncatedFilter {
-    ctor @Deprecated public TruncatedFilter(android.bluetooth.le.ScanFilter, java.util.List<android.bluetooth.le.ResultStorageDescriptor>);
-    method @Deprecated public android.bluetooth.le.ScanFilter getFilter();
-    method @Deprecated public java.util.List<android.bluetooth.le.ResultStorageDescriptor> getStorageDescriptors();
-  }
-
-}
-
 package android.companion {
 
   public final class CompanionDeviceManager {
@@ -7523,11 +7109,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;
@@ -12325,6 +11912,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
@@ -13691,6 +13279,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/api/system-removed.txt b/core/api/system-removed.txt
index 9a8a493..327bfef 100644
--- a/core/api/system-removed.txt
+++ b/core/api/system-removed.txt
@@ -68,14 +68,6 @@
 
 }
 
-package android.bluetooth {
-
-  public final class BluetoothHeadset implements android.bluetooth.BluetoothProfile {
-    method @Deprecated @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.MODIFY_PHONE_STATE}) public boolean setPriority(android.bluetooth.BluetoothDevice, int);
-  }
-
-}
-
 package android.content {
 
   public class Intent implements java.lang.Cloneable android.os.Parcelable {
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index d0e659b..18ceb25 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -675,14 +675,6 @@
 
 }
 
-package android.bluetooth {
-
-  public final class BluetoothClass implements android.os.Parcelable {
-    method public int getClassOfDevice();
-  }
-
-}
-
 package android.content {
 
   public final class AttributionSource implements android.os.Parcelable {
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 f94ee85..0000000
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ /dev/null
@@ -1,4434 +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 =
-            0; //BluetoothProtoEnums.CONNECTION_STATE_DISCONNECTED;
-    /** The profile is in connecting state */
-    public static final int STATE_CONNECTING = 1; //BluetoothProtoEnums.CONNECTION_STATE_CONNECTING;
-    /** The profile is in connected state */
-    public static final int STATE_CONNECTED = 2; //BluetoothProtoEnums.CONNECTION_STATE_CONNECTED;
-    /** The profile is in disconnecting state */
-    public static final int STATE_DISCONNECTING =
-            3; //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);
-                state = mService.getState();
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-            e.rethrowFromSystemServer();
-        } 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);
-        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;
-    }
-
-    /**
-     * 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) {
-                @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 mService.getAdapterConnectionState();
-            }
-            //return mBluetoothGetAdapterConnectionStateCache.query(null);
-        } catch (RemoteException e) {
-            Log.e(TAG, "failed to getConnectionState, error: ", 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;
-        }
-        try {
-            mServiceLock.readLock().lock();
-            if (mService != null) {
-                mService.getProfileConnectionState(profile);
-            }
-            //return mGetProfileConnectionStateCache.query(new Integer(profile));
-        } catch (RemoteException e) {
-            Log.e(TAG, "failed to getProfileConnectionState, error: ", e);
-        } finally {
-            mServiceLock.readLock().unlock();
-        }
-        return BluetoothProfile.STATE_DISCONNECTED;
-    }
-
-    /**
-     * 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 1edf5cc..0000000
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ /dev/null
@@ -1,2831 +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);
-            return sService.getBondState(this, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "failed to ", e);
-            e.rethrowFromSystemServer();
-        }
-        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 8e9d7b7..0000000
--- a/core/java/android/bluetooth/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-# Bug component: 27441
-
-sattiraju@google.com
-baligh@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/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/net/INetworkPolicyManager.aidl b/core/java/android/net/INetworkPolicyManager.aidl
index 147138e..6284f56 100644
--- a/core/java/android/net/INetworkPolicyManager.aidl
+++ b/core/java/android/net/INetworkPolicyManager.aidl
@@ -70,7 +70,7 @@
     int getMultipathPreference(in Network network);
 
     SubscriptionPlan getSubscriptionPlan(in NetworkTemplate template);
-    void onStatsProviderWarningOrLimitReached();
+    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/Ikev2VpnProfile.java b/core/java/android/net/Ikev2VpnProfile.java
index 5554137..036607b 100644
--- a/core/java/android/net/Ikev2VpnProfile.java
+++ b/core/java/android/net/Ikev2VpnProfile.java
@@ -25,6 +25,12 @@
 import static android.net.IpSecAlgorithm.AUTH_HMAC_SHA512;
 import static android.net.IpSecAlgorithm.CRYPT_AES_CBC;
 import static android.net.IpSecAlgorithm.CRYPT_AES_CTR;
+import static android.net.eap.EapSessionConfig.EapMsChapV2Config;
+import static android.net.ipsec.ike.IkeSessionParams.IkeAuthConfig;
+import static android.net.ipsec.ike.IkeSessionParams.IkeAuthDigitalSignLocalConfig;
+import static android.net.ipsec.ike.IkeSessionParams.IkeAuthDigitalSignRemoteConfig;
+import static android.net.ipsec.ike.IkeSessionParams.IkeAuthEapConfig;
+import static android.net.ipsec.ike.IkeSessionParams.IkeAuthPskConfig;
 
 import static com.android.internal.annotations.VisibleForTesting.Visibility;
 import static com.android.internal.util.Preconditions.checkStringNotEmpty;
@@ -34,6 +40,14 @@
 import android.annotation.Nullable;
 import android.annotation.RequiresFeature;
 import android.content.pm.PackageManager;
+import android.net.ipsec.ike.IkeFqdnIdentification;
+import android.net.ipsec.ike.IkeIdentification;
+import android.net.ipsec.ike.IkeIpv4AddrIdentification;
+import android.net.ipsec.ike.IkeIpv6AddrIdentification;
+import android.net.ipsec.ike.IkeKeyIdIdentification;
+import android.net.ipsec.ike.IkeRfc822AddrIdentification;
+import android.net.ipsec.ike.IkeSessionParams;
+import android.net.ipsec.ike.IkeTunnelConnectionParams;
 import android.security.Credentials;
 import android.util.Log;
 
@@ -644,6 +658,102 @@
         return Objects.requireNonNull(reference, String.format(messageTemplate, messageArgs));
     }
 
+    private static void checkBuilderSetter(boolean constructedFromIkeTunConParams,
+            @NonNull String message) {
+        if (constructedFromIkeTunConParams) {
+            throw new IllegalArgumentException("Constructed using IkeTunnelConnectionParams "
+                    + "should not set " + message);
+        }
+    }
+
+    private static int getTypeFromIkeSession(@NonNull IkeSessionParams params) {
+        final IkeAuthConfig config = params.getLocalAuthConfig();
+        if (config instanceof IkeAuthDigitalSignLocalConfig) {
+            return TYPE_IKEV2_IPSEC_RSA;
+        } else if (config instanceof IkeAuthEapConfig) {
+            return TYPE_IKEV2_IPSEC_USER_PASS;
+        } else if (config instanceof IkeAuthPskConfig) {
+            return TYPE_IKEV2_IPSEC_PSK;
+        } else {
+            throw new IllegalStateException("Invalid local IkeAuthConfig");
+        }
+    }
+
+    @Nullable
+    private static String getPasswordFromIkeSession(@NonNull IkeSessionParams params) {
+        if (!(params.getLocalAuthConfig() instanceof IkeAuthEapConfig)) return null;
+
+        final IkeAuthEapConfig ikeAuthEapConfig = (IkeAuthEapConfig) params.getLocalAuthConfig();
+        final EapMsChapV2Config eapMsChapV2Config =
+                ikeAuthEapConfig.getEapConfig().getEapMsChapV2Config();
+        return (eapMsChapV2Config != null) ? eapMsChapV2Config.getPassword() : null;
+    }
+
+    @Nullable
+    private static String getUsernameFromIkeSession(@NonNull IkeSessionParams params) {
+        if (!(params.getLocalAuthConfig() instanceof IkeAuthEapConfig)) return null;
+
+        final IkeAuthEapConfig ikeAuthEapConfig = (IkeAuthEapConfig) params.getLocalAuthConfig();
+        final EapMsChapV2Config eapMsChapV2Config =
+                ikeAuthEapConfig.getEapConfig().getEapMsChapV2Config();
+        return (eapMsChapV2Config != null) ? eapMsChapV2Config.getUsername() : null;
+    }
+
+    @Nullable
+    private static X509Certificate getUserCertFromIkeSession(@NonNull IkeSessionParams params) {
+        if (!(params.getLocalAuthConfig() instanceof IkeAuthDigitalSignLocalConfig)) return null;
+
+        final IkeAuthDigitalSignLocalConfig config =
+                (IkeAuthDigitalSignLocalConfig) params.getLocalAuthConfig();
+        return config.getClientEndCertificate();
+    }
+
+    @Nullable
+    private static X509Certificate getServerRootCaCertFromIkeSession(
+            @NonNull IkeSessionParams params) {
+        if (!(params.getRemoteAuthConfig() instanceof IkeAuthDigitalSignRemoteConfig)) return null;
+
+        final IkeAuthDigitalSignRemoteConfig config =
+                (IkeAuthDigitalSignRemoteConfig) params.getRemoteAuthConfig();
+        return config.getRemoteCaCert();
+    }
+
+    @Nullable
+    private static PrivateKey getRsaPrivateKeyFromIkeSession(@NonNull IkeSessionParams params) {
+        if (!(params.getLocalAuthConfig() instanceof IkeAuthDigitalSignLocalConfig)) return null;
+
+        final IkeAuthDigitalSignLocalConfig config =
+                (IkeAuthDigitalSignLocalConfig) params.getLocalAuthConfig();
+        return config.getPrivateKey();
+    }
+
+    @Nullable
+    private static byte[] getPresharedKeyFromIkeSession(@NonNull IkeSessionParams params) {
+        if (!(params.getLocalAuthConfig() instanceof IkeAuthPskConfig)) return null;
+
+        final IkeAuthPskConfig config = (IkeAuthPskConfig) params.getLocalAuthConfig();
+        return config.getPsk();
+    }
+
+    @NonNull
+    private static String getUserIdentityFromIkeSession(@NonNull IkeSessionParams params) {
+        final IkeIdentification ident = params.getLocalIdentification();
+        // Refer to VpnIkev2Utils.parseIkeIdentification().
+        if (ident instanceof IkeKeyIdIdentification) {
+            return "@#" + new String(((IkeKeyIdIdentification) ident).keyId);
+        } else if (ident instanceof IkeRfc822AddrIdentification) {
+            return "@@" + ((IkeRfc822AddrIdentification) ident).rfc822Name;
+        } else if (ident instanceof IkeFqdnIdentification) {
+            return "@" + ((IkeFqdnIdentification) ident).fqdn;
+        } else if (ident instanceof IkeIpv4AddrIdentification) {
+            return ((IkeIpv4AddrIdentification) ident).ipv4Address.getHostAddress();
+        } else if (ident instanceof IkeIpv6AddrIdentification) {
+            return ((IkeIpv6AddrIdentification) ident).ipv6Address.getHostAddress();
+        } else {
+            throw new IllegalArgumentException("Unknown IkeIdentification to get user identity");
+        }
+    }
+
     /** A incremental builder for IKEv2 VPN profiles */
     public static final class Builder {
         private int mType = -1;
@@ -671,6 +781,7 @@
         private int mMaxMtu = PlatformVpnProfile.MAX_MTU_DEFAULT;
         private boolean mIsRestrictedToTestNetworks = false;
         private boolean mExcludeLocalRoutes = false;
+        @Nullable private IkeTunnelConnectionParams mIkeTunConnParams;
 
         /**
          * Creates a new builder with the basic parameters of an IKEv2/IPsec VPN.
@@ -687,6 +798,32 @@
             mUserIdentity = identity;
         }
 
+        /**
+         * Creates a new builder from a {@link IkeTunnelConnectionParams}
+         *
+         * @param ikeTunConnParams the {@link IkeTunnelConnectionParams} contains IKEv2
+         *                         configurations
+         */
+        @RequiresFeature(PackageManager.FEATURE_IPSEC_TUNNELS)
+        public Builder(@NonNull IkeTunnelConnectionParams ikeTunConnParams) {
+            checkNotNull(ikeTunConnParams, MISSING_PARAM_MSG_TMPL, "ikeTunConnParams");
+
+            mIkeTunConnParams = ikeTunConnParams;
+
+            final IkeSessionParams ikeSessionParams = mIkeTunConnParams.getIkeSessionParams();
+            mServerAddr = ikeSessionParams.getServerHostname();
+
+            mType = getTypeFromIkeSession(ikeSessionParams);
+            mUserCert = getUserCertFromIkeSession(ikeSessionParams);
+            mServerRootCaCert = getServerRootCaCertFromIkeSession(ikeSessionParams);
+            mRsaPrivateKey = getRsaPrivateKeyFromIkeSession(ikeSessionParams);
+            mServerRootCaCert = getServerRootCaCertFromIkeSession(ikeSessionParams);
+            mUsername = getUsernameFromIkeSession(ikeSessionParams);
+            mPassword = getPasswordFromIkeSession(ikeSessionParams);
+            mPresharedKey = getPresharedKeyFromIkeSession(ikeSessionParams);
+            mUserIdentity = getUserIdentityFromIkeSession(ikeSessionParams);
+        }
+
         private void resetAuthParams() {
             mPresharedKey = null;
             mServerRootCaCert = null;
@@ -719,6 +856,7 @@
                 @Nullable X509Certificate serverRootCa) {
             checkNotNull(user, MISSING_PARAM_MSG_TMPL, "user");
             checkNotNull(pass, MISSING_PARAM_MSG_TMPL, "pass");
+            checkBuilderSetter(mIkeTunConnParams != null, "authUsernamePassword");
 
             // Test to make sure all auth params can be encoded safely.
             if (serverRootCa != null) checkCert(serverRootCa);
@@ -755,6 +893,7 @@
                 @Nullable X509Certificate serverRootCa) {
             checkNotNull(userCert, MISSING_PARAM_MSG_TMPL, "userCert");
             checkNotNull(key, MISSING_PARAM_MSG_TMPL, "key");
+            checkBuilderSetter(mIkeTunConnParams != null, "authDigitalSignature");
 
             // Test to make sure all auth params can be encoded safely.
             checkCert(userCert);
@@ -782,6 +921,7 @@
         @RequiresFeature(PackageManager.FEATURE_IPSEC_TUNNELS)
         public Builder setAuthPsk(@NonNull byte[] psk) {
             checkNotNull(psk, MISSING_PARAM_MSG_TMPL, "psk");
+            checkBuilderSetter(mIkeTunConnParams != null, "authPsk");
 
             resetAuthParams();
             mPresharedKey = psk;
@@ -931,8 +1071,6 @@
          *
          * Note that because the local traffic will always bypass the VPN,
          * it is not possible to set this flag on a non-bypassable VPN.
-         *
-         * @hide TODO(184750836): unhide once the implementation is completed
          */
         @NonNull
         @RequiresFeature(PackageManager.FEATURE_IPSEC_TUNNELS)
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 426fc61..c936bfa 100644
--- a/core/java/android/net/NetworkPolicyManager.java
+++ b/core/java/android/net/NetworkPolicyManager.java
@@ -546,7 +546,7 @@
     @RequiresPermission(anyOf = {
             NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
             android.Manifest.permission.NETWORK_STACK})
-    // @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     public SubscriptionPlan getSubscriptionPlan(@NonNull NetworkTemplate template) {
         try {
             return mService.getSubscriptionPlan(template);
@@ -565,10 +565,10 @@
     @RequiresPermission(anyOf = {
             NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
             android.Manifest.permission.NETWORK_STACK})
-    // @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
-    public void onStatsProviderWarningOrLimitReached() {
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public void notifyStatsProviderWarningOrLimitReached() {
         try {
-            mService.onStatsProviderWarningOrLimitReached();
+            mService.notifyStatsProviderWarningOrLimitReached();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
diff --git a/core/java/android/net/PlatformVpnProfile.java b/core/java/android/net/PlatformVpnProfile.java
index 777a90c..3c45799 100644
--- a/core/java/android/net/PlatformVpnProfile.java
+++ b/core/java/android/net/PlatformVpnProfile.java
@@ -83,8 +83,6 @@
 
     /**
      * Returns if the local traffic is exempted from the VPN.
-     *
-     * @hide TODO(184750836): unhide once the implementation is completed
      */
     public final boolean getExcludeLocalRoutes() {
         return mExcludeLocalRoutes;
diff --git a/core/java/android/net/netstats/NetworkStatsDataMigrationUtils.java b/core/java/android/net/netstats/NetworkStatsDataMigrationUtils.java
new file mode 100644
index 0000000..24c22a9
--- /dev/null
+++ b/core/java/android/net/netstats/NetworkStatsDataMigrationUtils.java
@@ -0,0 +1,520 @@
+/*
+ * 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 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.net.ConnectivityManager.TYPE_MOBILE;
+import static android.net.ConnectivityManager.TYPE_MOBILE_DUN;
+import static android.net.ConnectivityManager.TYPE_MOBILE_HIPRI;
+import static android.net.ConnectivityManager.TYPE_MOBILE_MMS;
+import static android.net.ConnectivityManager.TYPE_MOBILE_SUPL;
+import static android.net.NetworkStats.SET_DEFAULT;
+import static android.net.NetworkStats.TAG_NONE;
+
+import android.annotation.NonNull;
+import android.net.NetworkIdentity;
+import android.net.NetworkStatsCollection;
+import android.net.NetworkStatsHistory;
+import android.net.NetworkTemplate;
+import android.os.Environment;
+import android.util.AtomicFile;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.FastDataInput;
+
+import libcore.io.IoUtils;
+
+import java.io.BufferedInputStream;
+import java.io.DataInput;
+import java.io.DataInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.net.ProtocolException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Helper class to read old version of persistent network statistics, the implementation is
+ * intended to be modified by OEM partners to accommodate their custom changes.
+ * @hide
+ */
+// @SystemApi(client = MODULE_LIBRARIES)
+public class NetworkStatsDataMigrationUtils {
+
+    private static final HashMap<String, String> sPrefixLegacyFileNameMap =
+            new HashMap<String, String>() {{
+                put(PREFIX_XT, "netstats_xt.bin");
+                put(PREFIX_UID, "netstats_uid.bin");
+                put(PREFIX_UID_TAG, "netstats_uid.bin");
+            }};
+
+    // These version constants are copied from NetworkStatsCollection/History, which is okay for
+    // OEMs to modify to adapt their own logic.
+    private static class CollectionVersion {
+        static final int VERSION_NETWORK_INIT = 1;
+
+        static final int VERSION_UID_INIT = 1;
+        static final int VERSION_UID_WITH_IDENT = 2;
+        static final int VERSION_UID_WITH_TAG = 3;
+        static final int VERSION_UID_WITH_SET = 4;
+
+        static final int VERSION_UNIFIED_INIT = 16;
+    }
+
+    private static class HistoryVersion {
+        static final int VERSION_INIT = 1;
+        static final int VERSION_ADD_PACKETS = 2;
+        static final int VERSION_ADD_ACTIVE = 3;
+    }
+
+    private static class IdentitySetVersion {
+        static final int VERSION_INIT = 1;
+        static final int VERSION_ADD_ROAMING = 2;
+        static final int VERSION_ADD_NETWORK_ID = 3;
+        static final int VERSION_ADD_METERED = 4;
+        static final int VERSION_ADD_DEFAULT_NETWORK = 5;
+        static final int VERSION_ADD_OEM_MANAGED_NETWORK = 6;
+    }
+
+    /**
+     * File header magic number: "ANET". The definition is copied from NetworkStatsCollection,
+     * but it is fine for OEM to re-define to their own value to adapt the legacy file reading
+     * logic.
+     */
+    private static final int FILE_MAGIC = 0x414E4554;
+    /** Default buffer size from BufferedInputStream */
+    private static final int BUFFER_SIZE = 8192;
+
+    // Constructing this object is not allowed.
+    private NetworkStatsDataMigrationUtils() {
+    }
+
+    // Used to read files at /data/system/netstats_*.bin.
+    @NonNull
+    private static File getPlatformSystemDir() {
+        return new File(Environment.getDataDirectory(), "system");
+    }
+
+    // Used to read files at /data/system/netstats/<tag>.<start>-<end>.
+    @NonNull
+    private static File getPlatformBaseDir() {
+        File baseDir = new File(getPlatformSystemDir(), "netstats");
+        baseDir.mkdirs();
+        return baseDir;
+    }
+
+    // Get /data/system/netstats_*.bin legacy files. Does not check for existence.
+    @NonNull
+    private static File getLegacyBinFileForPrefix(@NonNull String prefix) {
+        return new File(getPlatformSystemDir(), sPrefixLegacyFileNameMap.get(prefix));
+    }
+
+    // List /data/system/netstats/[xt|uid|uid_tag].<start>-<end> legacy files.
+    @NonNull
+    private static ArrayList<File> getPlatformFileListForPrefix(@NonNull String prefix) {
+        final ArrayList<File> list = new ArrayList<>();
+        final File platformFiles = new File(getPlatformBaseDir(), "netstats");
+        if (platformFiles.exists()) {
+            for (String name : platformFiles.list()) {
+                // Skip when prefix doesn't match.
+                if (!name.startsWith(prefix + ".")) continue;
+
+                list.add(new File(platformFiles, name));
+            }
+        }
+        return list;
+    }
+
+    /**
+     * Read legacy persisted network stats from disk. This function provides a default
+     * implementation to read persisted network stats from two different locations.
+     * And this is intended to be modified by OEM to read from custom file format or
+     * locations if necessary.
+     *
+     * @param prefix         Type of data which is being read by the service.
+     * @param bucketDuration Duration of the buckets of the object, in milliseconds.
+     * @return {@link NetworkStatsCollection} instance.
+     */
+    @NonNull
+    public static NetworkStatsCollection readPlatformCollectionLocked(
+            @NonNull String prefix, long bucketDuration) throws IOException {
+        final NetworkStatsCollection.Builder builder =
+                new NetworkStatsCollection.Builder(bucketDuration);
+
+        // Import /data/system/netstats_uid.bin legacy files if exists.
+        switch (prefix) {
+            case PREFIX_UID:
+            case PREFIX_UID_TAG:
+                final File uidFile = getLegacyBinFileForPrefix(prefix);
+                if (uidFile.exists()) {
+                    readLegacyUid(builder, uidFile, PREFIX_UID_TAG.equals(prefix) ? true : false);
+                }
+                break;
+            default:
+                // Ignore other types.
+        }
+
+        // Import /data/system/netstats/[xt|uid|uid_tag].<start>-<end> legacy files if exists.
+        final ArrayList<File> platformFiles = getPlatformFileListForPrefix(prefix);
+        for (final File platformFile : platformFiles) {
+            if (platformFile.exists()) {
+                readPlatformCollection(builder, platformFile);
+            }
+        }
+
+        return builder.build();
+    }
+
+    private static void readPlatformCollection(@NonNull NetworkStatsCollection.Builder builder,
+            @NonNull File file) throws IOException {
+        final FileInputStream is = new FileInputStream(file);
+        final FastDataInput dataIn = new FastDataInput(is, BUFFER_SIZE);
+        try {
+            readPlatformCollection(builder, dataIn);
+        } finally {
+            IoUtils.closeQuietly(dataIn);
+        }
+    }
+
+    /**
+     * Helper function to read old version of NetworkStatsCollections that resided in the platform.
+     *
+     * @hide
+     */
+    @VisibleForTesting
+    public static void readPlatformCollection(@NonNull NetworkStatsCollection.Builder builder,
+            @NonNull DataInput in) throws IOException {
+        // verify file magic header intact
+        final int magic = in.readInt();
+        if (magic != FILE_MAGIC) {
+            throw new ProtocolException("unexpected magic: " + magic);
+        }
+
+        final int version = in.readInt();
+        switch (version) {
+            case CollectionVersion.VERSION_UNIFIED_INIT: {
+                // uid := size *(NetworkIdentitySet size *(uid set tag NetworkStatsHistory))
+                final int identSize = in.readInt();
+                for (int i = 0; i < identSize; i++) {
+                    final Set<NetworkIdentity> ident = readPlatformNetworkIdentitySet(in);
+
+                    final int size = in.readInt();
+                    for (int j = 0; j < size; j++) {
+                        final int uid = in.readInt();
+                        final int set = in.readInt();
+                        final int tag = in.readInt();
+
+                        final NetworkStatsCollection.Key key = new NetworkStatsCollection.Key(
+                                ident, uid, set, tag);
+                        final NetworkStatsHistory history = readPlatformHistory(in);
+                        builder.addEntry(key, history);
+                    }
+                }
+                break;
+            }
+            default: {
+                throw new ProtocolException("unexpected version: " + version);
+            }
+        }
+    }
+
+    // Copied from NetworkStatsHistory#DataStreamUtils.
+    private static long[] readFullLongArray(DataInput in) throws IOException {
+        final int size = in.readInt();
+        if (size < 0) throw new ProtocolException("negative array size");
+        final long[] values = new long[size];
+        for (int i = 0; i < values.length; i++) {
+            values[i] = in.readLong();
+        }
+        return values;
+    }
+
+    // Copied from NetworkStatsHistory#DataStreamUtils.
+    private static long[] readVarLongArray(@NonNull DataInput in) throws IOException {
+        final int size = in.readInt();
+        if (size == -1) return null;
+        if (size < 0) throw new ProtocolException("negative array size");
+        final long[] values = new long[size];
+        for (int i = 0; i < values.length; i++) {
+            values[i] = readVarLong(in);
+        }
+        return values;
+    }
+
+    /**
+     * Read variable-length {@link Long} using protobuf-style approach.
+     */
+    // Copied from NetworkStatsHistory#DataStreamUtils.
+    private static long readVarLong(DataInput in) throws IOException {
+        int shift = 0;
+        long result = 0;
+        while (shift < 64) {
+            byte b = in.readByte();
+            result |= (long) (b & 0x7F) << shift;
+            if ((b & 0x80) == 0) {
+                return result;
+            }
+            shift += 7;
+        }
+        throw new ProtocolException("malformed var long");
+    }
+
+    // Copied from NetworkIdentitySet.
+    private static String readOptionalString(DataInput in) throws IOException {
+        if (in.readByte() != 0) {
+            return in.readUTF();
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * This is copied from NetworkStatsHistory#NetworkStatsHistory(DataInput in). But it is fine
+     * for OEM to re-write the logic to adapt the legacy file reading.
+     */
+    @NonNull
+    private static NetworkStatsHistory readPlatformHistory(@NonNull DataInput in)
+            throws IOException {
+        final long bucketDuration;
+        final long[] bucketStart;
+        final long[] rxBytes;
+        final long[] rxPackets;
+        final long[] txBytes;
+        final long[] txPackets;
+        final long[] operations;
+        final int bucketCount;
+        long[] activeTime = new long[0];
+
+        final int version = in.readInt();
+        switch (version) {
+            case HistoryVersion.VERSION_INIT: {
+                bucketDuration = in.readLong();
+                bucketStart = readFullLongArray(in);
+                rxBytes = readFullLongArray(in);
+                rxPackets = new long[bucketStart.length];
+                txBytes = readFullLongArray(in);
+                txPackets = new long[bucketStart.length];
+                operations = new long[bucketStart.length];
+                bucketCount = bucketStart.length;
+                break;
+            }
+            case HistoryVersion.VERSION_ADD_PACKETS:
+            case HistoryVersion.VERSION_ADD_ACTIVE: {
+                bucketDuration = in.readLong();
+                bucketStart = readVarLongArray(in);
+                activeTime = (version >= HistoryVersion.VERSION_ADD_ACTIVE)
+                        ? readVarLongArray(in)
+                        : new long[bucketStart.length];
+                rxBytes = readVarLongArray(in);
+                rxPackets = readVarLongArray(in);
+                txBytes = readVarLongArray(in);
+                txPackets = readVarLongArray(in);
+                operations = readVarLongArray(in);
+                bucketCount = bucketStart.length;
+                break;
+            }
+            default: {
+                throw new ProtocolException("unexpected version: " + version);
+            }
+        }
+
+        final NetworkStatsHistory.Builder historyBuilder =
+                new NetworkStatsHistory.Builder(bucketDuration, bucketCount);
+        for (int i = 0; i < bucketCount; i++) {
+            final NetworkStatsHistory.Entry entry = new NetworkStatsHistory.Entry(
+                    bucketStart[i], activeTime[i],
+                    rxBytes[i], rxPackets[i], txBytes[i], txPackets[i], operations[i]);
+            historyBuilder.addEntry(entry);
+        }
+
+        return historyBuilder.build();
+    }
+
+    @NonNull
+    private static Set<NetworkIdentity> readPlatformNetworkIdentitySet(@NonNull DataInput in)
+            throws IOException {
+        final int version = in.readInt();
+        final int size = in.readInt();
+        final Set<NetworkIdentity> set = new HashSet<>();
+        for (int i = 0; i < size; i++) {
+            if (version <= IdentitySetVersion.VERSION_INIT) {
+                final int ignored = in.readInt();
+            }
+            final int type = in.readInt();
+            final int ratType = in.readInt();
+            final String subscriberId = readOptionalString(in);
+            final String networkId;
+            if (version >= IdentitySetVersion.VERSION_ADD_NETWORK_ID) {
+                networkId = readOptionalString(in);
+            } else {
+                networkId = null;
+            }
+            final boolean roaming;
+            if (version >= IdentitySetVersion.VERSION_ADD_ROAMING) {
+                roaming = in.readBoolean();
+            } else {
+                roaming = false;
+            }
+
+            final boolean metered;
+            if (version >= IdentitySetVersion.VERSION_ADD_METERED) {
+                metered = in.readBoolean();
+            } else {
+                // If this is the old data and the type is mobile, treat it as metered. (Note that
+                // if this is a mobile network, TYPE_MOBILE is the only possible type that could be
+                // used.)
+                metered = (type == TYPE_MOBILE);
+            }
+
+            final boolean defaultNetwork;
+            if (version >= IdentitySetVersion.VERSION_ADD_DEFAULT_NETWORK) {
+                defaultNetwork = in.readBoolean();
+            } else {
+                defaultNetwork = true;
+            }
+
+            final int oemNetCapabilities;
+            if (version >= IdentitySetVersion.VERSION_ADD_OEM_MANAGED_NETWORK) {
+                oemNetCapabilities = in.readInt();
+            } else {
+                oemNetCapabilities = NetworkIdentity.OEM_NONE;
+            }
+
+            // Legacy files might contain TYPE_MOBILE_* types which were deprecated in later
+            // releases. For backward compatibility, record them as TYPE_MOBILE instead.
+            final int collapsedLegacyType = getCollapsedLegacyType(type);
+            final NetworkIdentity.Builder builder = new NetworkIdentity.Builder()
+                    .setType(collapsedLegacyType)
+                    .setSubscriberId(subscriberId)
+                    .setWifiNetworkKey(networkId)
+                    .setRoaming(roaming).setMetered(metered)
+                    .setDefaultNetwork(defaultNetwork)
+                    .setOemManaged(oemNetCapabilities);
+            if (type == TYPE_MOBILE && ratType != NetworkTemplate.NETWORK_TYPE_ALL) {
+                builder.setRatType(ratType);
+            }
+            set.add(builder.build());
+        }
+        return set;
+    }
+
+    private static int getCollapsedLegacyType(int networkType) {
+        // The constants are referenced from ConnectivityManager#TYPE_MOBILE_*.
+        switch (networkType) {
+            case TYPE_MOBILE:
+            case TYPE_MOBILE_SUPL:
+            case TYPE_MOBILE_MMS:
+            case TYPE_MOBILE_DUN:
+            case TYPE_MOBILE_HIPRI:
+            case 10 /* TYPE_MOBILE_FOTA */:
+            case 11 /* TYPE_MOBILE_IMS */:
+            case 12 /* TYPE_MOBILE_CBS */:
+            case 14 /* TYPE_MOBILE_IA */:
+            case 15 /* TYPE_MOBILE_EMERGENCY */:
+                return TYPE_MOBILE;
+        }
+        return networkType;
+    }
+
+    private static void readLegacyUid(@NonNull NetworkStatsCollection.Builder builder,
+            @NonNull File uidFile, boolean onlyTaggedData) throws IOException {
+        final AtomicFile inputFile = new AtomicFile(uidFile);
+        DataInputStream in = new DataInputStream(new BufferedInputStream(inputFile.openRead()));
+        try {
+            readLegacyUid(builder, in, onlyTaggedData);
+        } finally {
+            IoUtils.closeQuietly(in);
+        }
+    }
+
+    /**
+     * Read legacy Uid statistics file format into the collection.
+     *
+     * This is copied from {@code NetworkStatsCollection#readLegacyUid}.
+     * See {@code NetworkStatsService#maybeUpgradeLegacyStatsLocked}.
+     *
+     * @param taggedData whether to read tagged data. For legacy uid files, the tagged
+     *                   data was stored in the same binary file with non-tagged data.
+     *                   But in later releases, these data should be kept in different
+     *                   recorders.
+     * @hide
+     */
+    @VisibleForTesting
+    public static void readLegacyUid(@NonNull NetworkStatsCollection.Builder builder,
+            @NonNull DataInput in, boolean taggedData) throws IOException {
+        try {
+            // verify file magic header intact
+            final int magic = in.readInt();
+            if (magic != FILE_MAGIC) {
+                throw new ProtocolException("unexpected magic: " + magic);
+            }
+
+            final int version = in.readInt();
+            switch (version) {
+                case CollectionVersion.VERSION_UID_INIT: {
+                    // uid := size *(UID NetworkStatsHistory)
+                    // drop this data version, since we don't have a good
+                    // mapping into NetworkIdentitySet.
+                    break;
+                }
+                case CollectionVersion.VERSION_UID_WITH_IDENT: {
+                    // uid := size *(NetworkIdentitySet size *(UID NetworkStatsHistory))
+                    // drop this data version, since this version only existed
+                    // for a short time.
+                    break;
+                }
+                case CollectionVersion.VERSION_UID_WITH_TAG:
+                case CollectionVersion.VERSION_UID_WITH_SET: {
+                    // uid := size *(NetworkIdentitySet size *(uid set tag NetworkStatsHistory))
+                    final int identSize = in.readInt();
+                    for (int i = 0; i < identSize; i++) {
+                        final Set<NetworkIdentity> ident = readPlatformNetworkIdentitySet(in);
+
+                        final int size = in.readInt();
+                        for (int j = 0; j < size; j++) {
+                            final int uid = in.readInt();
+                            final int set = (version >= CollectionVersion.VERSION_UID_WITH_SET)
+                                    ? in.readInt()
+                                    : SET_DEFAULT;
+                            final int tag = in.readInt();
+
+                            final NetworkStatsCollection.Key key = new NetworkStatsCollection.Key(
+                                    ident, uid, set, tag);
+                            final NetworkStatsHistory history = readPlatformHistory(in);
+
+                            if ((tag == TAG_NONE) != taggedData) {
+                                builder.addEntry(key, history);
+                            }
+                        }
+                    }
+                    break;
+                }
+                default: {
+                    throw new ProtocolException("unknown version: " + version);
+                }
+            }
+        } catch (FileNotFoundException | ProtocolException e) {
+            // missing stats is okay, probably first boot
+        }
+    }
+}
diff --git a/core/java/android/net/vcn/VcnGatewayConnectionConfig.java b/core/java/android/net/vcn/VcnGatewayConnectionConfig.java
index a6830b7..2339656 100644
--- a/core/java/android/net/vcn/VcnGatewayConnectionConfig.java
+++ b/core/java/android/net/vcn/VcnGatewayConnectionConfig.java
@@ -549,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/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/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 07b16ed..adcbb425 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -245,7 +245,6 @@
                 "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/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/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/res/res/xml/sms_short_codes.xml b/core/res/res/xml/sms_short_codes.xml
index 4c20ae1..d1d86a7 100644
--- a/core/res/res/xml/sms_short_codes.xml
+++ b/core/res/res/xml/sms_short_codes.xml
@@ -154,9 +154,9 @@
     <!-- Israel: 4 digits, known premium codes listed -->
     <shortcode country="il" pattern="\\d{4}" premium="4422|4545" />
 
-    <!-- Italy: 5 digits (premium=4xxxx), plus EU:
-         http://clients.txtnation.com/attachments/token/di5kfblvubttvlw/?name=Italy_CASP_EN.pdf -->
-    <shortcode country="it" pattern="\\d{5}" premium="4\\d{4}" free="116\\d{3}|4112503" standard="43\\d{3}" />
+    <!-- Italy: 5 digits (premium=41xxx,42xxx), plus EU:
+         https://www.itu.int/dms_pub/itu-t/oth/02/02/T020200006B0001PDFE.pdf -->
+    <shortcode country="it" pattern="\\d{5}" premium="4\\d{4}" free="116\\d{3}|4112503|40\\d{0,12}" standard="430\\d{2}|431\\d{2}|434\\d{4}|435\\d{4}|439\\d{7}" />
 
     <!-- Japan: 8083 used by SOFTBANK_DCB_2 -->
     <shortcode country="jp" pattern="\\d{1,5}" free="8083" />
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/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/hwui/Readback.cpp b/libs/hwui/Readback.cpp
index f8d6c07..a743d30 100644
--- a/libs/hwui/Readback.cpp
+++ b/libs/hwui/Readback.cpp
@@ -32,8 +32,6 @@
 
 using namespace android::uirenderer::renderthread;
 
-static constexpr bool sEnableExtraCropInset = true;
-
 namespace android {
 namespace uirenderer {
 
@@ -66,20 +64,6 @@
         ALOGW("Surface doesn't have any previously queued frames, nothing to readback from");
         return CopyResult::SourceEmpty;
     }
-
-    if (sEnableExtraCropInset &&
-        (cropRect.right - cropRect.left != bitmap->width() ||
-        cropRect.bottom - cropRect.top != bitmap->height())) {
-       /*
-        * When we need use filtering, we should also make border shrink here like gui.
-        * But we could not check format for YUV or RGB here... Just use 1 pix.
-        */
-        cropRect.left += 0.5f;
-        cropRect.top  += 0.5f;
-        cropRect.right -= 0.5f;
-        cropRect.bottom -= 0.5f;
-    }
-
     UniqueAHardwareBuffer sourceBuffer{rawSourceBuffer};
     AHardwareBuffer_Desc description;
     AHardwareBuffer_describe(sourceBuffer.get(), &description);
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/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 d1bb41e..88b9777 100644
--- a/media/java/android/media/BtProfileConnectionInfo.java
+++ b/media/java/android/media/BtProfileConnectionInfo.java
@@ -15,39 +15,25 @@
  */
 package android.media;
 
-import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.SystemApi;
 import android.bluetooth.BluetoothProfile;
 import android.os.Parcel;
 import android.os.Parcelable;
 
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
 /**
  * Contains information about Bluetooth profile connection state changed
  * {@hide}
  */
 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
 public final class BtProfileConnectionInfo implements Parcelable {
-    /** @hide */
-    @IntDef({
-            BluetoothProfile.A2DP,
-            BluetoothProfile.A2DP_SINK,
-            BluetoothProfile.HEADSET, // Can only be set by BtHelper
-            BluetoothProfile.HEARING_AID,
-            BluetoothProfile.LE_AUDIO,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface BtProfile {}
 
-    private final @BtProfile int mProfile;
+    private final int mProfile;
     private final boolean mSupprNoisy;
     private final int mVolume;
     private final boolean mIsLeOutput;
 
-    private BtProfileConnectionInfo(@BtProfile int profile, boolean suppressNoisyIntent, int volume,
+    private BtProfileConnectionInfo(int profile, boolean suppressNoisyIntent, int volume,
             boolean isLeOutput) {
         mProfile = profile;
         mSupprNoisy = suppressNoisyIntent;
@@ -59,7 +45,7 @@
      * Constructor used by BtHelper when a profile is connected
      * {@hide}
      */
-    public BtProfileConnectionInfo(@BtProfile int profile) {
+    public BtProfileConnectionInfo(int profile) {
         this(profile, false, -1, false);
     }
 
@@ -142,7 +128,7 @@
     /**
      * @return The profile connection
      */
-    public @BtProfile int getProfile() {
+    public int getProfile() {
         return mProfile;
     }
 
diff --git a/media/java/android/media/MediaCodecInfo.java b/media/java/android/media/MediaCodecInfo.java
index 3c152fb..77709d7 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),
         };
@@ -3953,6 +4025,12 @@
         public static final int DolbyVisionLevelUhd30   = 0x40;
         public static final int DolbyVisionLevelUhd48   = 0x80;
         public static final int DolbyVisionLevelUhd60   = 0x100;
+        @SuppressLint("AllUpper")
+        public static final int DolbyVisionLevelUhd120  = 0x200;
+        @SuppressLint("AllUpper")
+        public static final int DolbyVisionLevel8k30    = 0x400;
+        @SuppressLint("AllUpper")
+        public static final int DolbyVisionLevel8k60    = 0x800;
 
         // Profiles and levels for AV1 Codec, corresponding to the definitions in
         // "AV1 Bitstream & Decoding Process Specification", Annex A
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/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 d33666d..2b6570a 100644
--- a/packages/ConnectivityT/framework-t/src/android/app/usage/NetworkStats.java
+++ b/packages/ConnectivityT/framework-t/src/android/app/usage/NetworkStats.java
@@ -556,7 +556,7 @@
     /**
      * 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,
@@ -571,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 f74edb1..84adef5 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 */
@@ -131,6 +145,18 @@
     /** @hide */
     public static final int FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN = 1 << 2;
 
+    /**
+     * Virtual RAT type to represent 5G NSA (Non Stand Alone) mode, where the primary cell is
+     * still LTE and network allocates a secondary 5G cell so telephony reports RAT = LTE along
+     * with NR state as connected. This is a concept added by NetworkStats on top of the telephony
+     * constants for backward compatibility of metrics so this should not be overlapped with any of
+     * the {@code TelephonyManager.NETWORK_TYPE_*} constants.
+     *
+     * @hide
+     */
+    @SystemApi(client = MODULE_LIBRARIES)
+    public static final int NETWORK_TYPE_5G_NSA = -2;
+
     private int mFlags;
 
     /** @hide */
@@ -142,6 +168,11 @@
         setAugmentWithSubscriptionPlan(true);
     }
 
+    /** @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
@@ -150,7 +181,13 @@
      * @param pollOnOpen true if poll is needed.
      * @hide
      */
-    // @SystemApi(client = MODULE_LIBRARIES)
+    // 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;
@@ -204,9 +241,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);
@@ -378,10 +416,11 @@
      * @hide
      */
     @NonNull
-    // @SystemApi(client = MODULE_LIBRARIES)
+    @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);
@@ -411,10 +450,11 @@
      * @hide
      */
     @NonNull
-    // @SystemApi(client = MODULE_LIBRARIES)
+    @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);
@@ -427,6 +467,43 @@
     }
 
     /**
+     * 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.
      *
@@ -492,7 +569,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.
@@ -507,21 +585,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.
     }
 
     /**
@@ -578,50 +687,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) {
@@ -674,12 +816,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);
     }
 
     /**
@@ -704,6 +849,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.
@@ -714,6 +879,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;
+            }
+        }
     }
 
     /**
@@ -832,43 +1016,32 @@
         }
     }
 
-    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;
         }
     }
 
@@ -877,7 +1050,7 @@
      *
      * @hide
      */
-    // @SystemApi
+    @SystemApi(client = MODULE_LIBRARIES)
     @RequiresPermission(anyOf = {
             NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
             android.Manifest.permission.NETWORK_STACK})
@@ -890,17 +1063,18 @@
     }
 
     /**
-     * Advise persistence threshold; may be overridden internally.
+     * Set default value of global alert bytes, the value will be clamped to [128kB, 2MB].
      *
      * @hide
      */
-    // @SystemApi
+    @SystemApi(client = MODULE_LIBRARIES)
     @RequiresPermission(anyOf = {
             NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
-            android.Manifest.permission.NETWORK_STACK})
-    public void advisePersistThreshold(long thresholdBytes) {
+            Manifest.permission.NETWORK_STACK})
+    public void setDefaultGlobalAlert(long alertBytes) {
         try {
-            mService.advisePersistThreshold(thresholdBytes);
+            // TODO: Sync internal naming with the API surface.
+            mService.advisePersistThreshold(alertBytes);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -911,7 +1085,7 @@
      *
      * @hide
      */
-    // @SystemApi
+    @SystemApi(client = MODULE_LIBRARIES)
     @RequiresPermission(anyOf = {
             NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
             android.Manifest.permission.NETWORK_STACK})
@@ -927,9 +1101,17 @@
      * 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
+    @SystemApi(client = MODULE_LIBRARIES)
     @RequiresPermission(anyOf = {
             NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
             android.Manifest.permission.NETWORK_STACK})
@@ -941,4 +1123,52 @@
             throw e.rethrowFromSystemServer();
         }
     }
+
+    /**
+     * Get a RAT type representative of a group of RAT types for network statistics.
+     *
+     * Collapse the given Radio Access Technology (RAT) type into a bucket that
+     * is representative of the original RAT type for network statistics. The
+     * mapping mostly corresponds to {@code TelephonyManager#NETWORK_CLASS_BIT_MASK_*}
+     * but with adaptations specific to the virtual types introduced by
+     * networks stats.
+     *
+     * @param ratType An integer defined in {@code TelephonyManager#NETWORK_TYPE_*}.
+     *
+     * @hide
+     */
+    @SystemApi(client = MODULE_LIBRARIES)
+    public static int getCollapsedRatType(int ratType) {
+        switch (ratType) {
+            case TelephonyManager.NETWORK_TYPE_GPRS:
+            case TelephonyManager.NETWORK_TYPE_GSM:
+            case TelephonyManager.NETWORK_TYPE_EDGE:
+            case TelephonyManager.NETWORK_TYPE_IDEN:
+            case TelephonyManager.NETWORK_TYPE_CDMA:
+            case TelephonyManager.NETWORK_TYPE_1xRTT:
+                return TelephonyManager.NETWORK_TYPE_GSM;
+            case TelephonyManager.NETWORK_TYPE_EVDO_0:
+            case TelephonyManager.NETWORK_TYPE_EVDO_A:
+            case TelephonyManager.NETWORK_TYPE_EVDO_B:
+            case TelephonyManager.NETWORK_TYPE_EHRPD:
+            case TelephonyManager.NETWORK_TYPE_UMTS:
+            case TelephonyManager.NETWORK_TYPE_HSDPA:
+            case TelephonyManager.NETWORK_TYPE_HSUPA:
+            case TelephonyManager.NETWORK_TYPE_HSPA:
+            case TelephonyManager.NETWORK_TYPE_HSPAP:
+            case TelephonyManager.NETWORK_TYPE_TD_SCDMA:
+                return TelephonyManager.NETWORK_TYPE_UMTS;
+            case TelephonyManager.NETWORK_TYPE_LTE:
+            case TelephonyManager.NETWORK_TYPE_IWLAN:
+                return TelephonyManager.NETWORK_TYPE_LTE;
+            case TelephonyManager.NETWORK_TYPE_NR:
+                return TelephonyManager.NETWORK_TYPE_NR;
+            // Virtual RAT type for 5G NSA mode, see
+            // {@link NetworkStatsManager#NETWORK_TYPE_5G_NSA}.
+            case NetworkStatsManager.NETWORK_TYPE_5G_NSA:
+                return NetworkStatsManager.NETWORK_TYPE_5G_NSA;
+            default:
+                return TelephonyManager.NETWORK_TYPE_UNKNOWN;
+        }
+    }
 }
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 a4babb5..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);
diff --git a/packages/ConnectivityT/framework-t/src/android/net/INetworkStatsSession.aidl b/packages/ConnectivityT/framework-t/src/android/net/INetworkStatsSession.aidl
index babe0bf..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.
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 49aa99b..a423783 100644
--- a/packages/ConnectivityT/framework-t/src/android/net/IpSecManager.java
+++ b/packages/ConnectivityT/framework-t/src/android/net/IpSecManager.java
@@ -27,6 +27,7 @@
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.os.Binder;
+import android.os.IBinder;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
 import android.os.ServiceSpecificException;
@@ -988,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..73b9c72 100644
--- a/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentity.java
+++ b/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentity.java
@@ -16,18 +16,30 @@
 
 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.app.usage.NetworkStatsManager;
 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 +49,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 +76,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 +110,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 +118,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 +132,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 +181,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 +197,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 +302,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 != NetworkStatsManager.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 9d532e7..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";
 
     /**
@@ -678,6 +679,35 @@
     }
 
     /**
+     * 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
      */
diff --git a/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsCollection.java b/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsCollection.java
index 9f9d73f..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;
@@ -69,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
@@ -77,6 +85,7 @@
  *
  * @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" */
@@ -100,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;
@@ -117,6 +134,7 @@
         mDirty = false;
     }
 
+    /** @hide */
     public long getStartMillis() {
         return mStartMillis;
     }
@@ -124,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) {
@@ -133,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
@@ -168,6 +193,7 @@
         }
     }
 
+    /** @hide */
     @VisibleForTesting
     public long roundDown(long time) {
         if (time == Long.MIN_VALUE || time == Long.MAX_VALUE
@@ -182,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<>();
@@ -206,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,
@@ -331,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) {
@@ -377,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) {
@@ -387,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());
 
@@ -403,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);
@@ -433,6 +471,7 @@
         }
     }
 
+    /** @hide */
     @Override
     public void read(InputStream in) throws IOException {
         read((DataInput) new DataInputStream(in));
@@ -472,6 +511,7 @@
         }
     }
 
+    /** @hide */
     @Override
     public void write(OutputStream out) throws IOException {
         write((DataOutput) new DataOutputStream(out));
@@ -514,6 +554,7 @@
      * See {@code NetworkStatsService#maybeUpgradeLegacyStatsLocked}.
      *
      * @deprecated
+     * @hide
      */
     @Deprecated
     public void readLegacyNetwork(File file) throws IOException {
@@ -559,6 +600,7 @@
      * See {@code NetworkStatsService#maybeUpgradeLegacyStatsLocked}.
      *
      * @deprecated
+     * @hide
      */
     @Deprecated
     public void readLegacyUid(File file, boolean onlyTags) throws IOException {
@@ -629,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<>();
@@ -665,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());
@@ -683,6 +727,7 @@
         }
     }
 
+    /** @hide */
     public void dumpDebug(ProtoOutputStream proto, long tag) {
         final long start = proto.start(tag);
 
@@ -706,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");
@@ -768,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;
@@ -790,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
@@ -799,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..27e717f 100644
--- a/packages/ConnectivityT/framework-t/src/android/net/NetworkTemplate.java
+++ b/packages/ConnectivityT/framework-t/src/android/net/NetworkTemplate.java
@@ -41,13 +41,13 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
+import android.app.usage.NetworkStatsManager;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.net.wifi.WifiInfo;
 import android.os.Build;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.telephony.Annotation.NetworkType;
-import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.ArraySet;
 
@@ -58,9 +58,7 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.Arrays;
-import java.util.Collection;
 import java.util.Comparator;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Objects;
 import java.util.Set;
@@ -136,15 +134,6 @@
      * {@code TelephonyManager.NETWORK_TYPE_*} constants, and thus needs to stay in sync.
      */
     public static final int NETWORK_TYPE_ALL = -1;
-    /**
-     * Virtual RAT type to represent 5G NSA (Non Stand Alone) mode, where the primary cell is
-     * still LTE and network allocates a secondary 5G cell so telephony reports RAT = LTE along
-     * with NR state as connected. This should not be overlapped with any of the
-     * {@code TelephonyManager.NETWORK_TYPE_*} constants.
-     *
-     * @hide
-     */
-    public static final int NETWORK_TYPE_5G_NSA = -2;
 
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
@@ -263,7 +252,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 +272,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 +353,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 +402,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 +424,7 @@
         mMetered = metered;
         mRoaming = roaming;
         mDefaultNetwork = defaultNetwork;
-        mSubType = subType;
+        mRatType = ratType;
         mOemManaged = oemManaged;
         mSubscriberIdMatchRule = subscriberIdMatchRule;
         checkValidSubscriberIdMatchRule(matchRule, subscriberIdMatchRule);
@@ -453,7 +442,7 @@
         mMetered = in.readInt();
         mRoaming = in.readInt();
         mDefaultNetwork = in.readInt();
-        mSubType = in.readInt();
+        mRatType = in.readInt();
         mOemManaged = in.readInt();
         mSubscriberIdMatchRule = in.readInt();
     }
@@ -467,7 +456,7 @@
         dest.writeInt(mMetered);
         dest.writeInt(mRoaming);
         dest.writeInt(mDefaultNetwork);
-        dest.writeInt(mSubType);
+        dest.writeInt(mRatType);
         dest.writeInt(mOemManaged);
         dest.writeInt(mSubscriberIdMatchRule);
     }
@@ -500,8 +489,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 +503,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 +515,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 +582,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 +624,7 @@
      * Get the Radio Access Technology(RAT) type filter of the template.
      */
     public int getRatType() {
-        return mSubType;
+        return mRatType;
     }
 
     /**
@@ -652,7 +641,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 +699,9 @@
     }
 
     private boolean matchesCollapsedRatType(NetworkIdentity ident) {
-        return mSubType == NETWORK_TYPE_ALL
-                || getCollapsedRatType(mSubType) == getCollapsedRatType(ident.mSubType);
+        return mRatType == NETWORK_TYPE_ALL
+                || NetworkStatsManager.getCollapsedRatType(mRatType)
+                == NetworkStatsManager.getCollapsedRatType(ident.mRatType);
     }
 
     /**
@@ -729,7 +721,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) {
@@ -753,91 +745,13 @@
     }
 
     /**
-     * Get a Radio Access Technology(RAT) type that is representative of a group of RAT types.
-     * The mapping is corresponding to {@code TelephonyManager#NETWORK_CLASS_BIT_MASK_*}.
-     *
-     * @param ratType An integer defined in {@code TelephonyManager#NETWORK_TYPE_*}.
-     *
-     * @hide
-     */
-    // TODO: 1. Consider move this to TelephonyManager if used by other modules.
-    //       2. Consider make this configurable.
-    //       3. Use TelephonyManager APIs when available.
-    // TODO: @SystemApi when ready.
-    public static int getCollapsedRatType(int ratType) {
-        switch (ratType) {
-            case TelephonyManager.NETWORK_TYPE_GPRS:
-            case TelephonyManager.NETWORK_TYPE_GSM:
-            case TelephonyManager.NETWORK_TYPE_EDGE:
-            case TelephonyManager.NETWORK_TYPE_IDEN:
-            case TelephonyManager.NETWORK_TYPE_CDMA:
-            case TelephonyManager.NETWORK_TYPE_1xRTT:
-                return TelephonyManager.NETWORK_TYPE_GSM;
-            case TelephonyManager.NETWORK_TYPE_EVDO_0:
-            case TelephonyManager.NETWORK_TYPE_EVDO_A:
-            case TelephonyManager.NETWORK_TYPE_EVDO_B:
-            case TelephonyManager.NETWORK_TYPE_EHRPD:
-            case TelephonyManager.NETWORK_TYPE_UMTS:
-            case TelephonyManager.NETWORK_TYPE_HSDPA:
-            case TelephonyManager.NETWORK_TYPE_HSUPA:
-            case TelephonyManager.NETWORK_TYPE_HSPA:
-            case TelephonyManager.NETWORK_TYPE_HSPAP:
-            case TelephonyManager.NETWORK_TYPE_TD_SCDMA:
-                return TelephonyManager.NETWORK_TYPE_UMTS;
-            case TelephonyManager.NETWORK_TYPE_LTE:
-            case TelephonyManager.NETWORK_TYPE_IWLAN:
-                return TelephonyManager.NETWORK_TYPE_LTE;
-            case TelephonyManager.NETWORK_TYPE_NR:
-                return TelephonyManager.NETWORK_TYPE_NR;
-            // Virtual RAT type for 5G NSA mode, see {@link NetworkTemplate#NETWORK_TYPE_5G_NSA}.
-            case NetworkTemplate.NETWORK_TYPE_5G_NSA:
-                return NetworkTemplate.NETWORK_TYPE_5G_NSA;
-            default:
-                return TelephonyManager.NETWORK_TYPE_UNKNOWN;
-        }
-    }
-
-    /**
-     * Return all supported collapsed RAT types that could be returned by
-     * {@link #getCollapsedRatType(int)}.
-     *
-     * @hide
-     */
-    // TODO: @SystemApi when ready.
-    @NonNull
-    public static final int[] getAllCollapsedRatTypes() {
-        final int[] ratTypes = TelephonyManager.getAllNetworkTypes();
-        final HashSet<Integer> collapsedRatTypes = new HashSet<>();
-        for (final int ratType : ratTypes) {
-            collapsedRatTypes.add(NetworkTemplate.getCollapsedRatType(ratType));
-        }
-        // Add NETWORK_TYPE_5G_NSA to the returned list since 5G NSA is a virtual RAT type and
-        // it is not in TelephonyManager#NETWORK_TYPE_* constants.
-        // See {@link NetworkTemplate#NETWORK_TYPE_5G_NSA}.
-        collapsedRatTypes.add(NetworkTemplate.getCollapsedRatType(NETWORK_TYPE_5G_NSA));
-        // Ensure that unknown type is returned.
-        collapsedRatTypes.add(TelephonyManager.NETWORK_TYPE_UNKNOWN);
-        return toIntArray(collapsedRatTypes);
-    }
-
-    @NonNull
-    private static int[] toIntArray(@NonNull Collection<Integer> list) {
-        final int[] array = new int[list.size()];
-        int i = 0;
-        for (final Integer item : list) {
-            array[i++] = item;
-        }
-        return array;
-    }
-
-    /**
      * Check if matches Wi-Fi network template.
      */
     private boolean matchesWifi(NetworkIdentity ident) {
         switch (ident.mType) {
             case TYPE_WIFI:
                 return matchesSubscriberId(ident.mSubscriberId)
-                        && matchesWifiNetworkKey(ident.mNetworkId);
+                        && matchesWifiNetworkKey(ident.mWifiNetworkKey);
             default:
                 return false;
         }
@@ -1059,9 +973,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 1af32bf..c2f0cdf 100644
--- a/packages/ConnectivityT/framework-t/src/android/net/TrafficStats.java
+++ b/packages/ConnectivityT/framework-t/src/android/net/TrafficStats.java
@@ -16,8 +16,9 @@
 
 package android.net;
 
+import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
+
 import android.annotation.NonNull;
-import android.annotation.Nullable;
 import android.annotation.SuppressLint;
 import android.annotation.SystemApi;
 import android.annotation.TestApi;
@@ -27,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.IBinder;
 import android.os.RemoteException;
+import android.util.Log;
 
 import com.android.server.NetworkManagementSocketTagger;
 
@@ -37,8 +39,6 @@
 
 import java.io.FileDescriptor;
 import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
 import java.net.DatagramSocket;
 import java.net.Socket;
 import java.net.SocketException;
@@ -177,25 +177,12 @@
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 130143562)
     private synchronized static INetworkStatsService getStatsService() {
         if (sStatsService == null) {
-            sStatsService = getStatsBinder();
+            throw new IllegalStateException("TrafficStats not initialized, uid="
+                    + Binder.getCallingUid());
         }
         return sStatsService;
     }
 
-    @Nullable
-    private static INetworkStatsService getStatsBinder() {
-        try {
-            final Method getServiceMethod = Class.forName("android.os.ServiceManager")
-                    .getDeclaredMethod("getService", new Class[]{String.class});
-            final IBinder binder = (IBinder) getServiceMethod.invoke(
-                    null, Context.NETWORK_STATS_SERVICE);
-            return INetworkStatsService.Stub.asInterface(binder);
-        } catch (NoSuchMethodException | ClassNotFoundException | IllegalAccessException
-                | InvocationTargetException e) {
-            throw new NullPointerException("Cannot get INetworkStatsService: " + e);
-        }
-    }
-
     /**
      * Snapshot of {@link NetworkStats} when the currently active profiling
      * session started, or {@code null} if no session active.
@@ -210,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>
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/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/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 e15acf3..8e584d0 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;
@@ -47,23 +51,6 @@
 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;
@@ -73,7 +60,6 @@
 import static com.android.net.module.util.NetworkCapabilitiesUtils.getDisplayTransport;
 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;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -112,6 +98,7 @@
 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;
@@ -119,12 +106,10 @@
 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.Looper;
 import android.os.Message;
-import android.os.Messenger;
 import android.os.PowerManager;
 import android.os.RemoteException;
 import android.os.ServiceSpecificException;
@@ -135,6 +120,7 @@
 import android.provider.Settings.Global;
 import android.service.NetworkInterfaceProto;
 import android.service.NetworkStatsServiceDumpProto;
+import android.system.ErrnoException;
 import android.telephony.PhoneStateListener;
 import android.telephony.SubscriptionPlan;
 import android.text.TextUtils;
@@ -153,10 +139,14 @@
 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.BpfMap;
 import com.android.net.module.util.CollectionUtils;
+import com.android.net.module.util.IBpfMap;
+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.LocalServices;
+import com.android.net.module.util.Struct.U32;
+import com.android.net.module.util.Struct.U8;
 
 import java.io.File;
 import java.io.FileDescriptor;
@@ -217,6 +207,14 @@
     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";
+
+    // This is current path but may be changed soon.
+    private static final String UID_COUNTERSET_MAP_PATH =
+            "/sys/fs/bpf/map_netd_uid_counterset_map";
+
     private final Context mContext;
     private final NetworkStatsFactory mStatsFactory;
     private final AlarmManager mAlarmManager;
@@ -243,11 +241,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.
      */
@@ -257,9 +250,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 android.app.usage.NetworkStatsManager#getCollapsedRatType}.
          * Enabling this decreases the level of detail but saves performance, disk space and
          * amount of data logged.
          */
@@ -306,6 +299,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];
@@ -337,8 +333,14 @@
     @GuardedBy("mStatsLock")
     private NetworkStatsCollection mXtStatsCached;
 
-    /** Current counter sets for each UID. */
+    /**
+     * Current counter sets for each UID.
+     * TODO: maybe remove mActiveUidCounterSet and read UidCouneterSet value from mUidCounterSetMap
+     * directly ? But if mActiveUidCounterSet would be accessed very frequently, maybe keep
+     * mActiveUidCounterSet to avoid accessing kernel too frequently.
+     */
     private SparseIntArray mActiveUidCounterSet = new SparseIntArray();
+    private final IBpfMap<U32, U8> mUidCounterSetMap;
 
     /** Data layer operation counters for splicing into other structures. */
     private NetworkStats mUidOperations = new NetworkStats(0L, 10);
@@ -366,6 +368,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");
     }
@@ -428,7 +436,7 @@
         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());
 
@@ -458,10 +466,14 @@
         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();
+        mUidCounterSetMap = mDeps.getUidCounterSetMap();
     }
 
     /**
@@ -509,6 +521,31 @@
                 }
             };
         }
+
+        /**
+         * @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);
+        }
+
+        /** Get counter sets map for each UID. */
+        public IBpfMap<U32, U8> getUidCounterSetMap() {
+            try {
+                return new BpfMap<U32, U8>(UID_COUNTERSET_MAP_PATH, BpfMap.BPF_F_RDWR,
+                        U32.class, U8.class);
+            } catch (ErrnoException e) {
+                Log.wtf(TAG, "Cannot create uid counter set map: " + e);
+                return null;
+            }
+        }
     }
 
     /**
@@ -557,7 +594,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);
@@ -591,13 +628,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();
     }
@@ -708,12 +745,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 {
@@ -727,7 +777,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);
@@ -761,26 +811,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);
@@ -798,6 +863,7 @@
             @Override
             public NetworkStats getTaggedSummaryForAllUid(
                     NetworkTemplate template, long start, long end) {
+                enforceTemplatePermissions(template, callingPackage);
                 try {
                     final NetworkStats tagStats = getUidTagComplete()
                             .getSummary(template, start, end, mAccessLevel, mCallingUid);
@@ -810,6 +876,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,
@@ -824,6 +891,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,
@@ -845,6 +915,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);
@@ -881,7 +971,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);
@@ -898,14 +988,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);
         }
     }
 
@@ -936,8 +1026,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);
@@ -956,11 +1055,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);
@@ -1000,6 +1103,29 @@
         }
     }
 
+    private void setKernelCounterSet(int uid, int set) {
+        if (mUidCounterSetMap == null) {
+            Log.wtf(TAG, "Fail to set UidCounterSet: Null bpf map");
+            return;
+        }
+
+        if (set == SET_DEFAULT) {
+            try {
+                mUidCounterSetMap.deleteEntry(new U32(uid));
+            } catch (ErrnoException e) {
+                Log.w(TAG, "UidCounterSetMap.deleteEntry(" + uid + ") failed with errno: " + e);
+            }
+            return;
+        }
+
+        try {
+            mUidCounterSetMap.updateEntry(new U32(uid), new U8((short) set));
+        } catch (ErrnoException e) {
+            Log.w(TAG, "UidCounterSetMap.updateEntry(" + uid + ", " + set
+                    + ") failed with errno: " + e);
+        }
+    }
+
     @VisibleForTesting
     public void setUidForeground(int uid, boolean uidForeground) {
         PermissionUtils.enforceNetworkStackPermission(mContext);
@@ -1080,21 +1206,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);
         }
@@ -1319,16 +1444,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.
@@ -1343,12 +1470,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);
@@ -1358,6 +1485,9 @@
                 if (isMobile) {
                     mobileIfaces.add(baseIface);
                 }
+                if (isWifi) {
+                    wifiIfaces.add(baseIface);
+                }
             }
 
             // Traffic occurring on stacked interfaces is usually clatd.
@@ -1399,6 +1529,9 @@
                     if (isMobile) {
                         mobileIfaces.add(iface);
                     }
+                    if (isWifi) {
+                        wifiIfaces.add(iface);
+                    }
 
                     mStatsFactory.noteStackedIface(iface, baseIface);
                 }
@@ -1406,11 +1539,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) {
@@ -1428,11 +1566,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;
         }
@@ -2120,7 +2258,7 @@
         public void notifyWarningOrLimitReached() {
             Log.d(TAG, mTag + ": notifyWarningOrLimitReached");
             BinderUtils.withCleanCallingIdentity(() ->
-                    mNetworkPolicyManager.onStatsProviderWarningOrLimitReached());
+                    mNetworkPolicyManager.notifyStatsProviderWarningOrLimitReached());
         }
 
         @Override
@@ -2179,24 +2317,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() {
@@ -2204,25 +2329,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() {
@@ -2230,31 +2353,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/ConnectivityT/service/src/com/android/server/net/NetworkStatsSubscriptionsMonitor.java b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsSubscriptionsMonitor.java
index 4875f1c..3e35e603 100644
--- a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsSubscriptionsMonitor.java
+++ b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsSubscriptionsMonitor.java
@@ -16,8 +16,8 @@
 
 package com.android.server.net;
 
-import static android.net.NetworkTemplate.NETWORK_TYPE_5G_NSA;
-import static android.net.NetworkTemplate.getCollapsedRatType;
+import static android.app.usage.NetworkStatsManager.NETWORK_TYPE_5G_NSA;
+import static android.app.usage.NetworkStatsManager.getCollapsedRatType;
 import static android.telephony.TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED;
 import static android.telephony.TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA;
 import static android.telephony.TelephonyManager.NETWORK_TYPE_LTE;
@@ -57,7 +57,7 @@
          *
          * @param subscriberId IMSI of the subscription.
          * @param collapsedRatType collapsed RAT type.
-         *                         @see android.net.NetworkTemplate#getCollapsedRatType(int).
+         *                     @see android.app.usage.NetworkStatsManager#getCollapsedRatType(int).
          */
         void onCollapsedRatTypeChanged(@NonNull String subscriberId,
                 @Annotation.NetworkType int collapsedRatType);
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/ChartData.java b/packages/SettingsLib/src/com/android/settingslib/net/ChartData.java
index e30aac5..a69c59c 100644
--- a/packages/SettingsLib/src/com/android/settingslib/net/ChartData.java
+++ b/packages/SettingsLib/src/com/android/settingslib/net/ChartData.java
@@ -16,12 +16,18 @@
 
 package com.android.settingslib.net;
 
-import android.net.NetworkStatsHistory;
+import android.app.usage.NetworkStats;
+
+import java.util.List;
 
 public class ChartData {
-    public NetworkStatsHistory network;
+    // Collect the data usage history of the network from the given {@link NetworkTemplate}.
+    public List<NetworkStats.Bucket> network;
 
-    public NetworkStatsHistory detail;
-    public NetworkStatsHistory detailDefault;
-    public NetworkStatsHistory detailForeground;
+    // Collect the detail datausage history (foreground + Background).
+    public List<NetworkStats.Bucket> detail;
+    // Collect background datausage history.
+    public List<NetworkStats.Bucket> detailDefault;
+    // Collect foreground datausage history.
+    public List<NetworkStats.Bucket> detailForeground;
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/ChartDataLoader.java b/packages/SettingsLib/src/com/android/settingslib/net/ChartDataLoader.java
index 60d22a0..573922f 100644
--- a/packages/SettingsLib/src/com/android/settingslib/net/ChartDataLoader.java
+++ b/packages/SettingsLib/src/com/android/settingslib/net/ChartDataLoader.java
@@ -19,20 +19,21 @@
 import static android.net.NetworkStats.SET_DEFAULT;
 import static android.net.NetworkStats.SET_FOREGROUND;
 import static android.net.NetworkStats.TAG_NONE;
-import static android.net.NetworkStatsHistory.FIELD_RX_BYTES;
-import static android.net.NetworkStatsHistory.FIELD_TX_BYTES;
-import static android.text.format.DateUtils.HOUR_IN_MILLIS;
 
+import android.annotation.NonNull;
+import android.app.usage.NetworkStats;
+import android.app.usage.NetworkStatsManager;
 import android.content.AsyncTaskLoader;
 import android.content.Context;
-import android.net.INetworkStatsSession;
-import android.net.NetworkStatsHistory;
 import android.net.NetworkTemplate;
 import android.os.Bundle;
 import android.os.RemoteException;
 
 import com.android.settingslib.AppItem;
 
+import java.util.ArrayList;
+import java.util.List;
+
 /**
  * Framework loader is deprecated, use the compat version instead.
  *
@@ -42,26 +43,20 @@
 public class ChartDataLoader extends AsyncTaskLoader<ChartData> {
     private static final String KEY_TEMPLATE = "template";
     private static final String KEY_APP = "app";
-    private static final String KEY_FIELDS = "fields";
 
-    private final INetworkStatsSession mSession;
+    private final NetworkStatsManager mNetworkStatsManager;
     private final Bundle mArgs;
 
     public static Bundle buildArgs(NetworkTemplate template, AppItem app) {
-        return buildArgs(template, app, FIELD_RX_BYTES | FIELD_TX_BYTES);
-    }
-
-    public static Bundle buildArgs(NetworkTemplate template, AppItem app, int fields) {
         final Bundle args = new Bundle();
         args.putParcelable(KEY_TEMPLATE, template);
         args.putParcelable(KEY_APP, app);
-        args.putInt(KEY_FIELDS, fields);
         return args;
     }
 
-    public ChartDataLoader(Context context, INetworkStatsSession session, Bundle args) {
+    public ChartDataLoader(Context context, NetworkStatsManager statsManager, Bundle args) {
         super(context);
-        mSession = session;
+        mNetworkStatsManager = statsManager;
         mArgs = args;
     }
 
@@ -75,10 +70,9 @@
     public ChartData loadInBackground() {
         final NetworkTemplate template = mArgs.getParcelable(KEY_TEMPLATE);
         final AppItem app = mArgs.getParcelable(KEY_APP);
-        final int fields = mArgs.getInt(KEY_FIELDS);
 
         try {
-            return loadInBackground(template, app, fields);
+            return loadInBackground(template, app);
         } catch (RemoteException e) {
             // since we can't do much without history, and we don't want to
             // leave with half-baked UI, we bail hard.
@@ -86,10 +80,22 @@
         }
     }
 
-    private ChartData loadInBackground(NetworkTemplate template, AppItem app, int fields)
+    @NonNull
+    private List<NetworkStats.Bucket> convertToBuckets(@NonNull NetworkStats stats) {
+        final List<NetworkStats.Bucket> ret = new ArrayList<>();
+        while (stats.hasNextBucket()) {
+            final NetworkStats.Bucket bucket = new NetworkStats.Bucket();
+            stats.getNextBucket(bucket);
+            ret.add(bucket);
+        }
+        return ret;
+    }
+
+    private ChartData loadInBackground(NetworkTemplate template, AppItem app)
             throws RemoteException {
         final ChartData data = new ChartData();
-        data.network = mSession.getHistoryForNetwork(template, fields);
+        data.network = convertToBuckets(mNetworkStatsManager.queryDetailsForDevice(
+                template, Long.MIN_VALUE, Long.MAX_VALUE));
 
         if (app != null) {
             // load stats for current uid and template
@@ -103,13 +109,13 @@
             }
 
             if (size > 0) {
-                data.detail = new NetworkStatsHistory(data.detailForeground.getBucketDuration());
-                data.detail.recordEntireHistory(data.detailDefault);
-                data.detail.recordEntireHistory(data.detailForeground);
+                data.detail = new ArrayList<>();
+                data.detail.addAll(data.detailDefault);
+                data.detail.addAll(data.detailForeground);
             } else {
-                data.detailDefault = new NetworkStatsHistory(HOUR_IN_MILLIS);
-                data.detailForeground = new NetworkStatsHistory(HOUR_IN_MILLIS);
-                data.detail = new NetworkStatsHistory(HOUR_IN_MILLIS);
+                data.detailDefault = new ArrayList<>();
+                data.detailForeground = new ArrayList<>();
+                data.detail = new ArrayList<>();
             }
         }
 
@@ -129,17 +135,17 @@
     }
 
     /**
-     * Collect {@link NetworkStatsHistory} for the requested UID, combining with
-     * an existing {@link NetworkStatsHistory} if provided.
+     * Collect {@link List<NetworkStats.Bucket>} for the requested UID, combining with
+     * an existing {@link List<NetworkStats.Bucket>} if provided.
      */
-    private NetworkStatsHistory collectHistoryForUid(
-            NetworkTemplate template, int uid, int set, NetworkStatsHistory existing)
-            throws RemoteException {
-        final NetworkStatsHistory history = mSession.getHistoryForUid(
-                template, uid, set, TAG_NONE, FIELD_RX_BYTES | FIELD_TX_BYTES);
+    private List<NetworkStats.Bucket> collectHistoryForUid(
+            NetworkTemplate template, int uid, int set, List<NetworkStats.Bucket> existing) {
+        final List<NetworkStats.Bucket> history = convertToBuckets(
+                mNetworkStatsManager.queryDetailsForUidTagState(template,
+                        Long.MIN_VALUE, Long.MAX_VALUE, uid, TAG_NONE, set));
 
         if (existing != null) {
-            existing.recordEntireHistory(history);
+            existing.addAll(history);
             return existing;
         } else {
             return history;
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/SummaryForAllUidLoader.java b/packages/SettingsLib/src/com/android/settingslib/net/SummaryForAllUidLoader.java
index 649aeff..8da6032 100644
--- a/packages/SettingsLib/src/com/android/settingslib/net/SummaryForAllUidLoader.java
+++ b/packages/SettingsLib/src/com/android/settingslib/net/SummaryForAllUidLoader.java
@@ -16,13 +16,12 @@
 
 package com.android.settingslib.net;
 
+import android.app.usage.NetworkStats;
+import android.app.usage.NetworkStatsManager;
 import android.content.AsyncTaskLoader;
 import android.content.Context;
-import android.net.INetworkStatsSession;
-import android.net.NetworkStats;
 import android.net.NetworkTemplate;
 import android.os.Bundle;
-import android.os.RemoteException;
 
 /**
  * Framework loader is deprecated, use the compat version instead.
@@ -35,7 +34,7 @@
     private static final String KEY_START = "start";
     private static final String KEY_END = "end";
 
-    private final INetworkStatsSession mSession;
+    private final NetworkStatsManager mNetworkStatsManager;
     private final Bundle mArgs;
 
     public static Bundle buildArgs(NetworkTemplate template, long start, long end) {
@@ -46,9 +45,9 @@
         return args;
     }
 
-    public SummaryForAllUidLoader(Context context, INetworkStatsSession session, Bundle args) {
+    public SummaryForAllUidLoader(Context context, Bundle args) {
         super(context);
-        mSession = session;
+        mNetworkStatsManager = context.getSystemService(NetworkStatsManager.class);
         mArgs = args;
     }
 
@@ -63,12 +62,7 @@
         final NetworkTemplate template = mArgs.getParcelable(KEY_TEMPLATE);
         final long start = mArgs.getLong(KEY_START);
         final long end = mArgs.getLong(KEY_END);
-
-        try {
-            return mSession.getSummaryForAllUid(template, start, end, false);
-        } catch (RemoteException e) {
-            return null;
-        }
+        return mNetworkStatsManager.querySummary(template, start, end);
     }
 
     @Override
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/NetworkCycleDataForUidLoaderTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/NetworkCycleDataForUidLoaderTest.java
index 5b0f659..2f3da83 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/NetworkCycleDataForUidLoaderTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/NetworkCycleDataForUidLoaderTest.java
@@ -16,6 +16,7 @@
 
 package com.android.settingslib.net;
 
+import static android.app.usage.NetworkStats.Bucket.STATE_ALL;
 import static android.app.usage.NetworkStats.Bucket.STATE_FOREGROUND;
 import static android.net.NetworkStats.TAG_NONE;
 
@@ -83,7 +84,6 @@
 
         mLoader.recordUsage(start, end);
 
-        verify(mNetworkStatsManager).queryDetailsForUid(mNetworkTemplate, start, end, uid);
         verify(mNetworkStatsManager).queryDetailsForUidTagState(
                 mNetworkTemplate, start, end, uid, TAG_NONE, STATE_FOREGROUND);
     }
@@ -116,9 +116,12 @@
 
         mLoader.recordUsage(start, end);
 
-        verify(mNetworkStatsManager).queryDetailsForUid(mNetworkTemplate, start, end, 1);
-        verify(mNetworkStatsManager).queryDetailsForUid(mNetworkTemplate, start, end, 2);
-        verify(mNetworkStatsManager).queryDetailsForUid(mNetworkTemplate, start, end, 3);
+        verify(mNetworkStatsManager).queryDetailsForUidTagState(mNetworkTemplate, start, end, 1,
+                TAG_NONE, STATE_ALL);
+        verify(mNetworkStatsManager).queryDetailsForUidTagState(mNetworkTemplate, start, end, 2,
+                TAG_NONE, STATE_ALL);
+        verify(mNetworkStatsManager).queryDetailsForUidTagState(mNetworkTemplate, start, end, 3,
+                TAG_NONE, STATE_ALL);
     }
 
 }
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 5b9b74a..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" />
@@ -503,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" />
@@ -527,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 3951680..39ac5ef 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;
@@ -34,16 +34,13 @@
 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_RESTRICTED;
 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_STANDBY;
 import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT;
-import static android.net.NetworkStats.SET_DEFAULT;
-import static android.net.NetworkStats.STATS_PER_UID;
-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;
@@ -57,7 +54,6 @@
 import android.net.NetworkStack;
 import android.net.NetworkStats;
 import android.net.RouteInfo;
-import android.net.TetherStatsParcel;
 import android.net.UidRangeParcel;
 import android.net.util.NetdService;
 import android.os.BatteryStats;
@@ -1158,19 +1154,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) {
@@ -1179,7 +1168,7 @@
                         quotaList.delete(uid);
                     }
                 }
-            } catch (RemoteException | ServiceSpecificException e) {
+            } catch (RuntimeException e) {
                 throw new IllegalStateException(e);
             } finally {
                 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
@@ -1292,40 +1281,9 @@
     private class NetdTetheringStatsProvider extends ITetheringStatsProvider.Stub {
         @Override
         public NetworkStats getTetherStats(int how) {
-            // 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 TetherStatsParcel[] tetherStatsVec;
-            try {
-                tetherStatsVec = mNetdService.tetherGetStats();
-            } catch (RemoteException | ServiceSpecificException e) {
-                throw new IllegalStateException("problem parsing tethering stats: ", e);
-            }
-
-            final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(),
-                tetherStatsVec.length);
-            final NetworkStats.Entry entry = new NetworkStats.Entry();
-
-            for (TetherStatsParcel tetherStats : tetherStatsVec) {
-                try {
-                    entry.iface = tetherStats.iface;
-                    entry.uid = UID_TETHERING;
-                    entry.set = SET_DEFAULT;
-                    entry.tag = TAG_NONE;
-                    entry.rxBytes   = tetherStats.rxBytes;
-                    entry.rxPackets = tetherStats.rxPackets;
-                    entry.txBytes   = tetherStats.txBytes;
-                    entry.txPackets = tetherStats.txPackets;
-                    stats.combineValues(entry);
-                } catch (ArrayIndexOutOfBoundsException e) {
-                    throw new IllegalStateException("invalid tethering stats " + e);
-                }
-            }
-
-            return stats;
+            // Remove the implementation of NetdTetheringStatsProvider#getTetherStats
+            // since all callers are migrated to use INetd#tetherGetStats directly.
+            throw new UnsupportedOperationException();
         }
 
         @Override
@@ -1336,20 +1294,9 @@
 
     @Override
     public NetworkStats getNetworkStatsTethering(int how) {
-        NetworkStack.checkNetworkStackPermission(mContext);
-
-        final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 1);
-        synchronized (mTetheringStatsProviders) {
-            for (ITetheringStatsProvider provider: mTetheringStatsProviders.keySet()) {
-                try {
-                    stats.combineAllValues(provider.getTetherStats(how));
-                } catch (RemoteException e) {
-                    Log.e(TAG, "Problem reading tethering stats from " +
-                            mTetheringStatsProviders.get(provider) + ": " + e);
-                }
-            }
-        }
-        return stats;
+        // Remove the implementation of getNetworkStatsTethering since all callers are migrated
+        // to use INetd#tetherGetStats directly.
+        throw new UnsupportedOperationException();
     }
 
     @Override
@@ -1464,9 +1411,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);
             }
 
@@ -1538,25 +1486,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);
             }
         }
@@ -1572,10 +1505,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);
             }
         }
@@ -1645,12 +1578,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/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 53c8635..9546496 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -3620,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/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 fce6737..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;
@@ -279,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,
@@ -376,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);
                 }
@@ -409,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/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index e1cbdb7..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;
@@ -131,7 +128,6 @@
 import static com.android.internal.util.XmlUtils.writeLongAttribute;
 import static com.android.internal.util.XmlUtils.writeStringAttribute;
 import static com.android.net.module.util.NetworkStatsUtils.LIMIT_GLOBAL_ALERT;
-import static com.android.server.net.NetworkStatsService.ACTION_NETWORK_STATS_UPDATED;
 
 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
 import static org.xmlpull.v1.XmlPullParser.END_TAG;
@@ -185,7 +181,6 @@
 import android.net.NetworkStateSnapshot;
 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;
@@ -1013,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);
@@ -1221,19 +1217,16 @@
     };
 
     /**
-     * Receiver that watches for {@link NetworkStatsManager} 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}.
      */
-    private final NetworkStatsBroadcastReceiver mStatsReceiver =
-            new NetworkStatsBroadcastReceiver();
-    private class NetworkStatsBroadcastReceiver extends BroadcastReceiver {
-        private boolean mIsAnyIntentReceived = false;
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            // on background handler thread, and verified
-            // READ_NETWORK_USAGE_HISTORY permission above.
+    private final StatsCallback mStatsCallback = new StatsCallback();
+    private class StatsCallback extends NetworkStatsManager.UsageCallback {
+        private boolean mIsAnyCallbackReceived = false;
 
-            mIsAnyIntentReceived = true;
+        @Override
+        public void onThresholdReached(int networkType, String subscriberId) {
+            mIsAnyCallbackReceived = true;
 
             synchronized (mNetworkPoliciesSecondLock) {
                 updateNetworkRulesNL();
@@ -1243,11 +1236,11 @@
         }
 
         /**
-         * Return whether any {@code ACTION_NETWORK_STATS_UPDATED} intent is received.
+         * Return whether any callback is received.
          * Used to determine if NetworkStatsService is ready.
          */
-        public boolean isAnyIntentReceived() {
-            return mIsAnyIntentReceived;
+        public boolean isAnyCallbackReceived() {
+            return mIsAnyCallbackReceived;
         }
     };
 
@@ -1474,7 +1467,7 @@
 
         // 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 (!mStatsReceiver.isAnyIntentReceived()) return null;
+        if (!mStatsCallback.isAnyCallbackReceived()) return null;
 
         final List<NetworkStats.Bucket> stats = mDeps.getNetworkUidBytes(template, start, end);
         for (final NetworkStats.Bucket entry : stats) {
@@ -1518,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;
             }
@@ -1757,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)) {
@@ -1987,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);
@@ -2094,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);
         }
 
@@ -2295,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)) {
@@ -2323,7 +2317,7 @@
         if (dataWarningConfig == WARNING_DISABLED) {
             return WARNING_DISABLED;
         } else {
-            return dataWarningConfig * MB_IN_BYTES;
+            return DataUnit.MEBIBYTES.toBytes(dataWarningConfig);
         }
     }
 
@@ -2707,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");
@@ -3472,7 +3466,7 @@
      * {@link NetworkStatsProvider#onSetWarningAndLimit(String, long, long)}.
      */
     @Override
-    public void onStatsProviderWarningOrLimitReached() {
+    public void notifyStatsProviderWarningOrLimitReached() {
         enforceAnyPermissionOf(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
         // This API may be called before the system is ready.
         synchronized (mNetworkPoliciesSecondLock) {
@@ -3492,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
@@ -3502,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)) {
@@ -3519,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());
 
@@ -3545,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());
 
@@ -3577,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)) {
@@ -3587,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
@@ -3597,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
@@ -3607,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)) {
@@ -3619,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());
             }
@@ -5098,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: {
@@ -5469,7 +5464,7 @@
     private long getTotalBytes(NetworkTemplate template, long start, long end) {
         // 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 (!mStatsReceiver.isAnyIntentReceived()) return 0;
+        if (!mStatsCallback.isAnyCallbackReceived()) return 0;
         return mDeps.getNetworkTotalBytes(template, start, end);
     }
 
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..1fa948c 100644
--- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
+++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
@@ -18,28 +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.getAllCollapsedRatTypes;
+import static android.net.NetworkTemplate.OEM_MANAGED_PAID;
+import static android.net.NetworkTemplate.OEM_MANAGED_PRIVATE;
 import static android.os.Debug.getIonHeapsSizeKb;
 import static android.os.Process.LAST_SHARED_APPLICATION_GID;
 import static android.os.Process.getUidForPid;
@@ -80,6 +69,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 +83,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 +176,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 +224,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 +320,7 @@
     private WifiManager mWifiManager;
     private TelephonyManager mTelephony;
     private SubscriptionManager mSubscriptionManager;
+    private NetworkStatsManager mNetworkStatsManager;
 
     @GuardedBy("mKernelWakelockLock")
     private KernelWakelockReader mKernelWakelockReader;
@@ -776,7 +766,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 +956,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 +1086,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 +1103,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 +1119,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),
@@ -1202,13 +1167,14 @@
                 Slog.e(TAG, "baseline is null for " + atomTag + ", return.");
                 return StatsManager.PULL_SKIP;
             }
+
             final NetworkStatsExt diff = new NetworkStatsExt(
-                    item.stats.subtract(baseline.stats).removeEmptyEntries(), item.transports,
+                    removeEmptyEntries(item.stats.subtract(baseline.stats)), item.transports,
                     item.slicedByFgbg, item.slicedByTag, item.slicedByMetered, item.ratType,
                     item.subInfo, item.oemManaged);
 
             // If no diff, skip.
-            if (diff.stats.size() == 0) continue;
+            if (!diff.stats.iterator().hasNext()) continue;
 
             switch (atomTag) {
                 case FrameworkStatsLog.BYTES_TRANSFER_BY_TAG_AND_METERED:
@@ -1227,25 +1193,32 @@
         return StatsManager.PULL_SUCCESS;
     }
 
+    @NonNull private static NetworkStats removeEmptyEntries(NetworkStats stats) {
+        NetworkStats ret = new NetworkStats(0, 1);
+        for (NetworkStats.Entry e : stats) {
+            if (e.getRxBytes() != 0 || e.getRxPackets() != 0 || e.getTxBytes() != 0
+                    || e.getTxPackets() != 0 || e.getOperations() != 0) {
+                ret = ret.addEntry(e);
+            }
+        }
+        return ret;
+    }
+
     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,33 +1226,31 @@
 
     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()));
         }
     }
 
     private void addDataUsageBytesTransferAtoms(@NonNull NetworkStatsExt statsExt,
             @NonNull List<StatsEvent> pulledData) {
 
-        // Workaround for 5G NSA mode, see {@link NetworkTemplate#NETWORK_TYPE_5G_NSA}.
+        // Workaround for 5G NSA mode, see {@link NetworkStatsManager#NETWORK_TYPE_5G_NSA}.
         // 5G NSA mode means the primary cell is LTE with a secondary connection to an
         // NR cell. To mitigate risk, NetworkStats is currently storing this state as
         // a fake RAT type rather than storing the boolean separately.
-        final boolean is5GNsa = statsExt.ratType == NetworkTemplate.NETWORK_TYPE_5G_NSA;
+        final boolean is5GNsa = statsExt.ratType == NetworkStatsManager.NETWORK_TYPE_5G_NSA;
         // 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 +1264,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 +1306,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 +1333,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 +1366,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 +1382,72 @@
         return ret;
     }
 
+    /**
+     * Return all supported collapsed RAT types that could be returned by
+     * {@link android.app.usage.NetworkStatsManager#getCollapsedRatType(int)}.
+     */
+    @NonNull
+    private static int[] getAllCollapsedRatTypes() {
+        final int[] ratTypes = TelephonyManager.getAllNetworkTypes();
+        final HashSet<Integer> collapsedRatTypes = new HashSet<>();
+        for (final int ratType : ratTypes) {
+            collapsedRatTypes.add(NetworkStatsManager.getCollapsedRatType(ratType));
+        }
+        // Add NETWORK_TYPE_5G_NSA to the returned list since 5G NSA is a virtual RAT type and
+        // it is not in TelephonyManager#NETWORK_TYPE_* constants.
+        // See {@link NetworkStatsManager#NETWORK_TYPE_5G_NSA}.
+        collapsedRatTypes.add(
+                NetworkStatsManager.getCollapsedRatType(NetworkStatsManager.NETWORK_TYPE_5G_NSA));
+        // Ensure that unknown type is returned.
+        collapsedRatTypes.add(TelephonyManager.NETWORK_TYPE_UNKNOWN);
+        return com.android.net.module.util.CollectionUtils.toIntArray(collapsedRatTypes);
+    }
+
+    @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 +1457,27 @@
      *
      * 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);
-            if (slicer != null) {
-                slicer.accept(entry, recycle);
-            }
-
-            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);
+            @NonNull Function<NetworkStats.Entry, NetworkStats.Entry> slicer) {
+        NetworkStats ret = new NetworkStats(0, 1);
+        for (NetworkStats.Entry e : stats) {
+            ret = ret.addEntry(slicer.apply(e));
         }
         return ret;
     }
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/wm/SurfaceAnimator.java b/services/core/java/com/android/server/wm/SurfaceAnimator.java
index c7bf8ec..94f0e24 100644
--- a/services/core/java/com/android/server/wm/SurfaceAnimator.java
+++ b/services/core/java/com/android/server/wm/SurfaceAnimator.java
@@ -85,6 +85,8 @@
 
     private boolean mAnimationStartDelayed;
 
+    private boolean mAnimationFinished;
+
     /**
      * @param animatable The object to animate.
      * @param staticAnimationFinishedCallback Callback to invoke when an animation has finished
@@ -134,6 +136,7 @@
                         || anim.shouldDeferAnimationFinish(resetAndInvokeFinish))) {
                     resetAndInvokeFinish.run();
                 }
+                mAnimationFinished = true;
             }
         };
     }
@@ -289,6 +292,9 @@
             Slog.w(TAG, "Unable to transfer animation, surface or parent is null");
             cancelAnimation();
             return;
+        } else if (from.mAnimationFinished) {
+            Slog.w(TAG, "Unable to transfer animation, because " + from + " animation is finished");
+            return;
         }
         endDelayingAnimationStart();
         final Transaction t = mAnimatable.getPendingTransaction();
@@ -367,6 +373,7 @@
         SurfaceControl leash = mLeash;
         mLeash = null;
         final boolean scheduleAnim = removeLeash(t, mAnimatable, leash, destroyLeash);
+        mAnimationFinished = false;
         if (scheduleAnim) {
             mService.scheduleAnimationLocked();
         }
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 df98390..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;
@@ -3277,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");
     }
@@ -3301,7 +3304,7 @@
 
     @Override
     void handleStopUser(int userId) {
-        updateNetworkPreferenceForUser(userId, false);
+        updateNetworkPreferenceForUser(userId, PreferentialNetworkServiceConfig.DEFAULT);
         stopOwnerService(userId, "stop-user");
     }
 
@@ -11845,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());
@@ -11882,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");
@@ -17537,11 +17581,48 @@
         if (!isManagedProfile(userId)) {
             return;
         }
-        int networkPreference = preferentialNetworkServiceEnabled
-                ? PROFILE_NETWORK_PREFERENCE_ENTERPRISE : PROFILE_NETWORK_PREFERENCE_DEFAULT;
         ProfileNetworkPreference.Builder preferenceBuilder =
                 new ProfileNetworkPreference.Builder();
-        preferenceBuilder.setPreference(networkPreference);
+        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().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(() ->
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 2303495..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;
@@ -1839,6 +1839,7 @@
             try {
                 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/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 a63aa6a..3511fc1 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -39,7 +39,9 @@
 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;
@@ -89,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;
@@ -4109,6 +4112,7 @@
         ProfileNetworkPreference preferenceDetails2 =
                 new ProfileNetworkPreference.Builder()
                         .setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE)
+                        .setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1)
                         .build();
         List<ProfileNetworkPreference> preferences2 = new ArrayList<>();
         preferences2.add(preferenceDetails);
@@ -4118,6 +4122,164 @@
     }
 
     @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
     public void testSetSystemSettingFailWithNonWhitelistedSettings() throws Exception {
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
         setupDeviceOwner();
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 9a6f61e..e80721a 100644
--- a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
@@ -51,6 +51,7 @@
 import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
 import static android.net.NetworkStats.METERED_NO;
 import static android.net.NetworkStats.METERED_YES;
+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;
@@ -71,7 +72,6 @@
 import static com.android.server.net.NetworkPolicyManagerService.TYPE_RAPID;
 import static com.android.server.net.NetworkPolicyManagerService.TYPE_WARNING;
 import static com.android.server.net.NetworkPolicyManagerService.UidBlockedState.getEffectiveBlockedReasons;
-import static com.android.server.net.NetworkStatsService.ACTION_NETWORK_STATS_UPDATED;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -95,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;
 
@@ -495,8 +496,14 @@
         verify(mNetworkManager).registerObserver(networkObserver.capture());
         mNetworkObserver = networkObserver.getValue();
 
-        // Simulate NetworkStatsService broadcast stats updated to signal its readiness.
-        mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_UPDATED));
+        // 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;
@@ -1746,7 +1753,7 @@
     }
 
     private void triggerOnStatsProviderWarningOrLimitReached() throws InterruptedException {
-        mService.onStatsProviderWarningOrLimitReached();
+        mService.notifyStatsProviderWarningOrLimitReached();
         // Wait for processing of MSG_STATS_PROVIDER_WARNING_OR_LIMIT_REACHED.
         postMsgAndWaitForCompletion();
         verify(mStatsManager).forceUpdate();
@@ -2046,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()
@@ -2092,7 +2099,7 @@
     }
 
     private void verifyAdvisePersistThreshold() throws Exception {
-        verify(mStatsManager).advisePersistThreshold(anyLong());
+        verify(mStatsManager).setDefaultGlobalAlert(anyLong());
     }
 
     private static class TestAbstractFuture<T> extends AbstractFuture<T> {
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 77c12bb..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
@@ -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 {}
@@ -5025,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;
         }
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/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/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 */);
     }
 }
