Merge changes from topic "showBackground-api"

* changes:
  Support backgrounds during animations in shell
  Add API to show background behind animating windows
diff --git a/Android.bp b/Android.bp
index e96c731..ab11899 100644
--- a/Android.bp
+++ b/Android.bp
@@ -81,6 +81,7 @@
         // Java/AIDL sources under frameworks/base
         ":framework-annotations",
         ":framework-blobstore-sources",
+        ":framework-bluetooth-sources", // TODO(b/214988855) : Remove once framework-bluetooth jar is ready
         ":framework-connectivity-tiramisu-sources",
         ":framework-core-sources",
         ":framework-drm-sources",
@@ -93,7 +94,7 @@
         ":framework-mca-effect-sources",
         ":framework-mca-filterfw-sources",
         ":framework-mca-filterpacks-sources",
-        ":framework-media-sources",
+        ":framework-media-non-updatable-sources",
         ":framework-mms-sources",
         ":framework-omapi-sources",
         ":framework-opengl-sources",
diff --git a/ApiDocs.bp b/ApiDocs.bp
index 321952d..4aecc8f 100644
--- a/ApiDocs.bp
+++ b/ApiDocs.bp
@@ -60,9 +60,9 @@
     defaults: ["android-non-updatable-stubs-defaults"],
     srcs: [
         // No longer part of the stubs, but are included in the docs.
-        "test-base/src/**/*.java",
-        "test-mock/src/**/*.java",
-        "test-runner/src/**/*.java",
+        ":android-test-base-sources",
+        ":android-test-mock-sources",
+        ":android-test-runner-sources",
     ],
     libs: framework_docs_only_libs,
     create_doc_stubs: true,
diff --git a/cmds/sm/src/com/android/commands/sm/Sm.java b/cmds/sm/src/com/android/commands/sm/Sm.java
index 260c8a4..b384e70 100644
--- a/cmds/sm/src/com/android/commands/sm/Sm.java
+++ b/cmds/sm/src/com/android/commands/sm/Sm.java
@@ -259,7 +259,8 @@
     public void runDisableAppDataIsolation() throws RemoteException {
         if (!SystemProperties.getBoolean(
                 ANDROID_VOLD_APP_DATA_ISOLATION_ENABLED_PROPERTY, false)) {
-            throw new IllegalStateException("Storage app data isolation is not enabled.");
+            System.err.println("Storage app data isolation is not enabled.");
+            return;
         }
         final String pkgName = nextArg();
         final int pid = Integer.parseInt(nextArg());
diff --git a/core/api/current.txt b/core/api/current.txt
index 967199e..4d27dde 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -7287,6 +7287,10 @@
     method @Nullable public java.util.List<java.lang.String> getDelegatePackages(@NonNull android.content.ComponentName, @NonNull String);
     method @NonNull public java.util.List<java.lang.String> getDelegatedScopes(@Nullable android.content.ComponentName, @NonNull String);
     method public CharSequence getDeviceOwnerLockScreenInfo();
+    method @Nullable public android.graphics.drawable.Drawable getDrawable(int, int, @NonNull java.util.concurrent.Callable<android.graphics.drawable.Drawable>);
+    method @Nullable public android.graphics.drawable.Drawable getDrawable(int, int, int, @NonNull java.util.concurrent.Callable<android.graphics.drawable.Drawable>);
+    method @Nullable public android.graphics.drawable.Drawable getDrawableForDensity(int, int, int, @NonNull java.util.concurrent.Callable<android.graphics.drawable.Drawable>);
+    method @Nullable public android.graphics.drawable.Drawable getDrawableForDensity(int, int, int, int, @NonNull java.util.concurrent.Callable<android.graphics.drawable.Drawable>);
     method public CharSequence getEndUserSessionMessage(@NonNull android.content.ComponentName);
     method @NonNull public String getEnrollmentSpecificId();
     method @Nullable public android.app.admin.FactoryResetProtectionPolicy getFactoryResetProtectionPolicy(@Nullable android.content.ComponentName);
@@ -7510,6 +7514,7 @@
     field public static final String ACTION_CHECK_POLICY_COMPLIANCE = "android.app.action.CHECK_POLICY_COMPLIANCE";
     field public static final String ACTION_DEVICE_ADMIN_SERVICE = "android.app.action.DEVICE_ADMIN_SERVICE";
     field public static final String ACTION_DEVICE_OWNER_CHANGED = "android.app.action.DEVICE_OWNER_CHANGED";
+    field public static final String ACTION_DEVICE_POLICY_RESOURCE_UPDATED = "android.app.action.DEVICE_POLICY_RESOURCE_UPDATED";
     field public static final String ACTION_GET_PROVISIONING_MODE = "android.app.action.GET_PROVISIONING_MODE";
     field public static final String ACTION_MANAGED_PROFILE_PROVISIONED = "android.app.action.MANAGED_PROFILE_PROVISIONED";
     field public static final String ACTION_PROFILE_OWNER_CHANGED = "android.app.action.PROFILE_OWNER_CHANGED";
@@ -7585,6 +7590,8 @@
     field public static final String EXTRA_PROVISIONING_WIFI_SECURITY_TYPE = "android.app.extra.PROVISIONING_WIFI_SECURITY_TYPE";
     field public static final String EXTRA_PROVISIONING_WIFI_SSID = "android.app.extra.PROVISIONING_WIFI_SSID";
     field public static final String EXTRA_PROVISIONING_WIFI_USER_CERTIFICATE = "android.app.extra.PROVISIONING_WIFI_USER_CERTIFICATE";
+    field public static final String EXTRA_RESOURCE_ID = "android.app.extra.RESOURCE_ID";
+    field public static final String EXTRA_RESOURCE_TYPE_DRAWABLE = "android.app.extra.RESOURCE_TYPE_DRAWABLE";
     field public static final int FLAG_EVICT_CREDENTIAL_ENCRYPTION_KEY = 1; // 0x1
     field public static final int FLAG_MANAGED_CAN_ACCESS_PARENT = 2; // 0x2
     field public static final int FLAG_PARENT_CAN_ACCESS_MANAGED = 1; // 0x1
@@ -7679,6 +7686,35 @@
     method public void onApplicationUserDataCleared(String, boolean);
   }
 
+  public final class DevicePolicyResources {
+    ctor public DevicePolicyResources();
+  }
+
+  public static final class DevicePolicyResources.Drawable {
+    field public static final int INVALID_ID = -1; // 0xffffffff
+    field public static final int WORK_PROFILE_ICON = 1; // 0x1
+    field public static final int WORK_PROFILE_ICON_BADGE = 0; // 0x0
+    field public static final int WORK_PROFILE_OFF_ICON = 2; // 0x2
+    field public static final int WORK_PROFILE_USER_ICON = 3; // 0x3
+  }
+
+  public static final class DevicePolicyResources.Drawable.Source {
+    field public static final int HOME_WIDGET = 2; // 0x2
+    field public static final int LAUNCHER_OFF_BUTTON = 3; // 0x3
+    field public static final int NOTIFICATION = 0; // 0x0
+    field public static final int PROFILE_SWITCH_ANIMATION = 1; // 0x1
+    field public static final int QUICK_SETTINGS = 4; // 0x4
+    field public static final int STATUS_BAR = 5; // 0x5
+    field public static final int UNDEFINED = -1; // 0xffffffff
+  }
+
+  public static final class DevicePolicyResources.Drawable.Style {
+    field public static final int DEFAULT = -1; // 0xffffffff
+    field public static final int OUTLINE = 2; // 0x2
+    field public static final int SOLID_COLORED = 0; // 0x0
+    field public static final int SOLID_NOT_COLORED = 1; // 0x1
+  }
+
   public final class DnsEvent extends android.app.admin.NetworkEvent implements android.os.Parcelable {
     method public String getHostname();
     method public java.util.List<java.net.InetAddress> getInetAddresses();
@@ -15243,6 +15279,11 @@
 
   public class BitmapShader extends android.graphics.Shader {
     ctor public BitmapShader(@NonNull android.graphics.Bitmap, @NonNull android.graphics.Shader.TileMode, @NonNull android.graphics.Shader.TileMode);
+    method public int getFilterMode();
+    method public void setFilterMode(int);
+    field public static final int FILTER_MODE_DEFAULT = 0; // 0x0
+    field public static final int FILTER_MODE_LINEAR = 2; // 0x2
+    field public static final int FILTER_MODE_NEAREST = 1; // 0x1
   }
 
   public enum BlendMode {
@@ -16649,6 +16690,7 @@
     method public void setFloatUniform(@NonNull String, float, float, float);
     method public void setFloatUniform(@NonNull String, float, float, float, float);
     method public void setFloatUniform(@NonNull String, @NonNull float[]);
+    method public void setInputBuffer(@NonNull String, @NonNull android.graphics.BitmapShader);
     method public void setInputShader(@NonNull String, @NonNull android.graphics.Shader);
     method public void setIntUniform(@NonNull String, int);
     method public void setIntUniform(@NonNull String, int, int);
@@ -48188,6 +48230,18 @@
     method @NonNull public android.graphics.Insets getWaterfallInsets();
   }
 
+  public static final class DisplayCutout.Builder {
+    ctor public DisplayCutout.Builder();
+    method @NonNull public android.view.DisplayCutout build();
+    method @NonNull public android.view.DisplayCutout.Builder setBoundingRectBottom(@NonNull android.graphics.Rect);
+    method @NonNull public android.view.DisplayCutout.Builder setBoundingRectLeft(@NonNull android.graphics.Rect);
+    method @NonNull public android.view.DisplayCutout.Builder setBoundingRectRight(@NonNull android.graphics.Rect);
+    method @NonNull public android.view.DisplayCutout.Builder setBoundingRectTop(@NonNull android.graphics.Rect);
+    method @NonNull public android.view.DisplayCutout.Builder setCutoutPath(@NonNull android.graphics.Path);
+    method @NonNull public android.view.DisplayCutout.Builder setSafeInsets(@NonNull android.graphics.Insets);
+    method @NonNull public android.view.DisplayCutout.Builder setWaterfallInsets(@NonNull android.graphics.Insets);
+  }
+
   public final class DragAndDropPermissions implements android.os.Parcelable {
     method public int describeContents();
     method public void release();
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index d674507..800c8ab0 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -993,6 +993,18 @@
 
 package android.app.admin {
 
+  public final class DevicePolicyDrawableResource implements android.os.Parcelable {
+    ctor public DevicePolicyDrawableResource(@NonNull android.content.Context, int, int, int, @DrawableRes int);
+    ctor public DevicePolicyDrawableResource(@NonNull android.content.Context, int, int, @DrawableRes int);
+    method public int describeContents();
+    method @DrawableRes public int getCallingPackageResourceId();
+    method public int getDrawableId();
+    method public int getDrawableSource();
+    method public int getDrawableStyle();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.app.admin.DevicePolicyDrawableResource> CREATOR;
+  }
+
   public class DevicePolicyKeyguardService extends android.app.Service {
     ctor public DevicePolicyKeyguardService();
     method @Nullable public void dismiss();
@@ -1025,8 +1037,10 @@
     method @RequiresPermission("android.permission.NOTIFY_PENDING_SYSTEM_UPDATE") public void notifyPendingSystemUpdate(long, boolean);
     method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) public boolean packageHasActiveAdmins(String);
     method @RequiresPermission(android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS) public void provisionFullyManagedDevice(@NonNull android.app.admin.FullyManagedDeviceProvisioningParams) throws android.app.admin.ProvisioningException;
+    method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_MANAGEMENT_RESOURCES) public void resetDrawables(@NonNull int[]);
     method @Deprecated @RequiresPermission(android.Manifest.permission.MANAGE_DEVICE_ADMINS) public boolean setActiveProfileOwner(@NonNull android.content.ComponentName, String) throws java.lang.IllegalArgumentException;
     method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public void setDeviceProvisioningConfigApplied();
+    method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_MANAGEMENT_RESOURCES) public void setDrawables(@NonNull java.util.Set<android.app.admin.DevicePolicyDrawableResource>);
     method @Deprecated @RequiresPermission(value=android.Manifest.permission.GRANT_PROFILE_OWNER_DEVICE_IDS_ACCESS, conditional=true) public void setProfileOwnerCanAccessDeviceIds(@NonNull android.content.ComponentName);
     method public void setSecondaryLockscreenEnabled(@NonNull android.content.ComponentName, boolean);
     method @RequiresPermission(android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS) public void setUserProvisioningState(int, @NonNull android.os.UserHandle);
@@ -1058,6 +1072,7 @@
     field public static final int CODE_USER_HAS_PROFILE_OWNER = 2; // 0x2
     field public static final int CODE_USER_NOT_RUNNING = 3; // 0x3
     field public static final int CODE_USER_SETUP_COMPLETED = 4; // 0x4
+    field public static final String EXTRA_FORCE_UPDATE_ROLE_HOLDER = "android.app.extra.FORCE_UPDATE_ROLE_HOLDER";
     field public static final String EXTRA_PROFILE_OWNER_NAME = "android.app.extra.PROFILE_OWNER_NAME";
     field @Deprecated public static final String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_ICON_URI = "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_ICON_URI";
     field @Deprecated public static final String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_LABEL = "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_LABEL";
@@ -1069,6 +1084,7 @@
     field public static final String EXTRA_PROVISIONING_SUPPORT_URL = "android.app.extra.PROVISIONING_SUPPORT_URL";
     field public static final String EXTRA_PROVISIONING_TRIGGER = "android.app.extra.PROVISIONING_TRIGGER";
     field public static final String EXTRA_RESTRICTION = "android.app.extra.RESTRICTION";
+    field public static final String EXTRA_ROLE_HOLDER_STATE = "android.app.extra.ROLE_HOLDER_STATE";
     field public static final int FLAG_SUPPORTED_MODES_DEVICE_OWNER = 4; // 0x4
     field public static final int FLAG_SUPPORTED_MODES_ORGANIZATION_OWNED = 1; // 0x1
     field public static final int FLAG_SUPPORTED_MODES_PERSONALLY_OWNED = 2; // 0x2
@@ -1084,6 +1100,7 @@
     field public static final int RESULT_DEVICE_OWNER_SET = 123; // 0x7b
     field public static final int RESULT_UPDATE_DEVICE_MANAGEMENT_ROLE_HOLDER_RECOVERABLE_ERROR = 1; // 0x1
     field public static final int RESULT_UPDATE_DEVICE_MANAGEMENT_ROLE_HOLDER_UNRECOVERABLE_ERROR = 2; // 0x2
+    field public static final int RESULT_UPDATE_ROLE_HOLDER = 2; // 0x2
     field public static final int RESULT_WORK_PROFILE_CREATED = 122; // 0x7a
     field public static final int STATE_USER_PROFILE_COMPLETE = 4; // 0x4
     field public static final int STATE_USER_PROFILE_FINALIZED = 5; // 0x5
@@ -8215,6 +8232,7 @@
   public class TrafficStats {
     method public static void setThreadStatsTagApp();
     method public static void setThreadStatsTagBackup();
+    method public static void setThreadStatsTagDownload();
     method public static void setThreadStatsTagRestore();
     field public static final int TAG_NETWORK_STACK_IMPERSONATION_RANGE_END = -113; // 0xffffff8f
     field public static final int TAG_NETWORK_STACK_IMPERSONATION_RANGE_START = -128; // 0xffffff80
@@ -14051,14 +14069,21 @@
 
   public class ImsService extends android.app.Service {
     ctor public ImsService();
-    method public android.telephony.ims.feature.MmTelFeature createMmTelFeature(int);
-    method public android.telephony.ims.feature.RcsFeature createRcsFeature(int);
-    method public void disableIms(int);
-    method public void enableIms(int);
-    method public android.telephony.ims.stub.ImsConfigImplBase getConfig(int);
+    method @Nullable public android.telephony.ims.feature.MmTelFeature createEmergencyOnlyMmTelFeature(int);
+    method @Deprecated public android.telephony.ims.feature.MmTelFeature createMmTelFeature(int);
+    method @Nullable public android.telephony.ims.feature.MmTelFeature createMmTelFeatureForSubscription(int, int);
+    method @Deprecated public android.telephony.ims.feature.RcsFeature createRcsFeature(int);
+    method @Nullable public android.telephony.ims.feature.RcsFeature createRcsFeatureForSubscription(int, int);
+    method @Deprecated public void disableIms(int);
+    method public void disableImsForSubscription(int, int);
+    method @Deprecated public void enableIms(int);
+    method public void enableImsForSubscription(int, int);
+    method @Deprecated public android.telephony.ims.stub.ImsConfigImplBase getConfig(int);
+    method @NonNull public android.telephony.ims.stub.ImsConfigImplBase getConfigForSubscription(int, int);
     method @NonNull public java.util.concurrent.Executor getExecutor();
     method public long getImsServiceCapabilities();
-    method public android.telephony.ims.stub.ImsRegistrationImplBase getRegistration(int);
+    method @Deprecated public android.telephony.ims.stub.ImsRegistrationImplBase getRegistration(int);
+    method @NonNull public android.telephony.ims.stub.ImsRegistrationImplBase getRegistrationForSubscription(int, int);
     method @Nullable public android.telephony.ims.stub.SipTransportImplBase getSipTransport(int);
     method public final void onUpdateSupportedImsFeatures(android.telephony.ims.stub.ImsFeatureConfiguration) throws android.os.RemoteException;
     method public android.telephony.ims.stub.ImsFeatureConfiguration querySupportedImsFeatures();
diff --git a/core/java/android/app/admin/DevicePolicyDrawableResource.aidl b/core/java/android/app/admin/DevicePolicyDrawableResource.aidl
new file mode 100644
index 0000000..6b73d981
--- /dev/null
+++ b/core/java/android/app/admin/DevicePolicyDrawableResource.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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;
+
+parcelable DevicePolicyDrawableResource;
diff --git a/core/java/android/app/admin/DevicePolicyDrawableResource.java b/core/java/android/app/admin/DevicePolicyDrawableResource.java
new file mode 100644
index 0000000..d32ff84
--- /dev/null
+++ b/core/java/android/app/admin/DevicePolicyDrawableResource.java
@@ -0,0 +1,203 @@
+/*
+ * 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.DrawableRes;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.content.Context;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Objects;
+
+/**
+ * Used to pass in the required information for updating an enterprise drawable resource using
+ * {@link DevicePolicyManager#setDrawables}.
+ *
+ * @hide
+ */
+@SystemApi
+public final class DevicePolicyDrawableResource implements Parcelable {
+    private final @DevicePolicyResources.UpdatableDrawableId int mDrawableId;
+    private final @DevicePolicyResources.UpdatableDrawableStyle int mDrawableStyle;
+    private final @DevicePolicyResources.UpdatableDrawableSource int mDrawableSource;
+    private final @DrawableRes int mCallingPackageResourceId;
+    @NonNull private ParcelableResource mResource;
+
+    /**
+     * Creates an object containing the required information for updating an enterprise drawable
+     * resource using {@link DevicePolicyManager#setDrawables}.
+     *
+     * <p>It will be used to update the drawable defined by {@code drawableId} with style
+     * {@code drawableStyle} located in source {@code drawableSource} to the drawable with ID
+     * {@code callingPackageResourceId} in the calling package</p>
+     *
+     * @param drawableId The ID of the drawable to update.
+     * @param drawableStyle The style of the drawable to update.
+     * @param drawableSource The source of the drawable to update.
+     * @param callingPackageResourceId The ID of the drawable resource in the calling package to
+     *        use as an updated resource.
+     *
+     * @throws IllegalStateException if the resource with ID
+     * {@code callingPackageResourceId} doesn't exist in the {@code context} package.
+     */
+    public DevicePolicyDrawableResource(
+            @NonNull Context context,
+            @DevicePolicyResources.UpdatableDrawableId int drawableId,
+            @DevicePolicyResources.UpdatableDrawableStyle int drawableStyle,
+            @DevicePolicyResources.UpdatableDrawableSource int drawableSource,
+            @DrawableRes int callingPackageResourceId) {
+        this(drawableId, drawableStyle, drawableSource, callingPackageResourceId,
+                new ParcelableResource(context, callingPackageResourceId,
+                        ParcelableResource.RESOURCE_TYPE_DRAWABLE));
+    }
+
+    private DevicePolicyDrawableResource(
+            @DevicePolicyResources.UpdatableDrawableId int drawableId,
+            @DevicePolicyResources.UpdatableDrawableStyle int drawableStyle,
+            @DevicePolicyResources.UpdatableDrawableSource int drawableSource,
+            @DrawableRes int callingPackageResourceId,
+            @NonNull ParcelableResource resource) {
+        this.mDrawableId = drawableId;
+        this.mDrawableStyle = drawableStyle;
+        this.mDrawableSource = drawableSource;
+        this.mCallingPackageResourceId = callingPackageResourceId;
+        this.mResource = resource;
+    }
+
+    /**
+     * Creates an object containing the required information for updating an enterprise drawable
+     * resource using {@link DevicePolicyManager#setDrawables}.
+     * <p>It will be used to update the drawable defined by {@code drawableId} with style
+     * {@code drawableStyle} to the drawable with ID {@code callingPackageResourceId} in the
+     * calling package</p>
+     *
+     * @param drawableId The ID of the drawable to update.
+     * @param drawableStyle The style of the drawable to update.
+     * @param callingPackageResourceId The ID of the drawable resource in the calling package to
+     *        use as an updated resource.
+     *
+     * @throws IllegalStateException if the resource with ID
+     * {@code callingPackageResourceId} doesn't exist in the calling package.
+     */
+    public DevicePolicyDrawableResource(
+            @NonNull Context context,
+            @DevicePolicyResources.UpdatableDrawableId int drawableId,
+            @DevicePolicyResources.UpdatableDrawableStyle int drawableStyle,
+            @DrawableRes int callingPackageResourceId) {
+       this(context, drawableId, drawableStyle, DevicePolicyResources.Drawable.Source.UNDEFINED,
+               callingPackageResourceId);
+    }
+
+    /**
+     * Returns the ID of the drawable to update.
+     */
+    @DevicePolicyResources.UpdatableDrawableId
+    public int getDrawableId() {
+        return mDrawableId;
+    }
+
+    /**
+     * Returns the style of the drawable to update
+     */
+    @DevicePolicyResources.UpdatableDrawableStyle
+    public int getDrawableStyle() {
+        return mDrawableStyle;
+    }
+
+    /**
+     * Returns the source of the drawable to update.
+     */
+    @DevicePolicyResources.UpdatableDrawableSource
+    public int getDrawableSource() {
+        return mDrawableSource;
+    }
+
+    /**
+     * Returns the ID of the drawable resource in the calling package to use as an updated
+     * resource.
+     */
+    @DrawableRes
+    public int getCallingPackageResourceId() {
+        return mCallingPackageResourceId;
+    }
+
+    /**
+     * Returns the {@link ParcelableResource} of the drawable.
+     *
+     * @hide
+     */
+    @NonNull
+    public ParcelableResource getResource() {
+        return mResource;
+    }
+
+    @Override
+    public boolean equals(@Nullable Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        DevicePolicyDrawableResource other = (DevicePolicyDrawableResource) o;
+        return mDrawableId == other.mDrawableId
+                && mDrawableStyle == other.mDrawableStyle
+                && mDrawableSource == other.mDrawableSource
+                && mCallingPackageResourceId == other.mCallingPackageResourceId
+                && mResource.equals(other.mResource);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(
+                mDrawableId, mDrawableStyle, mDrawableSource, mCallingPackageResourceId, mResource);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeInt(mDrawableId);
+        dest.writeInt(mDrawableStyle);
+        dest.writeInt(mDrawableSource);
+        dest.writeInt(mCallingPackageResourceId);
+        dest.writeTypedObject(mResource, flags);
+    }
+
+    public static final @NonNull Creator<DevicePolicyDrawableResource> CREATOR =
+            new Creator<DevicePolicyDrawableResource>() {
+                @Override
+                public DevicePolicyDrawableResource createFromParcel(Parcel in) {
+                    int drawableId = in.readInt();
+                    int drawableStyle = in.readInt();
+                    int drawableSource = in.readInt();
+                    int callingPackageResourceId = in.readInt();
+                    ParcelableResource resource = in.readTypedObject(ParcelableResource.CREATOR);
+
+                    return new DevicePolicyDrawableResource(
+                            drawableId, drawableStyle, drawableSource, callingPackageResourceId,
+                            resource);
+                }
+
+                @Override
+                public DevicePolicyDrawableResource[] newArray(int size) {
+                    return new DevicePolicyDrawableResource[size];
+                }
+            };
+}
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index a60de08..2bfb938e 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -16,6 +16,9 @@
 
 package android.app.admin;
 
+import static android.app.admin.DevicePolicyResources.Drawable.INVALID_ID;
+import static android.app.admin.DevicePolicyResources.Drawable.Source.UNDEFINED;
+
 import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
 
 import android.Manifest.permission;
@@ -52,7 +55,9 @@
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.ParceledListSlice;
 import android.content.pm.UserInfo;
+import android.content.res.Resources;
 import android.graphics.Bitmap;
+import android.graphics.drawable.Drawable;
 import android.net.PrivateDnsConnectivityChecker;
 import android.net.ProxyInfo;
 import android.net.Uri;
@@ -89,6 +94,7 @@
 import android.text.TextUtils;
 import android.util.ArraySet;
 import android.util.DebugUtils;
+import android.util.DisplayMetrics;
 import android.util.Log;
 import android.util.Pair;
 
@@ -123,6 +129,7 @@
 import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
+import java.util.concurrent.Callable;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Executor;
@@ -480,6 +487,10 @@
      *
      * <p>Device management role holders are required to have a handler for this intent action.
      *
+     * <p>If {@link #EXTRA_ROLE_HOLDER_STATE} is supplied to this intent, it is the responsibility
+     * of the role holder to restore its state from this extra. This is the same {@link Bundle}
+     * which the role holder returns alongside {@link #RESULT_UPDATE_ROLE_HOLDER}.
+     *
      * <p>A result code of {@link Activity#RESULT_OK} implies that managed profile provisioning
      * finished successfully. If it did not, a result code of {@link Activity#RESULT_CANCELED}
      * is used instead.
@@ -527,6 +538,10 @@
      *
      * <p>Device management role holders are required to have a handler for this intent action.
      *
+     * <p>If {@link #EXTRA_ROLE_HOLDER_STATE} is supplied to this intent, it is the responsibility
+     * of the role holder to restore its state from this extra. This is the same {@link Bundle}
+     * which the role holder returns alongside {@link #RESULT_UPDATE_ROLE_HOLDER}.
+     *
      * <p>The result codes can be either {@link #RESULT_WORK_PROFILE_CREATED}, {@link
      * #RESULT_DEVICE_OWNER_SET} or {@link Activity#RESULT_CANCELED} if provisioning failed.
      *
@@ -566,6 +581,47 @@
             "android.app.action.ROLE_HOLDER_PROVISION_FINALIZATION";
 
     /**
+     * {@link Activity} result code which can be returned by {@link
+     * #ACTION_ROLE_HOLDER_PROVISION_MANAGED_PROFILE} and {@link
+     * #ACTION_ROLE_HOLDER_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE} to signal that an update
+     * to the role holder is required.
+     *
+     * <p>This result code must be accompanied by {@link #EXTRA_ROLE_HOLDER_STATE}.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final int RESULT_UPDATE_ROLE_HOLDER = 2;
+
+    /**
+     * A {@link Bundle} extra which describes the state of the role holder at the time when it
+     * returns {@link #RESULT_UPDATE_ROLE_HOLDER}.
+     *
+     * <p>After the update completes, the role holder's {@link
+     * #ACTION_ROLE_HOLDER_PROVISION_MANAGED_PROFILE} or {@link
+     * #ACTION_ROLE_HOLDER_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE} intent will be relaunched,
+     * which will contain this extra. It is the role holder's responsibility to restore its
+     * state from this extra.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String EXTRA_ROLE_HOLDER_STATE = "android.app.extra.ROLE_HOLDER_STATE";
+
+    /**
+     * A {@code boolean} extra which determines whether to force a role holder update, regardless
+     * of any internal conditions {@link #ACTION_UPDATE_DEVICE_MANAGEMENT_ROLE_HOLDER} might have.
+     *
+     * <p>This extra can be provided to intents with action {@link
+     * #ACTION_UPDATE_DEVICE_MANAGEMENT_ROLE_HOLDER}.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String EXTRA_FORCE_UPDATE_ROLE_HOLDER =
+            "android.app.extra.FORCE_UPDATE_ROLE_HOLDER";
+
+    /**
      * Action: Bugreport sharing with device owner has been accepted by the user.
      *
      * @hide
@@ -2854,6 +2910,9 @@
      * #RESULT_UPDATE_DEVICE_MANAGEMENT_ROLE_HOLDER_UNRECOVERABLE_ERROR} if it encounters a problem
      * that will not be solved by relaunching it again.
      *
+     * <p>If this activity has additional internal conditions which are not met, it should return
+     * {@link #RESULT_UPDATE_DEVICE_MANAGEMENT_ROLE_HOLDER_UNRECOVERABLE_ERROR}.
+     *
      * @hide
      */
     @RequiresPermission(android.Manifest.permission.LAUNCH_DEVICE_MANAGER_SETUP)
@@ -3181,6 +3240,36 @@
      */
     public static final int OPERATION_SAFETY_REASON_DRIVING_DISTRACTION = 1;
 
+    /**
+     * Broadcast action: notify system apps (e.g. settings, SysUI, etc) that the device management
+     * resources with IDs {@link #EXTRA_RESOURCE_ID} has been updated using, the updated resources
+     * can be retrieved using {@link #getDrawable}.
+     *
+     * <p>This broadcast is sent to registered receivers only.
+     *
+     * <p> The following extras will be included to identify the type of resource being updated:
+     * <ul>
+     *     <li>{@link #EXTRA_RESOURCE_TYPE_DRAWABLE} for drawable resources</li>
+     * </ul>
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_DEVICE_POLICY_RESOURCE_UPDATED =
+            "android.app.action.DEVICE_POLICY_RESOURCE_UPDATED";
+
+    /**
+     * A boolean extra for {@link #ACTION_DEVICE_POLICY_RESOURCE_UPDATED} to indicate that a
+     * resource of type {@link Drawable} is being updated.
+     */
+    public static final String EXTRA_RESOURCE_TYPE_DRAWABLE =
+            "android.app.extra.RESOURCE_TYPE_DRAWABLE";
+
+    /**
+     * An integer array extra for {@link #ACTION_DEVICE_POLICY_RESOURCE_UPDATED} to indicate which
+     * drawable IDs (see {@link DevicePolicyResources.UpdatableDrawableId}) have been updated.
+     */
+    public static final String EXTRA_RESOURCE_ID =
+            "android.app.extra.RESOURCE_ID";
+
     /** @hide */
     @NonNull
     @TestApi
@@ -14372,4 +14461,243 @@
     public Intent createProvisioningIntentFromNfcIntent(@NonNull Intent nfcIntent) {
         return ProvisioningIntentHelper.createProvisioningIntentFromNfcIntent(nfcIntent);
     }
+
+    /**
+     * For each {@link DevicePolicyDrawableResource} item in {@code drawables}, if
+     * {@link DevicePolicyDrawableResource#getDrawableSource()} is not set or is set to
+     * {@link DevicePolicyResources.Drawable.Source#UNDEFINED}, it updates the drawable resource for
+     * the combination of {@link DevicePolicyDrawableResource#getDrawableId()} and
+     * {@link DevicePolicyDrawableResource#getDrawableStyle()}, (see
+     * {@link DevicePolicyResources.Drawable} and {@link DevicePolicyResources.Drawable.Style}) to
+     * the drawable with ID {@link DevicePolicyDrawableResource#getCallingPackageResourceId()},
+     * meaning any system UI surface calling {@link #getDrawable}
+     * with {@code drawableId} and {@code drawableStyle} will get the new resource after this API
+     * is called.
+     *
+     * <p>Otherwise, if {@link DevicePolicyDrawableResource#getDrawableSource()} is set (see
+     * {@link DevicePolicyResources.Drawable.Source}, it overrides any drawables that was set for
+     * the same {@code drawableId} and {@code drawableStyle} for the provided source.
+     *
+     * <p>Sends a broadcast with action {@link #ACTION_DEVICE_POLICY_RESOURCE_UPDATED} to
+     * registered receivers when a resource has been updated successfully.
+     *
+     * <p>Important notes to consider when using this API:
+     * <ul>
+     * <li>{@link #getDrawable} references the resource
+     * {@link DevicePolicyDrawableResource#getCallingPackageResourceId()} in the
+     * calling package each time it gets called. You have to ensure that the resource is always
+     * available in the calling package as long as it is used as an updated resource.
+     * <li>You still have to re-call {@code setDrawables} even if you only make changes to the
+     * content of the resource with ID
+     * {@link DevicePolicyDrawableResource#getCallingPackageResourceId()} as the content might be
+     * cached and would need updating.
+     * </ul>
+     *
+     * @param drawables The list of {@link DevicePolicyDrawableResource} to update.
+     *
+     * @throws IllegalArgumentException if {@link DevicePolicyDrawableResource#getDrawableId()},
+     * {@link DevicePolicyDrawableResource#getDrawableStyle()}, or
+     * {@link DevicePolicyDrawableResource#getDrawableSource()} aren't defined in
+     * {@link DevicePolicyResources.Drawable}.
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_MANAGEMENT_RESOURCES)
+    public void setDrawables(@NonNull Set<DevicePolicyDrawableResource> drawables) {
+        if (mService != null) {
+            try {
+                mService.setDrawables(new ArrayList<>(drawables));
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+    }
+
+    /**
+     * Removes all updated drawables for the list of {@code drawableIds} (see
+     * {@link DevicePolicyResources.Drawable} that was previously set by calling
+     * {@link #setDrawables}, meaning any subsequent calls to {@link #getDrawable} for the provided
+     * IDs with any {@link DevicePolicyResources.Drawable.Style} and any
+     * {@link DevicePolicyResources.Drawable.Source} will return the default drawable from
+     * {@code defaultDrawableLoader}.
+     *
+     * <p>Sends a broadcast with action {@link #ACTION_DEVICE_POLICY_RESOURCE_UPDATED} to
+     * registered receivers when a resource has been reset successfully.
+     *
+     * @param drawableIds The list of IDs  to remove.
+     *
+     * @throws IllegalArgumentException if IDs are not defined in
+     * {@link DevicePolicyResources.Drawable}
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_MANAGEMENT_RESOURCES)
+    public void resetDrawables(@NonNull int[] drawableIds) {
+        if (mService != null) {
+            try {
+                mService.resetDrawables(drawableIds);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+    }
+
+    /**
+     * Returns the appropriate updated drawable for the {@code drawableId}
+     * (see {@link DevicePolicyResources.Drawable}), with style {@code drawableStyle}
+     * (see {@link DevicePolicyResources.Drawable.Style}) if one was set using
+     * {@code setDrawables}, otherwise returns the drawable from {@code defaultDrawableLoader}.
+     *
+     * <p>Also returns the drawable from {@code defaultDrawableLoader} if
+     * {@link DevicePolicyResources.Drawable#INVALID_ID} was passed.
+     *
+     * <p>This API uses the screen density returned from {@link Resources#getConfiguration()}, to
+     * set a different value use
+     * {@link #getDrawableForDensity(int, int, int, Callable)}.
+     *
+     * <p>Callers should register for {@link #ACTION_DEVICE_POLICY_RESOURCE_UPDATED} to get
+     * notified when a resource has been updated.
+     *
+     * <p>Note that each call to this API loads the resource from the package that called
+     * {@code setDrawables} to set the updated resource.
+     *
+     * @param drawableId The drawable ID to get the updated resource for.
+     * @param drawableStyle The drawable style to use.
+     * @param defaultDrawableLoader To get the default drawable if no updated drawable was set for
+     *                              the provided params.
+     */
+    @Nullable
+    public Drawable getDrawable(
+            @DevicePolicyResources.UpdatableDrawableId int drawableId,
+            @DevicePolicyResources.UpdatableDrawableStyle int drawableStyle,
+            @NonNull Callable<Drawable> defaultDrawableLoader) {
+        return getDrawable(drawableId, drawableStyle, UNDEFINED, defaultDrawableLoader);
+    }
+
+    /**
+     * Similar to {@link #getDrawable(int, int, Callable)}, but also accepts
+     * a {@code drawableSource} (see {@link DevicePolicyResources.Drawable.Source}) which
+     * could result in returning a different drawable than {@link #getDrawable(int, int, Callable)}
+     * if an override was set for that specific source.
+     *
+     * <p>Callers should register for {@link #ACTION_DEVICE_POLICY_RESOURCE_UPDATED} to get
+     * notified when a resource has been updated.
+     *
+     * @param drawableId The drawable ID to get the updated resource for.
+     * @param drawableStyle The drawable style to use.
+     * @param drawableSource The source for the caller.
+     * @param defaultDrawableLoader To get the default drawable if no updated drawable was set for
+     *                              the provided params.
+     */
+    @Nullable
+    public Drawable getDrawable(
+            @DevicePolicyResources.UpdatableDrawableId int drawableId,
+            @DevicePolicyResources.UpdatableDrawableStyle int drawableStyle,
+            @DevicePolicyResources.UpdatableDrawableSource int drawableSource,
+            @NonNull Callable<Drawable> defaultDrawableLoader) {
+        Objects.requireNonNull(defaultDrawableLoader, "defaultDrawableLoader can't be null");
+        if (drawableId == INVALID_ID) {
+            return ParcelableResource.loadDefaultDrawable(defaultDrawableLoader);
+        }
+        if (mService != null) {
+            try {
+                ParcelableResource resource = mService.getDrawable(
+                        drawableId, drawableStyle, drawableSource);
+                if (resource == null) {
+                    return ParcelableResource.loadDefaultDrawable(
+                            defaultDrawableLoader);
+                }
+                return resource.getDrawable(
+                        mContext,
+                        /* density= */ 0,
+                        defaultDrawableLoader);
+
+            } catch (RemoteException e) {
+                Log.e(
+                        TAG,
+                        "Error getting the updated drawable from DevicePolicyManagerService.",
+                        e);
+                return ParcelableResource.loadDefaultDrawable(defaultDrawableLoader);
+            }
+        }
+        return ParcelableResource.loadDefaultDrawable(defaultDrawableLoader);
+    }
+
+    /**
+     * Similar to {@link #getDrawable(int, int, Callable)}, but also accepts
+     * {@code density}. See {@link Resources#getDrawableForDensity(int, int, Resources.Theme)}.
+     *
+     * <p>Callers should register for {@link #ACTION_DEVICE_POLICY_RESOURCE_UPDATED} to get
+     * notified when a resource has been updated.
+     *
+     * @param drawableId The drawable ID to get the updated resource for.
+     * @param drawableStyle The drawable style to use.
+     * @param density The desired screen density indicated by the resource as
+     *            found in {@link DisplayMetrics}. A value of 0 means to use the
+     *            density returned from {@link Resources#getConfiguration()}.
+     * @param defaultDrawableLoader To get the default drawable if no updated drawable was set for
+     *                              the provided params.
+     */
+    @Nullable
+    public Drawable getDrawableForDensity(
+            @DevicePolicyResources.UpdatableDrawableId int drawableId,
+            @DevicePolicyResources.UpdatableDrawableStyle int drawableStyle,
+            int density,
+            @NonNull Callable<Drawable> defaultDrawableLoader) {
+        return getDrawableForDensity(
+                drawableId,
+                drawableStyle,
+                UNDEFINED,
+                density,
+                defaultDrawableLoader);
+    }
+
+     /**
+     * Similar to {@link #getDrawable(int, int, int, Callable)}, but also accepts
+     * {@code density}. See {@link Resources#getDrawableForDensity(int, int, Resources.Theme)}.
+     *
+     * <p>Callers should register for {@link #ACTION_DEVICE_POLICY_RESOURCE_UPDATED} to get
+     * notified when a resource has been updated.
+     *
+     * @param drawableId The drawable ID to get the updated resource for.
+     * @param drawableStyle The drawable style to use.
+     * @param drawableSource The source for the caller.
+     * @param density The desired screen density indicated by the resource as
+     *            found in {@link DisplayMetrics}. A value of 0 means to use the
+     *            density returned from {@link Resources#getConfiguration()}.
+     * @param defaultDrawableLoader To get the default drawable if no updated drawable was set for
+     *                              the provided params.
+     */
+    @Nullable
+    public Drawable getDrawableForDensity(
+            @DevicePolicyResources.UpdatableDrawableId int drawableId,
+            @DevicePolicyResources.UpdatableDrawableStyle int drawableStyle,
+            @DevicePolicyResources.UpdatableDrawableSource int drawableSource,
+            int density,
+            @NonNull Callable<Drawable> defaultDrawableLoader) {
+        Objects.requireNonNull(defaultDrawableLoader, "defaultDrawableLoader can't be null");
+        if (drawableId == INVALID_ID) {
+            return ParcelableResource.loadDefaultDrawable(defaultDrawableLoader);
+        }
+        if (mService != null) {
+            try {
+                ParcelableResource resource = mService.getDrawable(
+                        drawableId, drawableStyle, drawableSource);
+                if (resource == null) {
+                    return ParcelableResource.loadDefaultDrawable(
+                            defaultDrawableLoader);
+                }
+                return resource.getDrawable(mContext, density, defaultDrawableLoader);
+            } catch (RemoteException e) {
+                Log.e(
+                        TAG,
+                        "Error getting the updated drawable from DevicePolicyManagerService.",
+                        e);
+                return ParcelableResource.loadDefaultDrawable(defaultDrawableLoader);
+            }
+        }
+        return ParcelableResource.loadDefaultDrawable(defaultDrawableLoader);
+    }
 }
diff --git a/core/java/android/app/admin/DevicePolicyResources.java b/core/java/android/app/admin/DevicePolicyResources.java
new file mode 100644
index 0000000..5133f26
--- /dev/null
+++ b/core/java/android/app/admin/DevicePolicyResources.java
@@ -0,0 +1,243 @@
+/*
+ * 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.SuppressLint;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Class containing the required identifiers to update device management resources.
+ *
+ * <p>See {@link DevicePolicyManager#getDrawable}.
+ *
+ */
+public final class DevicePolicyResources {
+
+    /**
+     * Resource identifiers used to update device management-related system drawable resources.
+     *
+     * @hide
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(value = {
+            Drawable.INVALID_ID,
+            Drawable.WORK_PROFILE_ICON_BADGE,
+            Drawable.WORK_PROFILE_ICON,
+            Drawable.WORK_PROFILE_OFF_ICON,
+            Drawable.WORK_PROFILE_USER_ICON
+    })
+    public @interface UpdatableDrawableId {}
+
+    /**
+     * Identifiers to specify the desired style for the updatable device management system
+     * resource.
+     *
+     * @hide
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(value = {
+            Drawable.Style.SOLID_COLORED,
+            Drawable.Style.SOLID_NOT_COLORED,
+            Drawable.Style.OUTLINE,
+    })
+    public @interface UpdatableDrawableStyle {}
+
+    /**
+     * Identifiers to specify the location if the updatable device management system resource.
+     *
+     * @hide
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(value = {
+            Drawable.Source.UNDEFINED,
+            Drawable.Source.NOTIFICATION,
+            Drawable.Source.PROFILE_SWITCH_ANIMATION,
+            Drawable.Source.HOME_WIDGET,
+            Drawable.Source.LAUNCHER_OFF_BUTTON,
+            Drawable.Source.QUICK_SETTINGS,
+            Drawable.Source.STATUS_BAR
+    })
+    public @interface UpdatableDrawableSource {}
+
+
+    /**
+     * Class containing the identifiers used to update device management-related system drawable.
+     */
+    public static final class Drawable {
+
+        private Drawable() {
+        }
+
+        /**
+         * An ID for any drawable that can't be updated.
+         */
+        public static final int INVALID_ID = -1;
+
+        /**
+         * Specifically used to badge work profile app icons.
+         */
+        public static final int WORK_PROFILE_ICON_BADGE = 0;
+
+        /**
+         * General purpose work profile icon (i.e. generic icon badging). For badging app icons
+         * specifically, see {@link #WORK_PROFILE_ICON_BADGE}.
+         */
+        public static final int WORK_PROFILE_ICON = 1;
+
+        /**
+         * General purpose icon representing the work profile off state.
+         */
+        public static final int WORK_PROFILE_OFF_ICON = 2;
+
+        /**
+         * General purpose icon for the work profile user avatar.
+         */
+        public static final int WORK_PROFILE_USER_ICON = 3;
+
+        /**
+         * @hide
+         */
+        public static final Set<Integer> UPDATABLE_DRAWABLE_IDS = buildDrawablesSet();
+
+        private static Set<Integer> buildDrawablesSet() {
+            Set<Integer> drawables = new HashSet<>();
+            drawables.add(WORK_PROFILE_ICON_BADGE);
+            drawables.add(WORK_PROFILE_ICON);
+            drawables.add(WORK_PROFILE_OFF_ICON);
+            drawables.add(WORK_PROFILE_USER_ICON);
+            return drawables;
+        }
+
+        /**
+         * Class containing the source identifiers used to update device management-related system
+         * drawable.
+         */
+        public static final class Source {
+
+            private Source() {
+            }
+
+            /**
+             * A source identifier indicating that the updatable resource is used in a generic
+             * undefined location.
+             */
+            public static final int UNDEFINED = -1;
+
+            /**
+             * A source identifier indicating that the updatable drawable is used in notifications.
+             */
+            public static final int NOTIFICATION = 0;
+
+            /**
+             * A source identifier indicating that the updatable drawable is used in a cross
+             * profile switching animation.
+             */
+            public static final int PROFILE_SWITCH_ANIMATION = 1;
+
+            /**
+             * A source identifier indicating that the updatable drawable is used in a work
+             * profile home screen widget.
+             */
+            public static final int HOME_WIDGET = 2;
+
+            /**
+             * A source identifier indicating that the updatable drawable is used in the launcher
+             * turn off work button.
+             */
+            public static final int LAUNCHER_OFF_BUTTON = 3;
+
+            /**
+             * A source identifier indicating that the updatable drawable is used in quick settings.
+             */
+            public static final int QUICK_SETTINGS = 4;
+
+            /**
+             * A source identifier indicating that the updatable drawable is used in the status bar.
+             */
+            public static final int STATUS_BAR = 5;
+
+            /**
+             * @hide
+             */
+            public static final Set<Integer> UPDATABLE_DRAWABLE_SOURCES = buildSourcesSet();
+
+            private static Set<Integer> buildSourcesSet() {
+                Set<Integer> sources = new HashSet<>();
+                sources.add(UNDEFINED);
+                sources.add(NOTIFICATION);
+                sources.add(PROFILE_SWITCH_ANIMATION);
+                sources.add(HOME_WIDGET);
+                sources.add(LAUNCHER_OFF_BUTTON);
+                sources.add(QUICK_SETTINGS);
+                sources.add(STATUS_BAR);
+                return sources;
+            }
+        }
+
+        /**
+         * Class containing the style identifiers used to update device management-related system
+         * drawable.
+         */
+        @SuppressLint("StaticUtils")
+        public static final class Style {
+
+            private Style() {
+            }
+
+            /**
+             * A style identifier indicating that the updatable drawable should use the default
+             * style.
+             */
+            public static final int DEFAULT = -1;
+
+            /**
+             * A style identifier indicating that the updatable drawable has a solid color fill.
+             */
+            public static final int SOLID_COLORED = 0;
+
+            /**
+             * A style identifier indicating that the updatable drawable has a solid non-colored
+             * fill.
+             */
+            public static final int SOLID_NOT_COLORED = 1;
+
+            /**
+             * A style identifier indicating that the updatable drawable is an outline.
+             */
+            public static final int OUTLINE = 2;
+
+            /**
+             * @hide
+             */
+            public static final Set<Integer> UPDATABLE_DRAWABLE_STYLES = buildStylesSet();
+
+            private static Set<Integer> buildStylesSet() {
+                Set<Integer> styles = new HashSet<>();
+                styles.add(DEFAULT);
+                styles.add(SOLID_COLORED);
+                styles.add(SOLID_NOT_COLORED);
+                styles.add(OUTLINE);
+                return styles;
+            }
+        }
+    }
+}
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index b9fcdf5..8320087 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -17,6 +17,8 @@
 
 package android.app.admin;
 
+import android.app.admin.DevicePolicyDrawableResource;
+import android.app.admin.ParcelableResource;
 import android.app.admin.NetworkEvent;
 import android.app.IApplicationThread;
 import android.app.IServiceConnection;
@@ -531,4 +533,7 @@
     boolean canUsbDataSignalingBeDisabled();
 
     List<UserHandle> listForegroundAffiliatedUsers();
+    void setDrawables(in List<DevicePolicyDrawableResource> resource);
+    void resetDrawables(in int[] drawableIds);
+    ParcelableResource getDrawable(int drawableId, int drawableStyle, int drawableSource);
 }
diff --git a/core/java/android/app/admin/ParcelableResource.aidl b/core/java/android/app/admin/ParcelableResource.aidl
new file mode 100644
index 0000000..dd2b975
--- /dev/null
+++ b/core/java/android/app/admin/ParcelableResource.aidl
@@ -0,0 +1,20 @@
+/*
+ * 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;
+
+parcelable ParcelableResource;
diff --git a/core/java/android/app/admin/ParcelableResource.java b/core/java/android/app/admin/ParcelableResource.java
new file mode 100644
index 0000000..e517162
--- /dev/null
+++ b/core/java/android/app/admin/ParcelableResource.java
@@ -0,0 +1,286 @@
+/*
+ * 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 static java.util.Objects.requireNonNull;
+
+import android.annotation.AnyRes;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Slog;
+import android.util.TypedXmlPullParser;
+import android.util.TypedXmlSerializer;
+
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
+import java.util.concurrent.Callable;
+
+/**
+ * Used to store the required information to load a resource that was updated using
+ * {@link DevicePolicyManager#setDrawables}.
+ *
+ * @hide
+ */
+public final class ParcelableResource implements Parcelable {
+
+    private static String TAG = "DevicePolicyManager";
+
+    private static final String ATTR_RESOURCE_ID = "resource-id";
+    private static final String ATTR_PACKAGE_NAME = "package-name";
+    private static final String ATTR_RESOURCE_NAME = "resource-name";
+    private static final String ATTR_RESOURCE_TYPE = "resource-type";
+
+    public static final int RESOURCE_TYPE_DRAWABLE = 1;
+
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = { "RESOURCE_TYPE_" }, value = {
+            RESOURCE_TYPE_DRAWABLE
+    })
+    public @interface ResourceType {}
+
+    private final int mResourceId;
+    @NonNull private final String mPackageName;
+    @NonNull private final String mResourceName;
+    private final int mResourceType;
+
+    /**
+     *
+     * Creates a {@code ParcelableDevicePolicyResource} for the given {@code resourceId} and
+     * verifies that it exists in the package of the given {@code context}.
+     *
+     * @param context for the package containing the {@code resourceId} to use as the updated
+     *                resource
+     * @param resourceId of the resource to use as an updated resource
+     * @param resourceType see {@link ResourceType}
+     * @throws IllegalArgumentException if the given {@code resourceId} doesn't exist in the
+     * {@link Context#getResources()} of the given {@code context}
+     */
+    public ParcelableResource(@NonNull Context context, @AnyRes int resourceId,
+            @ResourceType int resourceType) throws IllegalArgumentException {
+        Objects.requireNonNull(context, "context must be provided");
+
+        verifyResourceExistsInCallingPackage(context, resourceId, resourceType);
+
+        this.mResourceId = resourceId;
+        this.mPackageName = context.getResources().getResourcePackageName(resourceId);
+        this.mResourceName = context.getResources().getResourceName(resourceId);
+        this.mResourceType = resourceType;
+    }
+
+    /**
+     * Creates a {@code ParcelableDevicePolicyResource} with the given params, this DOES NOT make
+     * any verifications on whether the given {@code resourceId} actually exists.
+     */
+    private ParcelableResource(
+            @AnyRes int resourceId, @NonNull String packageName, @NonNull String resourceName,
+            @ResourceType int resourceType) {
+        this.mResourceId = resourceId;
+        this.mPackageName = requireNonNull(packageName);
+        this.mResourceName = requireNonNull(resourceName);
+        this.mResourceType = resourceType;
+    }
+
+    private static void verifyResourceExistsInCallingPackage(
+            Context context, @AnyRes int resourceId, @ResourceType int resourceType)
+            throws IllegalArgumentException {
+        switch (resourceType) {
+            case RESOURCE_TYPE_DRAWABLE:
+                if (!hasDrawableInCallingPackage(context, resourceId)) {
+                    throw new IllegalArgumentException(String.format(
+                            "Drawable with id %d doesn't exist in the calling package %s",
+                            resourceId,
+                            context.getPackageName()));
+                }
+                break;
+            default:
+                throw new IllegalArgumentException(
+                        "Unknown ParcelableDevicePolicyResourceType: " + resourceType);
+        }
+    }
+
+    private static boolean hasDrawableInCallingPackage(Context context, @AnyRes int resourceId) {
+        try {
+            return context.getDrawable(resourceId) != null;
+        } catch (Resources.NotFoundException e) {
+            return false;
+        }
+    }
+
+    public @AnyRes int getResourceId() {
+        return mResourceId;
+    }
+
+    @NonNull
+    public String getPackageName() {
+        return mPackageName;
+    }
+
+    @NonNull
+    public String getResourceName() {
+        return mResourceName;
+    }
+
+    public int getResourceType() {
+        return mResourceType;
+    }
+
+    /**
+     * Loads the drawable with id {@code mResourceId} from {@code mPackageName} using the provided
+     * {@code density} and {@link Resources.Theme} and {@link Resources#getConfiguration} of the
+     * provided {@code context}.
+     *
+     * <p>Returns the default drawable by calling the {@code defaultDrawableLoader} if the updated
+     * drawable was not found or could not be loaded.</p>
+     */
+    @Nullable
+    public Drawable getDrawable(
+            Context context,
+            int density,
+            @NonNull Callable<Drawable> defaultDrawableLoader) {
+        // TODO(b/203548565): properly handle edge case when the device manager role holder is
+        //  unavailable because it's being updated.
+        try {
+            Resources resources = getAppResourcesWithCallersConfiguration(context);
+            verifyResourceName(resources);
+            return resources.getDrawableForDensity(mResourceId, density, context.getTheme());
+        } catch (PackageManager.NameNotFoundException | RuntimeException e) {
+            Slog.e(TAG, "Unable to load drawable resource " + mResourceName, e);
+            return loadDefaultDrawable(defaultDrawableLoader);
+        }
+    }
+
+    private Resources getAppResourcesWithCallersConfiguration(Context context)
+            throws PackageManager.NameNotFoundException {
+        PackageManager pm = context.getPackageManager();
+        ApplicationInfo ai = pm.getApplicationInfo(
+                mPackageName,
+                PackageManager.MATCH_UNINSTALLED_PACKAGES
+                        | PackageManager.GET_SHARED_LIBRARY_FILES);
+        return pm.getResourcesForApplication(ai, context.getResources().getConfiguration());
+    }
+
+    private void verifyResourceName(Resources resources) throws IllegalStateException {
+        String name = resources.getResourceName(mResourceId);
+        if (!mResourceName.equals(name)) {
+            throw new IllegalStateException(String.format("Current resource name %s for resource id"
+                            + " %d has changed from the previously stored resource name %s.",
+                    name, mResourceId, mResourceName));
+        }
+    }
+
+    /**
+     * returns the {@link Drawable} loaded from calling
+     * {@code defaultDrawableLoader}.
+     */
+    public static Drawable loadDefaultDrawable(
+            @NonNull Callable<Drawable> defaultDrawableLoader) {
+        try {
+            return defaultDrawableLoader.call();
+        } catch (Exception e) {
+            throw new RuntimeException("Couldn't load default drawable", e);
+        }
+    }
+
+    /**
+     * Writes the content of the current {@code ParcelableDevicePolicyResource} to the xml file
+     * specified by {@code xmlSerializer}.
+     */
+    public void writeToXmlFile(TypedXmlSerializer xmlSerializer) throws IOException {
+        xmlSerializer.attributeInt(/* namespace= */ null, ATTR_RESOURCE_ID, mResourceId);
+        xmlSerializer.attribute(/* namespace= */ null, ATTR_PACKAGE_NAME, mPackageName);
+        xmlSerializer.attribute(/* namespace= */ null, ATTR_RESOURCE_NAME, mResourceName);
+        xmlSerializer.attributeInt(/* namespace= */ null, ATTR_RESOURCE_TYPE, mResourceType);
+    }
+
+    /**
+     * Creates a new {@code ParcelableDevicePolicyResource} using the content of
+     * {@code xmlPullParser}.
+     */
+    public static ParcelableResource createFromXml(TypedXmlPullParser xmlPullParser)
+            throws XmlPullParserException, IOException {
+        int resourceId = xmlPullParser.getAttributeInt(/* namespace= */ null, ATTR_RESOURCE_ID);
+        String packageName = xmlPullParser.getAttributeValue(
+                /* namespace= */ null, ATTR_PACKAGE_NAME);
+        String resourceName = xmlPullParser.getAttributeValue(
+                /* namespace= */ null, ATTR_RESOURCE_NAME);
+        int resourceType = xmlPullParser.getAttributeInt(
+                /* namespace= */ null, ATTR_RESOURCE_TYPE);
+
+        return new ParcelableResource(
+                resourceId, packageName, resourceName, resourceType);
+    }
+
+    @Override
+    public boolean equals(@Nullable Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        ParcelableResource other = (ParcelableResource) o;
+        return mResourceId == other.mResourceId
+                && mPackageName.equals(other.mPackageName)
+                && mResourceName.equals(other.mResourceName)
+                && mResourceType == other.mResourceType;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mResourceId, mPackageName, mResourceName, mResourceType);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(mResourceId);
+        dest.writeString(mPackageName);
+        dest.writeString(mResourceName);
+        dest.writeInt(mResourceType);
+    }
+
+    public static final @NonNull Creator<ParcelableResource> CREATOR =
+            new Creator<ParcelableResource>() {
+                @Override
+                public ParcelableResource createFromParcel(Parcel in) {
+                    int resourceId = in.readInt();
+                    String packageName = in.readString();
+                    String resourceName = in.readString();
+                    int resourceType = in.readInt();
+
+                    return new ParcelableResource(
+                            resourceId, packageName, resourceName, resourceType);
+                }
+
+                @Override
+                public ParcelableResource[] newArray(int size) {
+                    return new ParcelableResource[size];
+                }
+            };
+}
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 661291c..0000000
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ /dev/null
@@ -1,4413 +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.time.Duration;
-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 {}
-
-    /** @hide */
-    @IntDef(value = {
-            BluetoothStatusCodes.SUCCESS,
-            BluetoothStatusCodes.ERROR_UNKNOWN,
-            BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED,
-            BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_SCAN_PERMISSION
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface ScanModeStatusCode {}
-
-    /**
-     * 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")
-                public 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) {
-            throw e.rethrowFromSystemServer();
-        } finally {
-            mServiceLock.readLock().unlock();
-        }
-        return SCAN_MODE_NONE;
-    }
-
-    /**
-     * Set the local Bluetooth adapter connectablility and discoverability.
-     * <p>If the scan mode is set to {@link #SCAN_MODE_CONNECTABLE_DISCOVERABLE},
-     * it will change to {@link #SCAN_MODE_CONNECTABLE} after the discoverable timeout.
-     * The discoverable timeout can be set with {@link #setDiscoverableTimeout} and
-     * checked with {@link #getDiscoverableTimeout}. By default, the timeout is usually
-     * 120 seconds on phones which is enough for a remote device to initiate and complete
-     * its discovery process.
-     * <p>Applications cannot set the scan mode. They should use
-     * {@link #ACTION_REQUEST_DISCOVERABLE} instead.
-     *
-     * @param mode represents the desired state of the local device scan mode
-     *
-     * @return status code indicating whether the scan mode was successfully set
-     * @hide
-     */
-    @SystemApi
-    @RequiresBluetoothScanPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_SCAN,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    @ScanModeStatusCode
-    public int setScanMode(@ScanMode int mode) {
-        if (getState() != STATE_ON) {
-            return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED;
-        }
-        try {
-            mServiceLock.readLock().lock();
-            if (mService != null) {
-                return mService.setScanMode(mode, mAttributionSource);
-            }
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        } finally {
-            mServiceLock.readLock().unlock();
-        }
-        return BluetoothStatusCodes.ERROR_UNKNOWN;
-    }
-
-    /**
-     * Get the timeout duration of the {@link #SCAN_MODE_CONNECTABLE_DISCOVERABLE}.
-     *
-     * @return the duration of the discoverable timeout or null if an error has occurred
-     */
-    @RequiresBluetoothScanPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
-    public @Nullable Duration getDiscoverableTimeout() {
-        if (getState() != STATE_ON) {
-            return null;
-        }
-        try {
-            mServiceLock.readLock().lock();
-            if (mService != null) {
-                long timeout = mService.getDiscoverableTimeout(mAttributionSource);
-                return (timeout == -1) ? null : Duration.ofSeconds(timeout);
-            }
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        } finally {
-            mServiceLock.readLock().unlock();
-        }
-        return null;
-    }
-
-    /**
-     * Set the total time the Bluetooth local adapter will stay discoverable when
-     * {@link #setScanMode} is called with {@link #SCAN_MODE_CONNECTABLE_DISCOVERABLE} mode.
-     * After this timeout, the scan mode will fallback to {@link #SCAN_MODE_CONNECTABLE}.
-     * <p>If <code>timeout</code> is set to 0, no timeout will occur and the scan mode will
-     * be persisted until a subsequent call to {@link #setScanMode}.
-     *
-     * @param timeout represents the total duration the local Bluetooth adapter will remain
-     *                discoverable, or no timeout if set to 0
-     * @return whether the timeout was successfully set
-     * @throws IllegalArgumentException if <code>timeout</code> duration in seconds is more
-     *         than {@link Integer#MAX_VALUE}
-     * @hide
-     */
-    @SystemApi
-    @RequiresBluetoothScanPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_SCAN,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    @ScanModeStatusCode
-    public int setDiscoverableTimeout(@NonNull Duration timeout) {
-        if (getState() != STATE_ON) {
-            return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED;
-        }
-        if (timeout.toSeconds() > Integer.MAX_VALUE) {
-            throw new IllegalArgumentException("Timeout in seconds must be less or equal to "
-                    + Integer.MAX_VALUE);
-        }
-        try {
-            mServiceLock.readLock().lock();
-            if (mService != null) {
-                return mService.setDiscoverableTimeout(timeout.toSeconds(), mAttributionSource);
-            }
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        } finally {
-            mServiceLock.readLock().unlock();
-        }
-        return BluetoothStatusCodes.ERROR_UNKNOWN;
-    }
-
-    /**
-     * 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")
-                public 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.FEATURE_SUPPORTED,
-            BluetoothStatusCodes.ERROR_UNKNOWN,
-            BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED,
-            BluetoothStatusCodes.FEATURE_NOT_SUPPORTED,
-    })
-    public @interface LeFeatureReturnValues {}
-
-    /**
-     * Returns {@link BluetoothStatusCodes#FEATURE_SUPPORTED} if the LE audio feature is
-     * supported, {@link BluetoothStatusCodes#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#FEATURE_SUPPORTED} if LE Periodic Advertising Sync
-     * Transfer Sender feature is supported,
-     * {@link BluetoothStatusCodes#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")
-                public 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")
-                public 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 a3c45d0..0000000
--- a/core/java/android/bluetooth/BluetoothClass.java
+++ /dev/null
@@ -1,445 +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.SystemApi;
-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);
-    }
-
-    public static final int PROFILE_HEADSET = 0;
-
-    public static final int PROFILE_A2DP = 1;
-
-    /** @hide */
-    @SystemApi
-    public static final int PROFILE_OPP = 2;
-
-    public static final int PROFILE_HID = 3;
-
-    /** @hide */
-    @SystemApi
-    public static final int PROFILE_PANU = 4;
-
-    /** @hide */
-    @SystemApi
-    public static final int PROFILE_NAP = 5;
-
-    /** @hide */
-    @SystemApi
-    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 whether this device supports specified profile
-     */
-    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 984166d..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")
-                public 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 2ed1eb4..0000000
--- a/core/java/android/bluetooth/BluetoothHeadset.java
+++ /dev/null
@@ -1,1516 +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.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.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-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 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);
-    }
-
-    /** @hide */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(value = {
-            BluetoothHeadset.STATE_AUDIO_DISCONNECTED,
-            BluetoothHeadset.STATE_AUDIO_CONNECTING,
-            BluetoothHeadset.STATE_AUDIO_CONNECTED,
-            BluetoothStatusCodes.ERROR_TIMEOUT
-    })
-    public @interface GetAudioStateReturnValues {}
-
-    /**
-     * Get the current audio state of the Headset.
-     *
-     * @param device is the Bluetooth device for which the audio state is being queried
-     * @return the audio state of the device or an error code
-     * @throws IllegalArgumentException if the device is null
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public @GetAudioStateReturnValues int getAudioState(@NonNull BluetoothDevice device) {
-        if (VDBG) log("getAudioState");
-        if (device == null) {
-            throw new IllegalArgumentException("device cannot be null");
-        }
-        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 e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-                throw e.rethrowFromSystemServer();
-            } catch (TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-                return BluetoothStatusCodes.ERROR_TIMEOUT;
-            }
-        }
-        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()));
-            }
-        }
-    }
-
-    /** @hide */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(value = {
-            BluetoothStatusCodes.SUCCESS,
-            BluetoothStatusCodes.ERROR_UNKNOWN,
-            BluetoothStatusCodes.ERROR_PROFILE_SERVICE_NOT_BOUND,
-            BluetoothStatusCodes.ERROR_TIMEOUT,
-            BluetoothStatusCodes.ERROR_AUDIO_DEVICE_ALREADY_CONNECTED,
-            BluetoothStatusCodes.ERROR_NO_ACTIVE_DEVICES,
-            BluetoothStatusCodes.ERROR_NOT_ACTIVE_DEVICE,
-            BluetoothStatusCodes.ERROR_AUDIO_ROUTE_BLOCKED,
-            BluetoothStatusCodes.ERROR_CALL_ACTIVE,
-            BluetoothStatusCodes.ERROR_PROFILE_NOT_CONNECTED
-    })
-    public @interface ConnectAudioReturnValues {}
-
-    /**
-     * Initiates a connection of SCO audio to the current active HFP device. The active HFP device
-     * can be identified with {@link BluetoothAdapter#getActiveDevices(int)}.
- * <p>
-     * If this function returns {@link BluetoothStatusCodes#SUCCESS}, the intent
-     * {@link #ACTION_AUDIO_STATE_CHANGED} will be broadcasted twice. First with {@link #EXTRA_STATE}
-     * set to {@link #STATE_AUDIO_CONNECTING}. This will be followed by a broadcast with
-     * {@link #EXTRA_STATE} set to either {@link #STATE_AUDIO_CONNECTED} if the audio connection is
-     * established or {@link #STATE_AUDIO_DISCONNECTED} if there was a failure in establishing the
-     * audio connection.
-     *
-     * @return whether the connection was successfully initiated or an error code on failure
-     * @hide
-     */
-    @SystemApi
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public @ConnectAudioReturnValues int connectAudio() {
-        if (VDBG) log("connectAudio()");
-        final IBluetoothHeadset service = mService;
-        final int defaultValue = BluetoothStatusCodes.ERROR_UNKNOWN;
-        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.connectAudio(mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-                throw e.rethrowFromSystemServer();
-            } catch (TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-                return BluetoothStatusCodes.ERROR_TIMEOUT;
-            }
-        }
-        return defaultValue;
-    }
-
-    /** @hide */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(value = {
-            BluetoothStatusCodes.SUCCESS,
-            BluetoothStatusCodes.ERROR_UNKNOWN,
-            BluetoothStatusCodes.ERROR_PROFILE_SERVICE_NOT_BOUND,
-            BluetoothStatusCodes.ERROR_TIMEOUT,
-            BluetoothStatusCodes.ERROR_PROFILE_NOT_CONNECTED,
-            BluetoothStatusCodes.ERROR_AUDIO_DEVICE_ALREADY_DISCONNECTED
-    })
-    public @interface DisconnectAudioReturnValues {}
-
-    /**
-     * Initiates a disconnection of HFP SCO audio from actively connected devices. It also tears
-     * down voice recognition or virtual voice call, if any exists.
-     *
-     * <p> If this function returns {@link BluetoothStatusCodes#SUCCESS}, the intent
-     * {@link #ACTION_AUDIO_STATE_CHANGED} will be broadcasted with {@link #EXTRA_STATE} set to
-     * {@link #STATE_AUDIO_DISCONNECTED}.
-     *
-     * @return whether the disconnection was initiated successfully or an error code on failure
-     * @hide
-     */
-    @SystemApi
-    @RequiresBluetoothConnectPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public @DisconnectAudioReturnValues int disconnectAudio() {
-        if (VDBG) log("disconnectAudio()");
-        final IBluetoothHeadset service = mService;
-        final int defaultValue = BluetoothStatusCodes.ERROR_UNKNOWN;
-        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.disconnectAudio(mAttributionSource, recv);
-                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
-            } catch (RemoteException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-                throw e.rethrowFromSystemServer();
-            } catch (TimeoutException e) {
-                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
-                return BluetoothStatusCodes.ERROR_TIMEOUT;
-            }
-        }
-        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(allOf = {
-            android.Manifest.permission.BLUETOOTH_CONNECT,
-            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 a457679..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) {
-        List<ResolveInfo> results = pm.queryIntentServices(intent,
-                PackageManager.ResolveInfoFlags.of(0));
-        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());
-                    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 a8ce4b4..0000000
--- a/core/java/android/bluetooth/BluetoothStatusCodes.java
+++ /dev/null
@@ -1,361 +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 199. Profile-specific return values occupy the range 200-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
-     * user.
-     */
-    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;
-
-    /**
-     * Indicates that the feature is supported.
-     */
-    public static final int FEATURE_SUPPORTED = 10;
-
-    /**
-     * Indicates that the feature is not supported.
-     */
-    public static final int FEATURE_NOT_SUPPORTED = 11;
-
-    /**
-     * Error code indicating that the device is not the active device for this profile.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int ERROR_NOT_ACTIVE_DEVICE = 12;
-
-    /**
-     * Error code indicating that there are no active devices for the profile.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int ERROR_NO_ACTIVE_DEVICES = 13;
-
-    /**
-     * Indicates that the Bluetooth profile is not connected to this device.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int ERROR_PROFILE_NOT_CONNECTED = 14;
-
-    /**
-     * Error code indicating that the requested operation timed out.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int ERROR_TIMEOUT = 15;
-
-    /**
-     * A GATT writeCharacteristic request is not permitted on the remote device.
-     */
-    public static final int ERROR_GATT_WRITE_NOT_ALLOWED = 200;
-
-    /**
-     * A GATT writeCharacteristic request is issued to a busy remote device.
-     */
-    public static final int ERROR_GATT_WRITE_REQUEST_BUSY = 201;
-
-    /**
-     * 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 there is already one device for which SCO audio is connected or connecting.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int ERROR_AUDIO_DEVICE_ALREADY_CONNECTED = 1116;
-
-    /**
-     * Indicates that SCO audio was already not connected for this device.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int ERROR_AUDIO_DEVICE_ALREADY_DISCONNECTED = 1117;
-
-    /**
-     * Indicates that there audio route is currently blocked by the system.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int ERROR_AUDIO_ROUTE_BLOCKED = 1118;
-
-    /**
-     * Indicates that there is an active call preventing this operation from succeeding.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int ERROR_CALL_ACTIVE = 1119;
-
-    /**
-     * 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 9982fa61..0000000
--- a/core/java/android/bluetooth/UidTraffic.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.bluetooth;
-
-import android.annotation.SystemApi;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Record of data traffic (in bytes) by an application identified by its UID.
- *
- * @hide
- */
-@SystemApi(client = SystemApi.Client.PRIVILEGED_APPS)
-public final class UidTraffic implements Cloneable, Parcelable {
-    private final int mAppUid;
-    private long mRxBytes;
-    private long mTxBytes;
-
-    /** @hide */
-    public UidTraffic(int appUid, long rx, long tx) {
-        mAppUid = appUid;
-        mRxBytes = rx;
-        mTxBytes = tx;
-    }
-
-    /** @hide */
-    private UidTraffic(Parcel in) {
-        mAppUid = in.readInt();
-        mRxBytes = in.readLong();
-        mTxBytes = in.readLong();
-    }
-
-    /** @hide */
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(mAppUid);
-        dest.writeLong(mRxBytes);
-        dest.writeLong(mTxBytes);
-    }
-
-    /** @hide */
-    public void setRxBytes(long bytes) {
-        mRxBytes = bytes;
-    }
-
-    /** @hide */
-    public void setTxBytes(long bytes) {
-        mTxBytes = bytes;
-    }
-
-    /** @hide */
-    public void addRxBytes(long bytes) {
-        mRxBytes += bytes;
-    }
-
-    /** @hide */
-    public void addTxBytes(long bytes) {
-        mTxBytes += bytes;
-    }
-
-    /**
-     * @return corresponding app Uid
-     */
-    public int getUid() {
-        return mAppUid;
-    }
-
-    /**
-     * @return rx bytes count
-     */
-    public long getRxBytes() {
-        return mRxBytes;
-    }
-
-    /**
-     * @return tx bytes count
-     */
-    public long getTxBytes() {
-        return mTxBytes;
-    }
-
-    /** @hide */
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    /** @hide */
-    @Override
-    public UidTraffic clone() {
-        return new UidTraffic(mAppUid, mRxBytes, mTxBytes);
-    }
-
-    /** @hide */
-    @Override
-    public String toString() {
-        return "UidTraffic{mAppUid=" + mAppUid + ", mRxBytes=" + mRxBytes + ", mTxBytes="
-                + mTxBytes + '}';
-    }
-
-    public static final @android.annotation.NonNull Creator<UidTraffic> CREATOR = new Creator<UidTraffic>() {
-        @Override
-        public UidTraffic createFromParcel(Parcel source) {
-            return new UidTraffic(source);
-        }
-
-        @Override
-        public UidTraffic[] newArray(int size) {
-            return new UidTraffic[size];
-        }
-    };
-}
diff --git a/core/java/android/bluetooth/annotations/RequiresBluetoothAdvertisePermission.java b/core/java/android/bluetooth/annotations/RequiresBluetoothAdvertisePermission.java
deleted file mode 100644
index c508c2c..0000000
--- a/core/java/android/bluetooth/annotations/RequiresBluetoothAdvertisePermission.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.annotations;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import android.Manifest;
-import android.os.Build;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * @memberDoc For apps targeting {@link Build.VERSION_CODES#S} or or higher,
- *            this requires the {@link Manifest.permission#BLUETOOTH_ADVERTISE}
- *            permission which can be gained with
- *            {@link android.app.Activity#requestPermissions(String[], int)}.
- * @hide
- */
-@Retention(SOURCE)
-@Target({METHOD, FIELD})
-public @interface RequiresBluetoothAdvertisePermission {
-}
diff --git a/core/java/android/bluetooth/annotations/RequiresBluetoothConnectPermission.java b/core/java/android/bluetooth/annotations/RequiresBluetoothConnectPermission.java
deleted file mode 100644
index e159eaa..0000000
--- a/core/java/android/bluetooth/annotations/RequiresBluetoothConnectPermission.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.annotations;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import android.Manifest;
-import android.os.Build;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * @memberDoc For apps targeting {@link Build.VERSION_CODES#S} or or higher,
- *            this requires the {@link Manifest.permission#BLUETOOTH_CONNECT}
- *            permission which can be gained with
- *            {@link android.app.Activity#requestPermissions(String[], int)}.
- * @hide
- */
-@Retention(SOURCE)
-@Target({METHOD, FIELD})
-public @interface RequiresBluetoothConnectPermission {
-}
diff --git a/core/java/android/bluetooth/annotations/RequiresBluetoothLocationPermission.java b/core/java/android/bluetooth/annotations/RequiresBluetoothLocationPermission.java
deleted file mode 100644
index 2bb3204..0000000
--- a/core/java/android/bluetooth/annotations/RequiresBluetoothLocationPermission.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.annotations;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import android.Manifest;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * @memberDoc In addition, this requires either the
- *            {@link Manifest.permission#ACCESS_FINE_LOCATION}
- *            permission or a strong assertion that you will never derive the
- *            physical location of the device. You can make this assertion by
- *            declaring {@code usesPermissionFlags="neverForLocation"} on the
- *            relevant {@code <uses-permission>} manifest tag, but it may
- *            restrict the types of Bluetooth devices you can interact with.
- * @hide
- */
-@Retention(SOURCE)
-@Target({METHOD, FIELD})
-public @interface RequiresBluetoothLocationPermission {
-}
diff --git a/core/java/android/bluetooth/annotations/RequiresBluetoothScanPermission.java b/core/java/android/bluetooth/annotations/RequiresBluetoothScanPermission.java
deleted file mode 100644
index 800ff39..0000000
--- a/core/java/android/bluetooth/annotations/RequiresBluetoothScanPermission.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.annotations;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import android.Manifest;
-import android.os.Build;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * @memberDoc For apps targeting {@link Build.VERSION_CODES#S} or or higher,
- *            this requires the {@link Manifest.permission#BLUETOOTH_SCAN}
- *            permission which can be gained with
- *            {@link android.app.Activity#requestPermissions(String[], int)}.
- * @hide
- */
-@Retention(SOURCE)
-@Target({METHOD, FIELD})
-public @interface RequiresBluetoothScanPermission {
-}
diff --git a/core/java/android/bluetooth/annotations/RequiresLegacyBluetoothAdminPermission.java b/core/java/android/bluetooth/annotations/RequiresLegacyBluetoothAdminPermission.java
deleted file mode 100644
index 9adf695..0000000
--- a/core/java/android/bluetooth/annotations/RequiresLegacyBluetoothAdminPermission.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.annotations;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import android.Manifest;
-import android.os.Build;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * @memberDoc For apps targeting {@link Build.VERSION_CODES#R} or lower, this
- *            requires the {@link Manifest.permission#BLUETOOTH_ADMIN}
- *            permission which can be gained with a simple
- *            {@code <uses-permission>} manifest tag.
- * @hide
- */
-@Retention(SOURCE)
-@Target({METHOD, FIELD})
-public @interface RequiresLegacyBluetoothAdminPermission {
-}
diff --git a/core/java/android/bluetooth/annotations/RequiresLegacyBluetoothPermission.java b/core/java/android/bluetooth/annotations/RequiresLegacyBluetoothPermission.java
deleted file mode 100644
index 79621c3..0000000
--- a/core/java/android/bluetooth/annotations/RequiresLegacyBluetoothPermission.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.annotations;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import android.Manifest;
-import android.os.Build;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * @memberDoc For apps targeting {@link Build.VERSION_CODES#R} or lower, this
- *            requires the {@link Manifest.permission#BLUETOOTH} permission
- *            which can be gained with a simple {@code <uses-permission>}
- *            manifest tag.
- * @hide
- */
-@Retention(SOURCE)
-@Target({METHOD, FIELD})
-public @interface RequiresLegacyBluetoothPermission {
-}
diff --git a/core/java/android/bluetooth/le/AdvertiseCallback.java b/core/java/android/bluetooth/le/AdvertiseCallback.java
deleted file mode 100644
index 4fa8c4f..0000000
--- a/core/java/android/bluetooth/le/AdvertiseCallback.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.le;
-
-/**
- * Bluetooth LE advertising callbacks, used to deliver advertising operation status.
- */
-public abstract class AdvertiseCallback {
-
-    /**
-     * The requested operation was successful.
-     *
-     * @hide
-     */
-    public static final int ADVERTISE_SUCCESS = 0;
-
-    /**
-     * Failed to start advertising as the advertise data to be broadcasted is larger than 31 bytes.
-     */
-    public static final int ADVERTISE_FAILED_DATA_TOO_LARGE = 1;
-
-    /**
-     * Failed to start advertising because no advertising instance is available.
-     */
-    public static final int ADVERTISE_FAILED_TOO_MANY_ADVERTISERS = 2;
-
-    /**
-     * Failed to start advertising as the advertising is already started.
-     */
-    public static final int ADVERTISE_FAILED_ALREADY_STARTED = 3;
-
-    /**
-     * Operation failed due to an internal error.
-     */
-    public static final int ADVERTISE_FAILED_INTERNAL_ERROR = 4;
-
-    /**
-     * This feature is not supported on this platform.
-     */
-    public static final int ADVERTISE_FAILED_FEATURE_UNSUPPORTED = 5;
-
-    /**
-     * Callback triggered in response to {@link BluetoothLeAdvertiser#startAdvertising} indicating
-     * that the advertising has been started successfully.
-     *
-     * @param settingsInEffect The actual settings used for advertising, which may be different from
-     * what has been requested.
-     */
-    public void onStartSuccess(AdvertiseSettings settingsInEffect) {
-    }
-
-    /**
-     * Callback when advertising could not be started.
-     *
-     * @param errorCode Error code (see ADVERTISE_FAILED_* constants) for advertising start
-     * failures.
-     */
-    public void onStartFailure(int errorCode) {
-    }
-}
diff --git a/core/java/android/bluetooth/le/AdvertiseData.java b/core/java/android/bluetooth/le/AdvertiseData.java
deleted file mode 100644
index fdf62ec..0000000
--- a/core/java/android/bluetooth/le/AdvertiseData.java
+++ /dev/null
@@ -1,374 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.le;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.os.Parcel;
-import android.os.ParcelUuid;
-import android.os.Parcelable;
-import android.util.ArrayMap;
-import android.util.SparseArray;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-
-/**
- * Advertise data packet container for Bluetooth LE advertising. This represents the data to be
- * advertised as well as the scan response data for active scans.
- * <p>
- * Use {@link AdvertiseData.Builder} to create an instance of {@link AdvertiseData} to be
- * advertised.
- *
- * @see BluetoothLeAdvertiser
- * @see ScanRecord
- */
-public final class AdvertiseData implements Parcelable {
-
-    @Nullable
-    private final List<ParcelUuid> mServiceUuids;
-
-    @NonNull
-    private final List<ParcelUuid> mServiceSolicitationUuids;
-
-    @Nullable
-    private final List<TransportDiscoveryData> mTransportDiscoveryData;
-
-    private final SparseArray<byte[]> mManufacturerSpecificData;
-    private final Map<ParcelUuid, byte[]> mServiceData;
-    private final boolean mIncludeTxPowerLevel;
-    private final boolean mIncludeDeviceName;
-
-    private AdvertiseData(List<ParcelUuid> serviceUuids,
-            List<ParcelUuid> serviceSolicitationUuids,
-            List<TransportDiscoveryData> transportDiscoveryData,
-            SparseArray<byte[]> manufacturerData,
-            Map<ParcelUuid, byte[]> serviceData,
-            boolean includeTxPowerLevel,
-            boolean includeDeviceName) {
-        mServiceUuids = serviceUuids;
-        mServiceSolicitationUuids = serviceSolicitationUuids;
-        mTransportDiscoveryData = transportDiscoveryData;
-        mManufacturerSpecificData = manufacturerData;
-        mServiceData = serviceData;
-        mIncludeTxPowerLevel = includeTxPowerLevel;
-        mIncludeDeviceName = includeDeviceName;
-    }
-
-    /**
-     * Returns a list of service UUIDs within the advertisement that are used to identify the
-     * Bluetooth GATT services.
-     */
-    public List<ParcelUuid> getServiceUuids() {
-        return mServiceUuids;
-    }
-
-    /**
-     * Returns a list of service solicitation UUIDs within the advertisement that we invite to connect.
-     */
-    @NonNull
-    public List<ParcelUuid> getServiceSolicitationUuids() {
-        return mServiceSolicitationUuids;
-    }
-
-    /**
-     * Returns a list of {@link TransportDiscoveryData} within the advertisement.
-     */
-    @NonNull
-    public List<TransportDiscoveryData> getTransportDiscoveryData() {
-        if (mTransportDiscoveryData == null) {
-            return Collections.emptyList();
-        }
-        return mTransportDiscoveryData;
-    }
-
-    /**
-     * Returns an array of manufacturer Id and the corresponding manufacturer specific data. The
-     * manufacturer id is a non-negative number assigned by Bluetooth SIG.
-     */
-    public SparseArray<byte[]> getManufacturerSpecificData() {
-        return mManufacturerSpecificData;
-    }
-
-    /**
-     * Returns a map of 16-bit UUID and its corresponding service data.
-     */
-    public Map<ParcelUuid, byte[]> getServiceData() {
-        return mServiceData;
-    }
-
-    /**
-     * Whether the transmission power level will be included in the advertisement packet.
-     */
-    public boolean getIncludeTxPowerLevel() {
-        return mIncludeTxPowerLevel;
-    }
-
-    /**
-     * Whether the device name will be included in the advertisement packet.
-     */
-    public boolean getIncludeDeviceName() {
-        return mIncludeDeviceName;
-    }
-
-    /**
-     * @hide
-     */
-    @Override
-    public int hashCode() {
-        return Objects.hash(mServiceUuids, mServiceSolicitationUuids, mTransportDiscoveryData,
-                mManufacturerSpecificData, mServiceData, mIncludeDeviceName, mIncludeTxPowerLevel);
-    }
-
-    /**
-     * @hide
-     */
-    @Override
-    public boolean equals(@Nullable Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj == null || getClass() != obj.getClass()) {
-            return false;
-        }
-        AdvertiseData other = (AdvertiseData) obj;
-        return Objects.equals(mServiceUuids, other.mServiceUuids)
-                && Objects.equals(mServiceSolicitationUuids, other.mServiceSolicitationUuids)
-                && Objects.equals(mTransportDiscoveryData, other.mTransportDiscoveryData)
-                && BluetoothLeUtils.equals(mManufacturerSpecificData,
-                    other.mManufacturerSpecificData)
-                && BluetoothLeUtils.equals(mServiceData, other.mServiceData)
-                && mIncludeDeviceName == other.mIncludeDeviceName
-                && mIncludeTxPowerLevel == other.mIncludeTxPowerLevel;
-    }
-
-    @Override
-    public String toString() {
-        return "AdvertiseData [mServiceUuids=" + mServiceUuids + ", mServiceSolicitationUuids="
-                + mServiceSolicitationUuids + ", mTransportDiscoveryData="
-                + mTransportDiscoveryData + ", mManufacturerSpecificData="
-                + BluetoothLeUtils.toString(mManufacturerSpecificData) + ", mServiceData="
-                + BluetoothLeUtils.toString(mServiceData)
-                + ", mIncludeTxPowerLevel=" + mIncludeTxPowerLevel + ", mIncludeDeviceName="
-                + mIncludeDeviceName + "]";
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeTypedArray(mServiceUuids.toArray(new ParcelUuid[mServiceUuids.size()]), flags);
-        dest.writeTypedArray(mServiceSolicitationUuids.toArray(
-                new ParcelUuid[mServiceSolicitationUuids.size()]), flags);
-
-        dest.writeTypedList(mTransportDiscoveryData);
-
-        // mManufacturerSpecificData could not be null.
-        dest.writeInt(mManufacturerSpecificData.size());
-        for (int i = 0; i < mManufacturerSpecificData.size(); ++i) {
-            dest.writeInt(mManufacturerSpecificData.keyAt(i));
-            dest.writeByteArray(mManufacturerSpecificData.valueAt(i));
-        }
-        dest.writeInt(mServiceData.size());
-        for (ParcelUuid uuid : mServiceData.keySet()) {
-            dest.writeTypedObject(uuid, flags);
-            dest.writeByteArray(mServiceData.get(uuid));
-        }
-        dest.writeByte((byte) (getIncludeTxPowerLevel() ? 1 : 0));
-        dest.writeByte((byte) (getIncludeDeviceName() ? 1 : 0));
-    }
-
-    public static final @android.annotation.NonNull Parcelable.Creator<AdvertiseData> CREATOR =
-            new Creator<AdvertiseData>() {
-                @Override
-                public AdvertiseData[] newArray(int size) {
-                    return new AdvertiseData[size];
-                }
-
-                @Override
-                public AdvertiseData createFromParcel(Parcel in) {
-                    Builder builder = new Builder();
-                    ArrayList<ParcelUuid> uuids = in.createTypedArrayList(ParcelUuid.CREATOR);
-                    for (ParcelUuid uuid : uuids) {
-                        builder.addServiceUuid(uuid);
-                    }
-
-                    ArrayList<ParcelUuid> solicitationUuids = in.createTypedArrayList(ParcelUuid.CREATOR);
-                    for (ParcelUuid uuid : solicitationUuids) {
-                        builder.addServiceSolicitationUuid(uuid);
-                    }
-
-                    List<TransportDiscoveryData> transportDiscoveryData =
-                            in.createTypedArrayList(TransportDiscoveryData.CREATOR);
-                    for (TransportDiscoveryData tdd : transportDiscoveryData) {
-                        builder.addTransportDiscoveryData(tdd);
-                    }
-
-                    int manufacturerSize = in.readInt();
-                    for (int i = 0; i < manufacturerSize; ++i) {
-                        int manufacturerId = in.readInt();
-                        byte[] manufacturerData = in.createByteArray();
-                        builder.addManufacturerData(manufacturerId, manufacturerData);
-                    }
-                    int serviceDataSize = in.readInt();
-                    for (int i = 0; i < serviceDataSize; ++i) {
-                        ParcelUuid serviceDataUuid = in.readTypedObject(ParcelUuid.CREATOR);
-                        byte[] serviceData = in.createByteArray();
-                        builder.addServiceData(serviceDataUuid, serviceData);
-                    }
-                    builder.setIncludeTxPowerLevel(in.readByte() == 1);
-                    builder.setIncludeDeviceName(in.readByte() == 1);
-                    return builder.build();
-                }
-            };
-
-    /**
-     * Builder for {@link AdvertiseData}.
-     */
-    public static final class Builder {
-        @Nullable
-        private List<ParcelUuid> mServiceUuids = new ArrayList<ParcelUuid>();
-        @NonNull
-        private List<ParcelUuid> mServiceSolicitationUuids = new ArrayList<ParcelUuid>();
-        @Nullable
-        private List<TransportDiscoveryData> mTransportDiscoveryData =
-                new ArrayList<TransportDiscoveryData>();
-        private SparseArray<byte[]> mManufacturerSpecificData = new SparseArray<byte[]>();
-        private Map<ParcelUuid, byte[]> mServiceData = new ArrayMap<ParcelUuid, byte[]>();
-        private boolean mIncludeTxPowerLevel;
-        private boolean mIncludeDeviceName;
-
-        /**
-         * Add a service UUID to advertise data.
-         *
-         * @param serviceUuid A service UUID to be advertised.
-         * @throws IllegalArgumentException If the {@code serviceUuid} is null.
-         */
-        public Builder addServiceUuid(ParcelUuid serviceUuid) {
-            if (serviceUuid == null) {
-                throw new IllegalArgumentException("serviceUuid is null");
-            }
-            mServiceUuids.add(serviceUuid);
-            return this;
-        }
-
-        /**
-         * Add a service solicitation UUID to advertise data.
-         *
-         * @param serviceSolicitationUuid A service solicitation UUID to be advertised.
-         * @throws IllegalArgumentException If the {@code serviceSolicitationUuid} is null.
-         */
-        @NonNull
-        public Builder addServiceSolicitationUuid(@NonNull ParcelUuid serviceSolicitationUuid) {
-            if (serviceSolicitationUuid == null) {
-                throw new IllegalArgumentException("serviceSolicitationUuid is null");
-            }
-            mServiceSolicitationUuids.add(serviceSolicitationUuid);
-            return this;
-        }
-
-        /**
-         * Add service data to advertise data.
-         *
-         * @param serviceDataUuid 16-bit UUID of the service the data is associated with
-         * @param serviceData Service data
-         * @throws IllegalArgumentException If the {@code serviceDataUuid} or {@code serviceData} is
-         * empty.
-         */
-        public Builder addServiceData(ParcelUuid serviceDataUuid, byte[] serviceData) {
-            if (serviceDataUuid == null || serviceData == null) {
-                throw new IllegalArgumentException(
-                        "serviceDataUuid or serviceDataUuid is null");
-            }
-            mServiceData.put(serviceDataUuid, serviceData);
-            return this;
-        }
-
-        /**
-         * Add Transport Discovery Data to advertise data.
-         *
-         * @param transportDiscoveryData Transport Discovery Data, consisting of one or more
-         * Transport Blocks. Transport Discovery Data AD Type Code is already included.
-         * @throws IllegalArgumentException If the {@code transportDiscoveryData} is empty
-         */
-        @NonNull
-        public Builder addTransportDiscoveryData(
-                @NonNull TransportDiscoveryData transportDiscoveryData) {
-            if (transportDiscoveryData == null) {
-                throw new IllegalArgumentException("transportDiscoveryData is null");
-            }
-            mTransportDiscoveryData.add(transportDiscoveryData);
-            return this;
-        }
-
-        /**
-         * Add manufacturer specific data.
-         * <p>
-         * Please refer to the Bluetooth Assigned Numbers document provided by the <a
-         * href="https://www.bluetooth.org">Bluetooth SIG</a> for a list of existing company
-         * identifiers.
-         *
-         * @param manufacturerId Manufacturer ID assigned by Bluetooth SIG.
-         * @param manufacturerSpecificData Manufacturer specific data
-         * @throws IllegalArgumentException If the {@code manufacturerId} is negative or {@code
-         * manufacturerSpecificData} is null.
-         */
-        public Builder addManufacturerData(int manufacturerId, byte[] manufacturerSpecificData) {
-            if (manufacturerId < 0) {
-                throw new IllegalArgumentException(
-                        "invalid manufacturerId - " + manufacturerId);
-            }
-            if (manufacturerSpecificData == null) {
-                throw new IllegalArgumentException("manufacturerSpecificData is null");
-            }
-            mManufacturerSpecificData.put(manufacturerId, manufacturerSpecificData);
-            return this;
-        }
-
-        /**
-         * Whether the transmission power level should be included in the advertise packet. Tx power
-         * level field takes 3 bytes in advertise packet.
-         */
-        public Builder setIncludeTxPowerLevel(boolean includeTxPowerLevel) {
-            mIncludeTxPowerLevel = includeTxPowerLevel;
-            return this;
-        }
-
-        /**
-         * Set whether the device name should be included in advertise packet.
-         */
-        public Builder setIncludeDeviceName(boolean includeDeviceName) {
-            mIncludeDeviceName = includeDeviceName;
-            return this;
-        }
-
-        /**
-         * Build the {@link AdvertiseData}.
-         */
-        public AdvertiseData build() {
-            return new AdvertiseData(mServiceUuids, mServiceSolicitationUuids,
-                    mTransportDiscoveryData, mManufacturerSpecificData, mServiceData,
-                    mIncludeTxPowerLevel, mIncludeDeviceName);
-        }
-    }
-}
diff --git a/core/java/android/bluetooth/le/AdvertiseSettings.java b/core/java/android/bluetooth/le/AdvertiseSettings.java
deleted file mode 100644
index c52a6ee..0000000
--- a/core/java/android/bluetooth/le/AdvertiseSettings.java
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.le;
-
-import android.annotation.NonNull;
-import android.annotation.SystemApi;
-import android.bluetooth.le.AdvertisingSetParameters.AddressTypeStatus;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * The {@link AdvertiseSettings} provide a way to adjust advertising preferences for each
- * Bluetooth LE advertisement instance. Use {@link AdvertiseSettings.Builder} to create an
- * instance of this class.
- */
-public final class AdvertiseSettings implements Parcelable {
-    /**
-     * Perform Bluetooth LE advertising in low power mode. This is the default and preferred
-     * advertising mode as it consumes the least power.
-     */
-    public static final int ADVERTISE_MODE_LOW_POWER = 0;
-
-    /**
-     * Perform Bluetooth LE advertising in balanced power mode. This is balanced between advertising
-     * frequency and power consumption.
-     */
-    public static final int ADVERTISE_MODE_BALANCED = 1;
-
-    /**
-     * Perform Bluetooth LE advertising in low latency, high power mode. This has the highest power
-     * consumption and should not be used for continuous background advertising.
-     */
-    public static final int ADVERTISE_MODE_LOW_LATENCY = 2;
-
-    /**
-     * Advertise using the lowest transmission (TX) power level. Low transmission power can be used
-     * to restrict the visibility range of advertising packets.
-     */
-    public static final int ADVERTISE_TX_POWER_ULTRA_LOW = 0;
-
-    /**
-     * Advertise using low TX power level.
-     */
-    public static final int ADVERTISE_TX_POWER_LOW = 1;
-
-    /**
-     * Advertise using medium TX power level.
-     */
-    public static final int ADVERTISE_TX_POWER_MEDIUM = 2;
-
-    /**
-     * Advertise using high TX power level. This corresponds to largest visibility range of the
-     * advertising packet.
-     */
-    public static final int ADVERTISE_TX_POWER_HIGH = 3;
-
-    /**
-     * The maximum limited advertisement duration as specified by the Bluetooth SIG
-     */
-    private static final int LIMITED_ADVERTISING_MAX_MILLIS = 180 * 1000;
-
-
-    private final int mAdvertiseMode;
-    private final int mAdvertiseTxPowerLevel;
-    private final int mAdvertiseTimeoutMillis;
-    private final boolean mAdvertiseConnectable;
-    private final int mOwnAddressType;
-
-    private AdvertiseSettings(int advertiseMode, int advertiseTxPowerLevel,
-            boolean advertiseConnectable, int advertiseTimeout,
-            @AddressTypeStatus int ownAddressType) {
-        mAdvertiseMode = advertiseMode;
-        mAdvertiseTxPowerLevel = advertiseTxPowerLevel;
-        mAdvertiseConnectable = advertiseConnectable;
-        mAdvertiseTimeoutMillis = advertiseTimeout;
-        mOwnAddressType = ownAddressType;
-    }
-
-    private AdvertiseSettings(Parcel in) {
-        mAdvertiseMode = in.readInt();
-        mAdvertiseTxPowerLevel = in.readInt();
-        mAdvertiseConnectable = in.readInt() != 0;
-        mAdvertiseTimeoutMillis = in.readInt();
-        mOwnAddressType = in.readInt();
-    }
-
-    /**
-     * Returns the advertise mode.
-     */
-    public int getMode() {
-        return mAdvertiseMode;
-    }
-
-    /**
-     * Returns the TX power level for advertising.
-     */
-    public int getTxPowerLevel() {
-        return mAdvertiseTxPowerLevel;
-    }
-
-    /**
-     * Returns whether the advertisement will indicate connectable.
-     */
-    public boolean isConnectable() {
-        return mAdvertiseConnectable;
-    }
-
-    /**
-     * Returns the advertising time limit in milliseconds.
-     */
-    public int getTimeout() {
-        return mAdvertiseTimeoutMillis;
-    }
-
-    /**
-     * @return the own address type for advertising
-     *
-     * @hide
-     */
-    @SystemApi
-    public @AddressTypeStatus int getOwnAddressType() {
-        return mOwnAddressType;
-    }
-
-    @Override
-    public String toString() {
-        return "Settings [mAdvertiseMode=" + mAdvertiseMode
-                + ", mAdvertiseTxPowerLevel=" + mAdvertiseTxPowerLevel
-                + ", mAdvertiseConnectable=" + mAdvertiseConnectable
-                + ", mAdvertiseTimeoutMillis=" + mAdvertiseTimeoutMillis
-                + ", mOwnAddressType=" + mOwnAddressType + "]";
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(mAdvertiseMode);
-        dest.writeInt(mAdvertiseTxPowerLevel);
-        dest.writeInt(mAdvertiseConnectable ? 1 : 0);
-        dest.writeInt(mAdvertiseTimeoutMillis);
-        dest.writeInt(mOwnAddressType);
-    }
-
-    public static final @android.annotation.NonNull Parcelable.Creator<AdvertiseSettings> CREATOR =
-            new Creator<AdvertiseSettings>() {
-                @Override
-                public AdvertiseSettings[] newArray(int size) {
-                    return new AdvertiseSettings[size];
-                }
-
-                @Override
-                public AdvertiseSettings createFromParcel(Parcel in) {
-                    return new AdvertiseSettings(in);
-                }
-            };
-
-    /**
-     * Builder class for {@link AdvertiseSettings}.
-     */
-    public static final class Builder {
-        private int mMode = ADVERTISE_MODE_LOW_POWER;
-        private int mTxPowerLevel = ADVERTISE_TX_POWER_MEDIUM;
-        private int mTimeoutMillis = 0;
-        private boolean mConnectable = true;
-        private int mOwnAddressType = AdvertisingSetParameters.ADDRESS_TYPE_DEFAULT;
-
-        /**
-         * Set advertise mode to control the advertising power and latency.
-         *
-         * @param advertiseMode Bluetooth LE Advertising mode, can only be one of {@link
-         * AdvertiseSettings#ADVERTISE_MODE_LOW_POWER},
-         * {@link AdvertiseSettings#ADVERTISE_MODE_BALANCED},
-         * or {@link AdvertiseSettings#ADVERTISE_MODE_LOW_LATENCY}.
-         * @throws IllegalArgumentException If the advertiseMode is invalid.
-         */
-        public Builder setAdvertiseMode(int advertiseMode) {
-            if (advertiseMode < ADVERTISE_MODE_LOW_POWER
-                    || advertiseMode > ADVERTISE_MODE_LOW_LATENCY) {
-                throw new IllegalArgumentException("unknown mode " + advertiseMode);
-            }
-            mMode = advertiseMode;
-            return this;
-        }
-
-        /**
-         * Set advertise TX power level to control the transmission power level for the advertising.
-         *
-         * @param txPowerLevel Transmission power of Bluetooth LE Advertising, can only be one of
-         * {@link AdvertiseSettings#ADVERTISE_TX_POWER_ULTRA_LOW}, {@link
-         * AdvertiseSettings#ADVERTISE_TX_POWER_LOW},
-         * {@link AdvertiseSettings#ADVERTISE_TX_POWER_MEDIUM}
-         * or {@link AdvertiseSettings#ADVERTISE_TX_POWER_HIGH}.
-         * @throws IllegalArgumentException If the {@code txPowerLevel} is invalid.
-         */
-        public Builder setTxPowerLevel(int txPowerLevel) {
-            if (txPowerLevel < ADVERTISE_TX_POWER_ULTRA_LOW
-                    || txPowerLevel > ADVERTISE_TX_POWER_HIGH) {
-                throw new IllegalArgumentException("unknown tx power level " + txPowerLevel);
-            }
-            mTxPowerLevel = txPowerLevel;
-            return this;
-        }
-
-        /**
-         * Set whether the advertisement type should be connectable or non-connectable.
-         *
-         * @param connectable Controls whether the advertisment type will be connectable (true) or
-         * non-connectable (false).
-         */
-        public Builder setConnectable(boolean connectable) {
-            mConnectable = connectable;
-            return this;
-        }
-
-        /**
-         * Limit advertising to a given amount of time.
-         *
-         * @param timeoutMillis Advertising time limit. May not exceed 180000 milliseconds. A value
-         * of 0 will disable the time limit.
-         * @throws IllegalArgumentException If the provided timeout is over 180000 ms.
-         */
-        public Builder setTimeout(int timeoutMillis) {
-            if (timeoutMillis < 0 || timeoutMillis > LIMITED_ADVERTISING_MAX_MILLIS) {
-                throw new IllegalArgumentException("timeoutMillis invalid (must be 0-"
-                        + LIMITED_ADVERTISING_MAX_MILLIS + " milliseconds)");
-            }
-            mTimeoutMillis = timeoutMillis;
-            return this;
-        }
-
-        /**
-         * Set own address type for advertising to control public or privacy mode. If used to set
-         * address type anything other than {@link AdvertisingSetParameters#ADDRESS_TYPE_DEFAULT},
-         * then it will require BLUETOOTH_PRIVILEGED permission and will be checked at the
-         * time of starting advertising.
-         *
-         * @throws IllegalArgumentException If the {@code ownAddressType} is invalid
-         *
-         * @hide
-         */
-        @SystemApi
-        public @NonNull Builder setOwnAddressType(@AddressTypeStatus int ownAddressType) {
-            if (ownAddressType < AdvertisingSetParameters.ADDRESS_TYPE_DEFAULT
-                    ||  ownAddressType > AdvertisingSetParameters.ADDRESS_TYPE_RANDOM) {
-                throw new IllegalArgumentException("unknown address type " + ownAddressType);
-            }
-            mOwnAddressType = ownAddressType;
-            return this;
-        }
-
-        /**
-         * Build the {@link AdvertiseSettings} object.
-         */
-        public AdvertiseSettings build() {
-            return new AdvertiseSettings(mMode, mTxPowerLevel, mConnectable, mTimeoutMillis,
-                mOwnAddressType);
-        }
-    }
-}
diff --git a/core/java/android/bluetooth/le/AdvertisingSet.java b/core/java/android/bluetooth/le/AdvertisingSet.java
deleted file mode 100644
index bbdb695..0000000
--- a/core/java/android/bluetooth/le/AdvertisingSet.java
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.le;
-
-import android.annotation.RequiresNoPermission;
-import android.annotation.RequiresPermission;
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.IBluetoothGatt;
-import android.bluetooth.IBluetoothManager;
-import android.bluetooth.annotations.RequiresBluetoothAdvertisePermission;
-import android.bluetooth.annotations.RequiresLegacyBluetoothAdminPermission;
-import android.content.AttributionSource;
-import android.os.RemoteException;
-import android.util.Log;
-
-/**
- * This class provides a way to control single Bluetooth LE advertising instance.
- * <p>
- * To get an instance of {@link AdvertisingSet}, call the
- * {@link BluetoothLeAdvertiser#startAdvertisingSet} method.
- *
- * @see AdvertiseData
- */
-public final class AdvertisingSet {
-    private static final String TAG = "AdvertisingSet";
-
-    private final IBluetoothGatt mGatt;
-    private int mAdvertiserId;
-    private AttributionSource mAttributionSource;
-
-    /* package */ AdvertisingSet(int advertiserId, IBluetoothManager bluetoothManager,
-            AttributionSource attributionSource) {
-        mAdvertiserId = advertiserId;
-        mAttributionSource = attributionSource;
-        try {
-            mGatt = bluetoothManager.getBluetoothGatt();
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to get Bluetooth gatt - ", e);
-            throw new IllegalStateException("Failed to get Bluetooth");
-        }
-    }
-
-    /* package */ void setAdvertiserId(int advertiserId) {
-        mAdvertiserId = advertiserId;
-    }
-
-    /**
-     * Enables Advertising. This method returns immediately, the operation status is
-     * delivered through {@code callback.onAdvertisingEnabled()}.
-     *
-     * @param enable whether the advertising should be enabled (true), or disabled (false)
-     * @param duration advertising duration, in 10ms unit. Valid range is from 1 (10ms) to 65535
-     * (655,350 ms)
-     * @param maxExtendedAdvertisingEvents maximum number of extended advertising events the
-     * controller shall attempt to send prior to terminating the extended advertising, even if the
-     * duration has not expired. Valid range is from 1 to 255.
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothAdvertisePermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)
-    public void enableAdvertising(boolean enable, int duration,
-            int maxExtendedAdvertisingEvents) {
-        try {
-            mGatt.enableAdvertisingSet(mAdvertiserId, enable, duration,
-                    maxExtendedAdvertisingEvents, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "remote exception - ", e);
-        }
-    }
-
-    /**
-     * Set/update data being Advertised. Make sure that data doesn't exceed the size limit for
-     * specified AdvertisingSetParameters. This method returns immediately, the operation status is
-     * delivered through {@code callback.onAdvertisingDataSet()}.
-     * <p>
-     * Advertising data must be empty if non-legacy scannable advertising is used.
-     *
-     * @param advertiseData Advertisement data to be broadcasted. Size must not exceed {@link
-     * BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the advertisement is connectable,
-     * three bytes will be added for flags. If the update takes place when the advertising set is
-     * enabled, the data can be maximum 251 bytes long.
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothAdvertisePermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)
-    public void setAdvertisingData(AdvertiseData advertiseData) {
-        try {
-            mGatt.setAdvertisingData(mAdvertiserId, advertiseData, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "remote exception - ", e);
-        }
-    }
-
-    /**
-     * Set/update scan response data. Make sure that data doesn't exceed the size limit for
-     * specified AdvertisingSetParameters. This method returns immediately, the operation status
-     * is delivered through {@code callback.onScanResponseDataSet()}.
-     *
-     * @param scanResponse Scan response associated with the advertisement data. Size must not
-     * exceed {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the update takes place
-     * when the advertising set is enabled, the data can be maximum 251 bytes long.
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothAdvertisePermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)
-    public void setScanResponseData(AdvertiseData scanResponse) {
-        try {
-            mGatt.setScanResponseData(mAdvertiserId, scanResponse, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "remote exception - ", e);
-        }
-    }
-
-    /**
-     * Update advertising parameters associated with this AdvertisingSet. Must be called when
-     * advertising is not active. This method returns immediately, the operation status is delivered
-     * through {@code callback.onAdvertisingParametersUpdated}.
-     *
-     * @param parameters advertising set parameters.
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothAdvertisePermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)
-    public void setAdvertisingParameters(AdvertisingSetParameters parameters) {
-        try {
-            mGatt.setAdvertisingParameters(mAdvertiserId, parameters, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "remote exception - ", e);
-        }
-    }
-
-    /**
-     * Update periodic advertising parameters associated with this set. Must be called when
-     * periodic advertising is not enabled. This method returns immediately, the operation
-     * status is delivered through {@code callback.onPeriodicAdvertisingParametersUpdated()}.
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothAdvertisePermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)
-    public void setPeriodicAdvertisingParameters(PeriodicAdvertisingParameters parameters) {
-        try {
-            mGatt.setPeriodicAdvertisingParameters(mAdvertiserId, parameters, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "remote exception - ", e);
-        }
-    }
-
-    /**
-     * Used to set periodic advertising data, must be called after setPeriodicAdvertisingParameters,
-     * or after advertising was started with periodic advertising data set. This method returns
-     * immediately, the operation status is delivered through
-     * {@code callback.onPeriodicAdvertisingDataSet()}.
-     *
-     * @param periodicData Periodic advertising data. Size must not exceed {@link
-     * BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the update takes place when the
-     * periodic advertising is enabled for this set, the data can be maximum 251 bytes long.
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothAdvertisePermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)
-    public void setPeriodicAdvertisingData(AdvertiseData periodicData) {
-        try {
-            mGatt.setPeriodicAdvertisingData(mAdvertiserId, periodicData, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "remote exception - ", e);
-        }
-    }
-
-    /**
-     * Used to enable/disable periodic advertising. This method returns immediately, the operation
-     * status is delivered through {@code callback.onPeriodicAdvertisingEnable()}.
-     *
-     * @param enable whether the periodic advertising should be enabled (true), or disabled
-     * (false).
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothAdvertisePermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)
-    public void setPeriodicAdvertisingEnabled(boolean enable) {
-        try {
-            mGatt.setPeriodicAdvertisingEnable(mAdvertiserId, enable, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "remote exception - ", e);
-        }
-    }
-
-    /**
-     * Returns address associated with this advertising set.
-     * This method is exposed only for Bluetooth PTS tests, no app or system service
-     * should ever use it.
-     *
-     * @hide
-     */
-    @RequiresBluetoothAdvertisePermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_ADVERTISE,
-            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
-    })
-    public void getOwnAddress() {
-        try {
-            mGatt.getOwnAddress(mAdvertiserId, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "remote exception - ", e);
-        }
-    }
-
-    /**
-     * Returns advertiserId associated with this advertising set.
-     *
-     * @hide
-     */
-    @RequiresNoPermission
-    public int getAdvertiserId() {
-        return mAdvertiserId;
-    }
-}
diff --git a/core/java/android/bluetooth/le/AdvertisingSetCallback.java b/core/java/android/bluetooth/le/AdvertisingSetCallback.java
deleted file mode 100644
index 51324fd..0000000
--- a/core/java/android/bluetooth/le/AdvertisingSetCallback.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.le;
-
-/**
- * Bluetooth LE advertising set callbacks, used to deliver advertising operation
- * status.
- */
-public abstract class AdvertisingSetCallback {
-
-    /**
-     * The requested operation was successful.
-     */
-    public static final int ADVERTISE_SUCCESS = 0;
-
-    /**
-     * Failed to start advertising as the advertise data to be broadcasted is too
-     * large.
-     */
-    public static final int ADVERTISE_FAILED_DATA_TOO_LARGE = 1;
-
-    /**
-     * Failed to start advertising because no advertising instance is available.
-     */
-    public static final int ADVERTISE_FAILED_TOO_MANY_ADVERTISERS = 2;
-
-    /**
-     * Failed to start advertising as the advertising is already started.
-     */
-    public static final int ADVERTISE_FAILED_ALREADY_STARTED = 3;
-
-    /**
-     * Operation failed due to an internal error.
-     */
-    public static final int ADVERTISE_FAILED_INTERNAL_ERROR = 4;
-
-    /**
-     * This feature is not supported on this platform.
-     */
-    public static final int ADVERTISE_FAILED_FEATURE_UNSUPPORTED = 5;
-
-    /**
-     * Callback triggered in response to {@link BluetoothLeAdvertiser#startAdvertisingSet}
-     * indicating result of the operation. If status is ADVERTISE_SUCCESS, then advertisingSet
-     * contains the started set and it is advertising. If error occurred, advertisingSet is
-     * null, and status will be set to proper error code.
-     *
-     * @param advertisingSet The advertising set that was started or null if error.
-     * @param txPower tx power that will be used for this set.
-     * @param status Status of the operation.
-     */
-    public void onAdvertisingSetStarted(AdvertisingSet advertisingSet, int txPower, int status) {
-    }
-
-    /**
-     * Callback triggered in response to {@link BluetoothLeAdvertiser#stopAdvertisingSet}
-     * indicating advertising set is stopped.
-     *
-     * @param advertisingSet The advertising set.
-     */
-    public void onAdvertisingSetStopped(AdvertisingSet advertisingSet) {
-    }
-
-    /**
-     * Callback triggered in response to {@link BluetoothLeAdvertiser#startAdvertisingSet}
-     * indicating result of the operation. If status is ADVERTISE_SUCCESS, then advertising set is
-     * advertising.
-     *
-     * @param advertisingSet The advertising set.
-     * @param status Status of the operation.
-     */
-    public void onAdvertisingEnabled(AdvertisingSet advertisingSet, boolean enable, int status) {
-    }
-
-    /**
-     * Callback triggered in response to {@link AdvertisingSet#setAdvertisingData} indicating
-     * result of the operation. If status is ADVERTISE_SUCCESS, then data was changed.
-     *
-     * @param advertisingSet The advertising set.
-     * @param status Status of the operation.
-     */
-    public void onAdvertisingDataSet(AdvertisingSet advertisingSet, int status) {
-    }
-
-    /**
-     * Callback triggered in response to {@link AdvertisingSet#setAdvertisingData} indicating
-     * result of the operation.
-     *
-     * @param advertisingSet The advertising set.
-     * @param status Status of the operation.
-     */
-    public void onScanResponseDataSet(AdvertisingSet advertisingSet, int status) {
-    }
-
-    /**
-     * Callback triggered in response to {@link AdvertisingSet#setAdvertisingParameters}
-     * indicating result of the operation.
-     *
-     * @param advertisingSet The advertising set.
-     * @param txPower tx power that will be used for this set.
-     * @param status Status of the operation.
-     */
-    public void onAdvertisingParametersUpdated(AdvertisingSet advertisingSet,
-            int txPower, int status) {
-    }
-
-    /**
-     * Callback triggered in response to {@link AdvertisingSet#setPeriodicAdvertisingParameters}
-     * indicating result of the operation.
-     *
-     * @param advertisingSet The advertising set.
-     * @param status Status of the operation.
-     */
-    public void onPeriodicAdvertisingParametersUpdated(AdvertisingSet advertisingSet, int status) {
-    }
-
-    /**
-     * Callback triggered in response to {@link AdvertisingSet#setPeriodicAdvertisingData}
-     * indicating result of the operation.
-     *
-     * @param advertisingSet The advertising set.
-     * @param status Status of the operation.
-     */
-    public void onPeriodicAdvertisingDataSet(AdvertisingSet advertisingSet,
-            int status) {
-    }
-
-    /**
-     * Callback triggered in response to {@link AdvertisingSet#setPeriodicAdvertisingEnabled}
-     * indicating result of the operation.
-     *
-     * @param advertisingSet The advertising set.
-     * @param status Status of the operation.
-     */
-    public void onPeriodicAdvertisingEnabled(AdvertisingSet advertisingSet, boolean enable,
-            int status) {
-    }
-
-    /**
-     * Callback triggered in response to {@link AdvertisingSet#getOwnAddress()}
-     * indicating result of the operation.
-     *
-     * @param advertisingSet The advertising set.
-     * @param addressType type of address.
-     * @param address advertising set bluetooth address.
-     * @hide
-     */
-    public void onOwnAddressRead(AdvertisingSet advertisingSet, int addressType, String address) {
-    }
-}
diff --git a/core/java/android/bluetooth/le/AdvertisingSetParameters.java b/core/java/android/bluetooth/le/AdvertisingSetParameters.java
deleted file mode 100644
index 5c8fae6..0000000
--- a/core/java/android/bluetooth/le/AdvertisingSetParameters.java
+++ /dev/null
@@ -1,513 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.le;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.SystemApi;
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothDevice;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * The {@link AdvertisingSetParameters} provide a way to adjust advertising
- * preferences for each
- * Bluetooth LE advertising set. Use {@link AdvertisingSetParameters.Builder} to
- * create an
- * instance of this class.
- */
-public final class AdvertisingSetParameters implements Parcelable {
-
-    /**
-     * Advertise on low frequency, around every 1000ms. This is the default and
-     * preferred advertising mode as it consumes the least power.
-     */
-    public static final int INTERVAL_HIGH = 1600;
-
-    /**
-     * Advertise on medium frequency, around every 250ms. This is balanced
-     * between advertising frequency and power consumption.
-     */
-    public static final int INTERVAL_MEDIUM = 400;
-
-    /**
-     * Perform high frequency, low latency advertising, around every 100ms. This
-     * has the highest power consumption and should not be used for continuous
-     * background advertising.
-     */
-    public static final int INTERVAL_LOW = 160;
-
-    /**
-     * Minimum value for advertising interval.
-     */
-    public static final int INTERVAL_MIN = 160;
-
-    /**
-     * Maximum value for advertising interval.
-     */
-    public static final int INTERVAL_MAX = 16777215;
-
-    /**
-     * Advertise using the lowest transmission (TX) power level. Low transmission
-     * power can be used to restrict the visibility range of advertising packets.
-     */
-    public static final int TX_POWER_ULTRA_LOW = -21;
-
-    /**
-     * Advertise using low TX power level.
-     */
-    public static final int TX_POWER_LOW = -15;
-
-    /**
-     * Advertise using medium TX power level.
-     */
-    public static final int TX_POWER_MEDIUM = -7;
-
-    /**
-     * Advertise using high TX power level. This corresponds to largest visibility
-     * range of the advertising packet.
-     */
-    public static final int TX_POWER_HIGH = 1;
-
-    /**
-     * Minimum value for TX power.
-     */
-    public static final int TX_POWER_MIN = -127;
-
-    /**
-     * Maximum value for TX power.
-     */
-    public static final int TX_POWER_MAX = 1;
-
-    /**
-     * The maximum limited advertisement duration as specified by the Bluetooth
-     * SIG
-     */
-    private static final int LIMITED_ADVERTISING_MAX_MILLIS = 180 * 1000;
-
-    /** @hide */
-    @IntDef(prefix = "ADDRESS_TYPE_", value = {
-        ADDRESS_TYPE_DEFAULT,
-        ADDRESS_TYPE_PUBLIC,
-        ADDRESS_TYPE_RANDOM
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface AddressTypeStatus {}
-
-    /**
-     * Advertise own address type that corresponds privacy settings of the device.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int ADDRESS_TYPE_DEFAULT = -1;
-
-    /**
-     * Advertise own public address type.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int ADDRESS_TYPE_PUBLIC = 0;
-
-    /**
-     * Generate and adverise own resolvable private address.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int ADDRESS_TYPE_RANDOM = 1;
-
-    private final boolean mIsLegacy;
-    private final boolean mIsAnonymous;
-    private final boolean mIncludeTxPower;
-    private final int mPrimaryPhy;
-    private final int mSecondaryPhy;
-    private final boolean mConnectable;
-    private final boolean mScannable;
-    private final int mInterval;
-    private final int mTxPowerLevel;
-    private final int mOwnAddressType;
-
-    private AdvertisingSetParameters(boolean connectable, boolean scannable, boolean isLegacy,
-            boolean isAnonymous, boolean includeTxPower,
-            int primaryPhy, int secondaryPhy,
-            int interval, int txPowerLevel, @AddressTypeStatus int ownAddressType) {
-        mConnectable = connectable;
-        mScannable = scannable;
-        mIsLegacy = isLegacy;
-        mIsAnonymous = isAnonymous;
-        mIncludeTxPower = includeTxPower;
-        mPrimaryPhy = primaryPhy;
-        mSecondaryPhy = secondaryPhy;
-        mInterval = interval;
-        mTxPowerLevel = txPowerLevel;
-        mOwnAddressType = ownAddressType;
-    }
-
-    private AdvertisingSetParameters(Parcel in) {
-        mConnectable = in.readInt() != 0;
-        mScannable = in.readInt() != 0;
-        mIsLegacy = in.readInt() != 0;
-        mIsAnonymous = in.readInt() != 0;
-        mIncludeTxPower = in.readInt() != 0;
-        mPrimaryPhy = in.readInt();
-        mSecondaryPhy = in.readInt();
-        mInterval = in.readInt();
-        mTxPowerLevel = in.readInt();
-        mOwnAddressType = in.readInt();
-    }
-
-    /**
-     * Returns whether the advertisement will be connectable.
-     */
-    public boolean isConnectable() {
-        return mConnectable;
-    }
-
-    /**
-     * Returns whether the advertisement will be scannable.
-     */
-    public boolean isScannable() {
-        return mScannable;
-    }
-
-    /**
-     * Returns whether the legacy advertisement will be used.
-     */
-    public boolean isLegacy() {
-        return mIsLegacy;
-    }
-
-    /**
-     * Returns whether the advertisement will be anonymous.
-     */
-    public boolean isAnonymous() {
-        return mIsAnonymous;
-    }
-
-    /**
-     * Returns whether the TX Power will be included.
-     */
-    public boolean includeTxPower() {
-        return mIncludeTxPower;
-    }
-
-    /**
-     * Returns the primary advertising phy.
-     */
-    public int getPrimaryPhy() {
-        return mPrimaryPhy;
-    }
-
-    /**
-     * Returns the secondary advertising phy.
-     */
-    public int getSecondaryPhy() {
-        return mSecondaryPhy;
-    }
-
-    /**
-     * Returns the advertising interval.
-     */
-    public int getInterval() {
-        return mInterval;
-    }
-
-    /**
-     * Returns the TX power level for advertising.
-     */
-    public int getTxPowerLevel() {
-        return mTxPowerLevel;
-    }
-
-    /**
-     * @return the own address type for advertising
-     *
-     * @hide
-     */
-    @SystemApi
-    public @AddressTypeStatus int getOwnAddressType() {
-        return mOwnAddressType;
-    }
-
-    @Override
-    public String toString() {
-        return "AdvertisingSetParameters [connectable=" + mConnectable
-                + ", isLegacy=" + mIsLegacy
-                + ", isAnonymous=" + mIsAnonymous
-                + ", includeTxPower=" + mIncludeTxPower
-                + ", primaryPhy=" + mPrimaryPhy
-                + ", secondaryPhy=" + mSecondaryPhy
-                + ", interval=" + mInterval
-                + ", txPowerLevel=" + mTxPowerLevel
-                + ", ownAddressType=" + mOwnAddressType + "]";
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(mConnectable ? 1 : 0);
-        dest.writeInt(mScannable ? 1 : 0);
-        dest.writeInt(mIsLegacy ? 1 : 0);
-        dest.writeInt(mIsAnonymous ? 1 : 0);
-        dest.writeInt(mIncludeTxPower ? 1 : 0);
-        dest.writeInt(mPrimaryPhy);
-        dest.writeInt(mSecondaryPhy);
-        dest.writeInt(mInterval);
-        dest.writeInt(mTxPowerLevel);
-        dest.writeInt(mOwnAddressType);
-    }
-
-    public static final @android.annotation.NonNull Parcelable.Creator<AdvertisingSetParameters> CREATOR =
-            new Creator<AdvertisingSetParameters>() {
-                @Override
-                public AdvertisingSetParameters[] newArray(int size) {
-                    return new AdvertisingSetParameters[size];
-                }
-
-                @Override
-                public AdvertisingSetParameters createFromParcel(Parcel in) {
-                    return new AdvertisingSetParameters(in);
-                }
-            };
-
-    /**
-     * Builder class for {@link AdvertisingSetParameters}.
-     */
-    public static final class Builder {
-        private boolean mConnectable = false;
-        private boolean mScannable = false;
-        private boolean mIsLegacy = false;
-        private boolean mIsAnonymous = false;
-        private boolean mIncludeTxPower = false;
-        private int mPrimaryPhy = BluetoothDevice.PHY_LE_1M;
-        private int mSecondaryPhy = BluetoothDevice.PHY_LE_1M;
-        private int mInterval = INTERVAL_LOW;
-        private int mTxPowerLevel = TX_POWER_MEDIUM;
-        private int mOwnAddressType = ADDRESS_TYPE_DEFAULT;
-
-        /**
-         * Set whether the advertisement type should be connectable or
-         * non-connectable.
-         * Legacy advertisements can be both connectable and scannable. Non-legacy
-         * advertisements can be only scannable or only connectable.
-         *
-         * @param connectable Controls whether the advertisement type will be connectable (true) or
-         * non-connectable (false).
-         */
-        public Builder setConnectable(boolean connectable) {
-            mConnectable = connectable;
-            return this;
-        }
-
-        /**
-         * Set whether the advertisement type should be scannable.
-         * Legacy advertisements can be both connectable and scannable. Non-legacy
-         * advertisements can be only scannable or only connectable.
-         *
-         * @param scannable Controls whether the advertisement type will be scannable (true) or
-         * non-scannable (false).
-         */
-        public Builder setScannable(boolean scannable) {
-            mScannable = scannable;
-            return this;
-        }
-
-        /**
-         * When set to true, advertising set will advertise 4.x Spec compliant
-         * advertisements.
-         *
-         * @param isLegacy whether legacy advertising mode should be used.
-         */
-        public Builder setLegacyMode(boolean isLegacy) {
-            mIsLegacy = isLegacy;
-            return this;
-        }
-
-        /**
-         * Set whether advertiser address should be ommited from all packets. If this
-         * mode is used, periodic advertising can't be enabled for this set.
-         *
-         * This is used only if legacy mode is not used.
-         *
-         * @param isAnonymous whether anonymous advertising should be used.
-         */
-        public Builder setAnonymous(boolean isAnonymous) {
-            mIsAnonymous = isAnonymous;
-            return this;
-        }
-
-        /**
-         * Set whether TX power should be included in the extended header.
-         *
-         * This is used only if legacy mode is not used.
-         *
-         * @param includeTxPower whether TX power should be included in extended header
-         */
-        public Builder setIncludeTxPower(boolean includeTxPower) {
-            mIncludeTxPower = includeTxPower;
-            return this;
-        }
-
-        /**
-         * Set the primary physical channel used for this advertising set.
-         *
-         * This is used only if legacy mode is not used.
-         *
-         * Use {@link BluetoothAdapter#isLeCodedPhySupported} to determine if LE Coded PHY is
-         * supported on this device.
-         *
-         * @param primaryPhy Primary advertising physical channel, can only be {@link
-         * BluetoothDevice#PHY_LE_1M} or {@link BluetoothDevice#PHY_LE_CODED}.
-         * @throws IllegalArgumentException If the primaryPhy is invalid.
-         */
-        public Builder setPrimaryPhy(int primaryPhy) {
-            if (primaryPhy != BluetoothDevice.PHY_LE_1M
-                    && primaryPhy != BluetoothDevice.PHY_LE_CODED) {
-                throw new IllegalArgumentException("bad primaryPhy " + primaryPhy);
-            }
-            mPrimaryPhy = primaryPhy;
-            return this;
-        }
-
-        /**
-         * Set the secondary physical channel used for this advertising set.
-         *
-         * This is used only if legacy mode is not used.
-         *
-         * Use {@link BluetoothAdapter#isLeCodedPhySupported} and
-         * {@link BluetoothAdapter#isLe2MPhySupported} to determine if LE Coded PHY or 2M PHY is
-         * supported on this device.
-         *
-         * @param secondaryPhy Secondary advertising physical channel, can only be one of {@link
-         * BluetoothDevice#PHY_LE_1M}, {@link BluetoothDevice#PHY_LE_2M} or {@link
-         * BluetoothDevice#PHY_LE_CODED}.
-         * @throws IllegalArgumentException If the secondaryPhy is invalid.
-         */
-        public Builder setSecondaryPhy(int secondaryPhy) {
-            if (secondaryPhy != BluetoothDevice.PHY_LE_1M
-                    && secondaryPhy != BluetoothDevice.PHY_LE_2M
-                    && secondaryPhy != BluetoothDevice.PHY_LE_CODED) {
-                throw new IllegalArgumentException("bad secondaryPhy " + secondaryPhy);
-            }
-            mSecondaryPhy = secondaryPhy;
-            return this;
-        }
-
-        /**
-         * Set advertising interval.
-         *
-         * @param interval Bluetooth LE Advertising interval, in 0.625ms unit. Valid range is from
-         * 160 (100ms) to 16777215 (10,485.759375 s). Recommended values are: {@link
-         * AdvertisingSetParameters#INTERVAL_LOW}, {@link AdvertisingSetParameters#INTERVAL_MEDIUM},
-         * or {@link AdvertisingSetParameters#INTERVAL_HIGH}.
-         * @throws IllegalArgumentException If the interval is invalid.
-         */
-        public Builder setInterval(int interval) {
-            if (interval < INTERVAL_MIN || interval > INTERVAL_MAX) {
-                throw new IllegalArgumentException("unknown interval " + interval);
-            }
-            mInterval = interval;
-            return this;
-        }
-
-        /**
-         * Set the transmission power level for the advertising.
-         *
-         * @param txPowerLevel Transmission power of Bluetooth LE Advertising, in dBm. The valid
-         * range is [-127, 1] Recommended values are:
-         * {@link AdvertisingSetParameters#TX_POWER_ULTRA_LOW},
-         * {@link AdvertisingSetParameters#TX_POWER_LOW},
-         * {@link AdvertisingSetParameters#TX_POWER_MEDIUM},
-         * or {@link AdvertisingSetParameters#TX_POWER_HIGH}.
-         * @throws IllegalArgumentException If the {@code txPowerLevel} is invalid.
-         */
-        public Builder setTxPowerLevel(int txPowerLevel) {
-            if (txPowerLevel < TX_POWER_MIN || txPowerLevel > TX_POWER_MAX) {
-                throw new IllegalArgumentException("unknown txPowerLevel " + txPowerLevel);
-            }
-            mTxPowerLevel = txPowerLevel;
-            return this;
-        }
-
-        /**
-         * Set own address type for advertising to control public or privacy mode. If used to set
-         * address type anything other than {@link AdvertisingSetParameters#ADDRESS_TYPE_DEFAULT},
-         * then it will require BLUETOOTH_PRIVILEGED permission and will be checked at the
-         * time of starting advertising.
-         *
-         * @throws IllegalArgumentException If the {@code ownAddressType} is invalid
-         *
-         * @hide
-         */
-        @SystemApi
-        public @NonNull Builder setOwnAddressType(@AddressTypeStatus int ownAddressType) {
-            if (ownAddressType < AdvertisingSetParameters.ADDRESS_TYPE_DEFAULT
-                    ||  ownAddressType > AdvertisingSetParameters.ADDRESS_TYPE_RANDOM) {
-                throw new IllegalArgumentException("unknown address type " + ownAddressType);
-            }
-            mOwnAddressType = ownAddressType;
-            return this;
-        }
-
-        /**
-         * Build the {@link AdvertisingSetParameters} object.
-         *
-         * @throws IllegalStateException if invalid combination of parameters is used.
-         */
-        public AdvertisingSetParameters build() {
-            if (mIsLegacy) {
-                if (mIsAnonymous) {
-                    throw new IllegalArgumentException("Legacy advertising can't be anonymous");
-                }
-
-                if (mConnectable && !mScannable) {
-                    throw new IllegalStateException(
-                            "Legacy advertisement can't be connectable and non-scannable");
-                }
-
-                if (mIncludeTxPower) {
-                    throw new IllegalStateException(
-                            "Legacy advertising can't include TX power level in header");
-                }
-            } else {
-                if (mConnectable && mScannable) {
-                    throw new IllegalStateException(
-                            "Advertising can't be both connectable and scannable");
-                }
-
-                if (mIsAnonymous && mConnectable) {
-                    throw new IllegalStateException(
-                            "Advertising can't be both connectable and anonymous");
-                }
-            }
-
-            return new AdvertisingSetParameters(mConnectable, mScannable, mIsLegacy, mIsAnonymous,
-                    mIncludeTxPower, mPrimaryPhy, mSecondaryPhy, mInterval, mTxPowerLevel,
-                    mOwnAddressType);
-        }
-    }
-}
diff --git a/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java b/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java
deleted file mode 100644
index 879dcee..0000000
--- a/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java
+++ /dev/null
@@ -1,756 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.le;
-
-import android.annotation.RequiresNoPermission;
-import android.annotation.RequiresPermission;
-import android.annotation.SuppressLint;
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothUuid;
-import android.bluetooth.IBluetoothGatt;
-import android.bluetooth.IBluetoothManager;
-import android.bluetooth.annotations.RequiresBluetoothAdvertisePermission;
-import android.bluetooth.annotations.RequiresLegacyBluetoothAdminPermission;
-import android.content.AttributionSource;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.ParcelUuid;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Objects;
-
-/**
- * This class provides a way to perform Bluetooth LE advertise operations, such as starting and
- * stopping advertising. An advertiser can broadcast up to 31 bytes of advertisement data
- * represented by {@link AdvertiseData}.
- * <p>
- * To get an instance of {@link BluetoothLeAdvertiser}, call the
- * {@link BluetoothAdapter#getBluetoothLeAdvertiser()} method.
- *
- * @see AdvertiseData
- */
-public final class BluetoothLeAdvertiser {
-
-    private static final String TAG = "BluetoothLeAdvertiser";
-
-    private static final int MAX_ADVERTISING_DATA_BYTES = 1650;
-    private static final int MAX_LEGACY_ADVERTISING_DATA_BYTES = 31;
-    // Each fields need one byte for field length and another byte for field type.
-    private static final int OVERHEAD_BYTES_PER_FIELD = 2;
-    // Flags field will be set by system.
-    private static final int FLAGS_FIELD_BYTES = 3;
-    private static final int MANUFACTURER_SPECIFIC_DATA_LENGTH = 2;
-
-    private final BluetoothAdapter mBluetoothAdapter;
-    private final IBluetoothManager mBluetoothManager;
-    private final AttributionSource mAttributionSource;
-
-    private final Handler mHandler;
-    private final Map<AdvertiseCallback, AdvertisingSetCallback>
-            mLegacyAdvertisers = new HashMap<>();
-    private final Map<AdvertisingSetCallback, IAdvertisingSetCallback>
-            mCallbackWrappers = Collections.synchronizedMap(new HashMap<>());
-    private final Map<Integer, AdvertisingSet>
-            mAdvertisingSets = Collections.synchronizedMap(new HashMap<>());
-
-    /**
-     * Use BluetoothAdapter.getLeAdvertiser() instead.
-     *
-     * @param bluetoothManager BluetoothManager that conducts overall Bluetooth Management
-     * @hide
-     */
-    public BluetoothLeAdvertiser(BluetoothAdapter bluetoothAdapter) {
-        mBluetoothAdapter = Objects.requireNonNull(bluetoothAdapter);
-        mBluetoothManager = mBluetoothAdapter.getBluetoothManager();
-        mAttributionSource = mBluetoothAdapter.getAttributionSource();
-        mHandler = new Handler(Looper.getMainLooper());
-    }
-
-    /**
-     * Start Bluetooth LE Advertising. On success, the {@code advertiseData} will be broadcasted.
-     * Returns immediately, the operation status is delivered through {@code callback}.
-     *
-     * @param settings Settings for Bluetooth LE advertising.
-     * @param advertiseData Advertisement data to be broadcasted.
-     * @param callback Callback for advertising status.
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothAdvertisePermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)
-    public void startAdvertising(AdvertiseSettings settings,
-            AdvertiseData advertiseData, final AdvertiseCallback callback) {
-        startAdvertising(settings, advertiseData, null, callback);
-    }
-
-    /**
-     * Start Bluetooth LE Advertising. The {@code advertiseData} will be broadcasted if the
-     * operation succeeds. The {@code scanResponse} is returned when a scanning device sends an
-     * active scan request. This method returns immediately, the operation status is delivered
-     * through {@code callback}.
-     *
-     * @param settings Settings for Bluetooth LE advertising.
-     * @param advertiseData Advertisement data to be advertised in advertisement packet.
-     * @param scanResponse Scan response associated with the advertisement data.
-     * @param callback Callback for advertising status.
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothAdvertisePermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)
-    public void startAdvertising(AdvertiseSettings settings,
-            AdvertiseData advertiseData, AdvertiseData scanResponse,
-            final AdvertiseCallback callback) {
-        synchronized (mLegacyAdvertisers) {
-            BluetoothLeUtils.checkAdapterStateOn(mBluetoothAdapter);
-            if (callback == null) {
-                throw new IllegalArgumentException("callback cannot be null");
-            }
-            boolean isConnectable = settings.isConnectable();
-            if (totalBytes(advertiseData, isConnectable) > MAX_LEGACY_ADVERTISING_DATA_BYTES
-                    || totalBytes(scanResponse, false) > MAX_LEGACY_ADVERTISING_DATA_BYTES) {
-                postStartFailure(callback, AdvertiseCallback.ADVERTISE_FAILED_DATA_TOO_LARGE);
-                return;
-            }
-            if (mLegacyAdvertisers.containsKey(callback)) {
-                postStartFailure(callback, AdvertiseCallback.ADVERTISE_FAILED_ALREADY_STARTED);
-                return;
-            }
-
-            AdvertisingSetParameters.Builder parameters = new AdvertisingSetParameters.Builder();
-            parameters.setLegacyMode(true);
-            parameters.setConnectable(isConnectable);
-            parameters.setScannable(true); // legacy advertisements we support are always scannable
-            parameters.setOwnAddressType(settings.getOwnAddressType());
-            if (settings.getMode() == AdvertiseSettings.ADVERTISE_MODE_LOW_POWER) {
-                parameters.setInterval(1600); // 1s
-            } else if (settings.getMode() == AdvertiseSettings.ADVERTISE_MODE_BALANCED) {
-                parameters.setInterval(400); // 250ms
-            } else if (settings.getMode() == AdvertiseSettings.ADVERTISE_MODE_LOW_LATENCY) {
-                parameters.setInterval(160); // 100ms
-            }
-
-            if (settings.getTxPowerLevel() == AdvertiseSettings.ADVERTISE_TX_POWER_ULTRA_LOW) {
-                parameters.setTxPowerLevel(-21);
-            } else if (settings.getTxPowerLevel() == AdvertiseSettings.ADVERTISE_TX_POWER_LOW) {
-                parameters.setTxPowerLevel(-15);
-            } else if (settings.getTxPowerLevel() == AdvertiseSettings.ADVERTISE_TX_POWER_MEDIUM) {
-                parameters.setTxPowerLevel(-7);
-            } else if (settings.getTxPowerLevel() == AdvertiseSettings.ADVERTISE_TX_POWER_HIGH) {
-                parameters.setTxPowerLevel(1);
-            }
-
-            int duration = 0;
-            int timeoutMillis = settings.getTimeout();
-            if (timeoutMillis > 0) {
-                duration = (timeoutMillis < 10) ? 1 : timeoutMillis / 10;
-            }
-
-            AdvertisingSetCallback wrapped = wrapOldCallback(callback, settings);
-            mLegacyAdvertisers.put(callback, wrapped);
-            startAdvertisingSet(parameters.build(), advertiseData, scanResponse, null, null,
-                    duration, 0, wrapped);
-        }
-    }
-
-    @SuppressLint({
-            "AndroidFrameworkBluetoothPermission",
-            "AndroidFrameworkRequiresPermission",
-    })
-    AdvertisingSetCallback wrapOldCallback(AdvertiseCallback callback, AdvertiseSettings settings) {
-        return new AdvertisingSetCallback() {
-            @Override
-            public void onAdvertisingSetStarted(AdvertisingSet advertisingSet, int txPower,
-                    int status) {
-                if (status != AdvertisingSetCallback.ADVERTISE_SUCCESS) {
-                    postStartFailure(callback, status);
-                    return;
-                }
-
-                postStartSuccess(callback, settings);
-            }
-
-            /* Legacy advertiser is disabled on timeout */
-            @Override
-            public void onAdvertisingEnabled(AdvertisingSet advertisingSet, boolean enabled,
-                    int status) {
-                if (enabled) {
-                    Log.e(TAG, "Legacy advertiser should be only disabled on timeout,"
-                            + " but was enabled!");
-                    return;
-                }
-
-                stopAdvertising(callback);
-            }
-
-        };
-    }
-
-    /**
-     * Stop Bluetooth LE advertising. The {@code callback} must be the same one use in
-     * {@link BluetoothLeAdvertiser#startAdvertising}.
-     *
-     * @param callback {@link AdvertiseCallback} identifies the advertising instance to stop.
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothAdvertisePermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)
-    public void stopAdvertising(final AdvertiseCallback callback) {
-        synchronized (mLegacyAdvertisers) {
-            if (callback == null) {
-                throw new IllegalArgumentException("callback cannot be null");
-            }
-            AdvertisingSetCallback wrapper = mLegacyAdvertisers.get(callback);
-            if (wrapper == null) return;
-
-            stopAdvertisingSet(wrapper);
-
-            mLegacyAdvertisers.remove(callback);
-        }
-    }
-
-    /**
-     * Creates a new advertising set. If operation succeed, device will start advertising. This
-     * method returns immediately, the operation status is delivered through
-     * {@code callback.onAdvertisingSetStarted()}.
-     * <p>
-     *
-     * @param parameters advertising set parameters.
-     * @param advertiseData Advertisement data to be broadcasted. Size must not exceed {@link
-     * BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the advertisement is connectable,
-     * three bytes will be added for flags.
-     * @param scanResponse Scan response associated with the advertisement data. Size must not
-     * exceed {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}.
-     * @param periodicParameters periodic advertisng parameters. If null, periodic advertising will
-     * not be started.
-     * @param periodicData Periodic advertising data. Size must not exceed {@link
-     * BluetoothAdapter#getLeMaximumAdvertisingDataLength}.
-     * @param callback Callback for advertising set.
-     * @throws IllegalArgumentException when any of the data parameter exceed the maximum allowable
-     * size, or unsupported advertising PHY is selected, or when attempt to use Periodic Advertising
-     * feature is made when it's not supported by the controller.
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothAdvertisePermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)
-    public void startAdvertisingSet(AdvertisingSetParameters parameters,
-            AdvertiseData advertiseData, AdvertiseData scanResponse,
-            PeriodicAdvertisingParameters periodicParameters,
-            AdvertiseData periodicData, AdvertisingSetCallback callback) {
-        startAdvertisingSet(parameters, advertiseData, scanResponse, periodicParameters,
-                periodicData, 0, 0, callback, new Handler(Looper.getMainLooper()));
-    }
-
-    /**
-     * Creates a new advertising set. If operation succeed, device will start advertising. This
-     * method returns immediately, the operation status is delivered through
-     * {@code callback.onAdvertisingSetStarted()}.
-     * <p>
-     *
-     * @param parameters advertising set parameters.
-     * @param advertiseData Advertisement data to be broadcasted. Size must not exceed {@link
-     * BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the advertisement is connectable,
-     * three bytes will be added for flags.
-     * @param scanResponse Scan response associated with the advertisement data. Size must not
-     * exceed {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}.
-     * @param periodicParameters periodic advertisng parameters. If null, periodic advertising will
-     * not be started.
-     * @param periodicData Periodic advertising data. Size must not exceed {@link
-     * BluetoothAdapter#getLeMaximumAdvertisingDataLength}.
-     * @param callback Callback for advertising set.
-     * @param handler thread upon which the callbacks will be invoked.
-     * @throws IllegalArgumentException when any of the data parameter exceed the maximum allowable
-     * size, or unsupported advertising PHY is selected, or when attempt to use Periodic Advertising
-     * feature is made when it's not supported by the controller.
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothAdvertisePermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)
-    public void startAdvertisingSet(AdvertisingSetParameters parameters,
-            AdvertiseData advertiseData, AdvertiseData scanResponse,
-            PeriodicAdvertisingParameters periodicParameters,
-            AdvertiseData periodicData, AdvertisingSetCallback callback,
-            Handler handler) {
-        startAdvertisingSet(parameters, advertiseData, scanResponse, periodicParameters,
-                periodicData, 0, 0, callback, handler);
-    }
-
-    /**
-     * Creates a new advertising set. If operation succeed, device will start advertising. This
-     * method returns immediately, the operation status is delivered through
-     * {@code callback.onAdvertisingSetStarted()}.
-     * <p>
-     *
-     * @param parameters advertising set parameters.
-     * @param advertiseData Advertisement data to be broadcasted. Size must not exceed {@link
-     * BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the advertisement is connectable,
-     * three bytes will be added for flags.
-     * @param scanResponse Scan response associated with the advertisement data. Size must not
-     * exceed {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}.
-     * @param periodicParameters periodic advertisng parameters. If null, periodic advertising will
-     * not be started.
-     * @param periodicData Periodic advertising data. Size must not exceed {@link
-     * BluetoothAdapter#getLeMaximumAdvertisingDataLength}.
-     * @param duration advertising duration, in 10ms unit. Valid range is from 1 (10ms) to 65535
-     * (655,350 ms). 0 means advertising should continue until stopped.
-     * @param maxExtendedAdvertisingEvents maximum number of extended advertising events the
-     * controller shall attempt to send prior to terminating the extended advertising, even if the
-     * duration has not expired. Valid range is from 1 to 255. 0 means no maximum.
-     * @param callback Callback for advertising set.
-     * @throws IllegalArgumentException when any of the data parameter exceed the maximum allowable
-     * size, or unsupported advertising PHY is selected, or when attempt to use Periodic Advertising
-     * feature is made when it's not supported by the controller.
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothAdvertisePermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)
-    public void startAdvertisingSet(AdvertisingSetParameters parameters,
-            AdvertiseData advertiseData, AdvertiseData scanResponse,
-            PeriodicAdvertisingParameters periodicParameters,
-            AdvertiseData periodicData, int duration,
-            int maxExtendedAdvertisingEvents,
-            AdvertisingSetCallback callback) {
-        startAdvertisingSet(parameters, advertiseData, scanResponse, periodicParameters,
-                periodicData, duration, maxExtendedAdvertisingEvents, callback,
-                new Handler(Looper.getMainLooper()));
-    }
-
-    /**
-     * Creates a new advertising set. If operation succeed, device will start advertising. This
-     * method returns immediately, the operation status is delivered through
-     * {@code callback.onAdvertisingSetStarted()}.
-     * <p>
-     *
-     * @param parameters Advertising set parameters.
-     * @param advertiseData Advertisement data to be broadcasted. Size must not exceed {@link
-     * BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the advertisement is connectable,
-     * three bytes will be added for flags.
-     * @param scanResponse Scan response associated with the advertisement data. Size must not
-     * exceed {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}
-     * @param periodicParameters Periodic advertisng parameters. If null, periodic advertising will
-     * not be started.
-     * @param periodicData Periodic advertising data. Size must not exceed {@link
-     * BluetoothAdapter#getLeMaximumAdvertisingDataLength}
-     * @param duration advertising duration, in 10ms unit. Valid range is from 1 (10ms) to 65535
-     * (655,350 ms). 0 means advertising should continue until stopped.
-     * @param maxExtendedAdvertisingEvents maximum number of extended advertising events the
-     * controller shall attempt to send prior to terminating the extended advertising, even if the
-     * duration has not expired. Valid range is from 1 to 255. 0 means no maximum.
-     * @param callback Callback for advertising set.
-     * @param handler Thread upon which the callbacks will be invoked.
-     * @throws IllegalArgumentException When any of the data parameter exceed the maximum allowable
-     * size, or unsupported advertising PHY is selected, or when attempt to use Periodic Advertising
-     * feature is made when it's not supported by the controller, or when
-     * maxExtendedAdvertisingEvents is used on a controller that doesn't support the LE Extended
-     * Advertising
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothAdvertisePermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)
-    public void startAdvertisingSet(AdvertisingSetParameters parameters,
-            AdvertiseData advertiseData, AdvertiseData scanResponse,
-            PeriodicAdvertisingParameters periodicParameters,
-            AdvertiseData periodicData, int duration,
-            int maxExtendedAdvertisingEvents, AdvertisingSetCallback callback,
-            Handler handler) {
-        BluetoothLeUtils.checkAdapterStateOn(mBluetoothAdapter);
-        if (callback == null) {
-            throw new IllegalArgumentException("callback cannot be null");
-        }
-
-        boolean isConnectable = parameters.isConnectable();
-        if (parameters.isLegacy()) {
-            if (totalBytes(advertiseData, isConnectable) > MAX_LEGACY_ADVERTISING_DATA_BYTES) {
-                throw new IllegalArgumentException("Legacy advertising data too big");
-            }
-
-            if (totalBytes(scanResponse, false) > MAX_LEGACY_ADVERTISING_DATA_BYTES) {
-                throw new IllegalArgumentException("Legacy scan response data too big");
-            }
-        } else {
-            boolean supportCodedPhy = mBluetoothAdapter.isLeCodedPhySupported();
-            boolean support2MPhy = mBluetoothAdapter.isLe2MPhySupported();
-            int pphy = parameters.getPrimaryPhy();
-            int sphy = parameters.getSecondaryPhy();
-            if (pphy == BluetoothDevice.PHY_LE_CODED && !supportCodedPhy) {
-                throw new IllegalArgumentException("Unsupported primary PHY selected");
-            }
-
-            if ((sphy == BluetoothDevice.PHY_LE_CODED && !supportCodedPhy)
-                    || (sphy == BluetoothDevice.PHY_LE_2M && !support2MPhy)) {
-                throw new IllegalArgumentException("Unsupported secondary PHY selected");
-            }
-
-            int maxData = mBluetoothAdapter.getLeMaximumAdvertisingDataLength();
-            if (totalBytes(advertiseData, isConnectable) > maxData) {
-                throw new IllegalArgumentException("Advertising data too big");
-            }
-
-            if (totalBytes(scanResponse, false) > maxData) {
-                throw new IllegalArgumentException("Scan response data too big");
-            }
-
-            if (totalBytes(periodicData, false) > maxData) {
-                throw new IllegalArgumentException("Periodic advertising data too big");
-            }
-
-            boolean supportPeriodic = mBluetoothAdapter.isLePeriodicAdvertisingSupported();
-            if (periodicParameters != null && !supportPeriodic) {
-                throw new IllegalArgumentException(
-                        "Controller does not support LE Periodic Advertising");
-            }
-        }
-
-        if (maxExtendedAdvertisingEvents < 0 || maxExtendedAdvertisingEvents > 255) {
-            throw new IllegalArgumentException(
-                    "maxExtendedAdvertisingEvents out of range: " + maxExtendedAdvertisingEvents);
-        }
-
-        if (maxExtendedAdvertisingEvents != 0
-                && !mBluetoothAdapter.isLePeriodicAdvertisingSupported()) {
-            throw new IllegalArgumentException(
-                    "Can't use maxExtendedAdvertisingEvents with controller that don't support "
-                            + "LE Extended Advertising");
-        }
-
-        if (duration < 0 || duration > 65535) {
-            throw new IllegalArgumentException("duration out of range: " + duration);
-        }
-
-        IBluetoothGatt gatt;
-        try {
-            gatt = mBluetoothManager.getBluetoothGatt();
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to get Bluetooth GATT - ", e);
-            postStartSetFailure(handler, callback,
-                    AdvertiseCallback.ADVERTISE_FAILED_INTERNAL_ERROR);
-            return;
-        }
-
-        if (gatt == null) {
-            Log.e(TAG, "Bluetooth GATT is null");
-            postStartSetFailure(handler, callback,
-                    AdvertiseCallback.ADVERTISE_FAILED_INTERNAL_ERROR);
-            return;
-        }
-
-        IAdvertisingSetCallback wrapped = wrap(callback, handler);
-        if (mCallbackWrappers.putIfAbsent(callback, wrapped) != null) {
-            throw new IllegalArgumentException(
-                    "callback instance already associated with advertising");
-        }
-
-        try {
-            gatt.startAdvertisingSet(parameters, advertiseData, scanResponse, periodicParameters,
-                    periodicData, duration, maxExtendedAdvertisingEvents, wrapped,
-                    mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to start advertising set - ", e);
-            postStartSetFailure(handler, callback,
-                    AdvertiseCallback.ADVERTISE_FAILED_INTERNAL_ERROR);
-            return;
-        }
-    }
-
-    /**
-     * Used to dispose of a {@link AdvertisingSet} object, obtained with {@link
-     * BluetoothLeAdvertiser#startAdvertisingSet}.
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothAdvertisePermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)
-    public void stopAdvertisingSet(AdvertisingSetCallback callback) {
-        if (callback == null) {
-            throw new IllegalArgumentException("callback cannot be null");
-        }
-
-        IAdvertisingSetCallback wrapped = mCallbackWrappers.remove(callback);
-        if (wrapped == null) {
-            return;
-        }
-
-        IBluetoothGatt gatt;
-        try {
-            gatt = mBluetoothManager.getBluetoothGatt();
-            gatt.stopAdvertisingSet(wrapped, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to stop advertising - ", e);
-        }
-    }
-
-    /**
-     * Cleans up advertisers. Should be called when bluetooth is down.
-     *
-     * @hide
-     */
-    @RequiresNoPermission
-    public void cleanup() {
-        mLegacyAdvertisers.clear();
-        mCallbackWrappers.clear();
-        mAdvertisingSets.clear();
-    }
-
-    // Compute the size of advertisement data or scan resp
-    @RequiresBluetoothAdvertisePermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)
-    private int totalBytes(AdvertiseData data, boolean isFlagsIncluded) {
-        if (data == null) return 0;
-        // Flags field is omitted if the advertising is not connectable.
-        int size = (isFlagsIncluded) ? FLAGS_FIELD_BYTES : 0;
-        if (data.getServiceUuids() != null) {
-            int num16BitUuids = 0;
-            int num32BitUuids = 0;
-            int num128BitUuids = 0;
-            for (ParcelUuid uuid : data.getServiceUuids()) {
-                if (BluetoothUuid.is16BitUuid(uuid)) {
-                    ++num16BitUuids;
-                } else if (BluetoothUuid.is32BitUuid(uuid)) {
-                    ++num32BitUuids;
-                } else {
-                    ++num128BitUuids;
-                }
-            }
-            // 16 bit service uuids are grouped into one field when doing advertising.
-            if (num16BitUuids != 0) {
-                size += OVERHEAD_BYTES_PER_FIELD + num16BitUuids * BluetoothUuid.UUID_BYTES_16_BIT;
-            }
-            // 32 bit service uuids are grouped into one field when doing advertising.
-            if (num32BitUuids != 0) {
-                size += OVERHEAD_BYTES_PER_FIELD + num32BitUuids * BluetoothUuid.UUID_BYTES_32_BIT;
-            }
-            // 128 bit service uuids are grouped into one field when doing advertising.
-            if (num128BitUuids != 0) {
-                size += OVERHEAD_BYTES_PER_FIELD
-                        + num128BitUuids * BluetoothUuid.UUID_BYTES_128_BIT;
-            }
-        }
-        if (data.getServiceSolicitationUuids() != null) {
-            int num16BitUuids = 0;
-            int num32BitUuids = 0;
-            int num128BitUuids = 0;
-            for (ParcelUuid uuid : data.getServiceSolicitationUuids()) {
-                if (BluetoothUuid.is16BitUuid(uuid)) {
-                    ++num16BitUuids;
-                } else if (BluetoothUuid.is32BitUuid(uuid)) {
-                    ++num32BitUuids;
-                } else {
-                    ++num128BitUuids;
-                }
-            }
-            // 16 bit service uuids are grouped into one field when doing advertising.
-            if (num16BitUuids != 0) {
-                size += OVERHEAD_BYTES_PER_FIELD + num16BitUuids * BluetoothUuid.UUID_BYTES_16_BIT;
-            }
-            // 32 bit service uuids are grouped into one field when doing advertising.
-            if (num32BitUuids != 0) {
-                size += OVERHEAD_BYTES_PER_FIELD + num32BitUuids * BluetoothUuid.UUID_BYTES_32_BIT;
-            }
-            // 128 bit service uuids are grouped into one field when doing advertising.
-            if (num128BitUuids != 0) {
-                size += OVERHEAD_BYTES_PER_FIELD
-                        + num128BitUuids * BluetoothUuid.UUID_BYTES_128_BIT;
-            }
-        }
-        for (TransportDiscoveryData transportDiscoveryData : data.getTransportDiscoveryData()) {
-            size += OVERHEAD_BYTES_PER_FIELD + transportDiscoveryData.totalBytes();
-        }
-        for (ParcelUuid uuid : data.getServiceData().keySet()) {
-            int uuidLen = BluetoothUuid.uuidToBytes(uuid).length;
-            size += OVERHEAD_BYTES_PER_FIELD + uuidLen
-                    + byteLength(data.getServiceData().get(uuid));
-        }
-        for (int i = 0; i < data.getManufacturerSpecificData().size(); ++i) {
-            size += OVERHEAD_BYTES_PER_FIELD + MANUFACTURER_SPECIFIC_DATA_LENGTH
-                    + byteLength(data.getManufacturerSpecificData().valueAt(i));
-        }
-        if (data.getIncludeTxPowerLevel()) {
-            size += OVERHEAD_BYTES_PER_FIELD + 1; // tx power level value is one byte.
-        }
-        if (data.getIncludeDeviceName()) {
-            final int length = mBluetoothAdapter.getNameLengthForAdvertise();
-            if (length >= 0) {
-                size += OVERHEAD_BYTES_PER_FIELD + length;
-            }
-        }
-        return size;
-    }
-
-    private int byteLength(byte[] array) {
-        return array == null ? 0 : array.length;
-    }
-
-    @SuppressLint("AndroidFrameworkBluetoothPermission")
-    IAdvertisingSetCallback wrap(AdvertisingSetCallback callback, Handler handler) {
-        return new IAdvertisingSetCallback.Stub() {
-            @Override
-            public void onAdvertisingSetStarted(int advertiserId, int txPower, int status) {
-                handler.post(new Runnable() {
-                    @Override
-                    public void run() {
-                        if (status != AdvertisingSetCallback.ADVERTISE_SUCCESS) {
-                            callback.onAdvertisingSetStarted(null, 0, status);
-                            mCallbackWrappers.remove(callback);
-                            return;
-                        }
-
-                        AdvertisingSet advertisingSet = new AdvertisingSet(
-                                advertiserId, mBluetoothManager, mAttributionSource);
-                        mAdvertisingSets.put(advertiserId, advertisingSet);
-                        callback.onAdvertisingSetStarted(advertisingSet, txPower, status);
-                    }
-                });
-            }
-
-            @Override
-            public void onOwnAddressRead(int advertiserId, int addressType, String address) {
-                handler.post(new Runnable() {
-                    @Override
-                    public void run() {
-                        AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId);
-                        callback.onOwnAddressRead(advertisingSet, addressType, address);
-                    }
-                });
-            }
-
-            @Override
-            public void onAdvertisingSetStopped(int advertiserId) {
-                handler.post(new Runnable() {
-                    @Override
-                    public void run() {
-                        AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId);
-                        callback.onAdvertisingSetStopped(advertisingSet);
-                        mAdvertisingSets.remove(advertiserId);
-                        mCallbackWrappers.remove(callback);
-                    }
-                });
-            }
-
-            @Override
-            public void onAdvertisingEnabled(int advertiserId, boolean enabled, int status) {
-                handler.post(new Runnable() {
-                    @Override
-                    public void run() {
-                        AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId);
-                        callback.onAdvertisingEnabled(advertisingSet, enabled, status);
-                    }
-                });
-            }
-
-            @Override
-            public void onAdvertisingDataSet(int advertiserId, int status) {
-                handler.post(new Runnable() {
-                    @Override
-                    public void run() {
-                        AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId);
-                        callback.onAdvertisingDataSet(advertisingSet, status);
-                    }
-                });
-            }
-
-            @Override
-            public void onScanResponseDataSet(int advertiserId, int status) {
-                handler.post(new Runnable() {
-                    @Override
-                    public void run() {
-                        AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId);
-                        callback.onScanResponseDataSet(advertisingSet, status);
-                    }
-                });
-            }
-
-            @Override
-            public void onAdvertisingParametersUpdated(int advertiserId, int txPower, int status) {
-                handler.post(new Runnable() {
-                    @Override
-                    public void run() {
-                        AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId);
-                        callback.onAdvertisingParametersUpdated(advertisingSet, txPower, status);
-                    }
-                });
-            }
-
-            @Override
-            public void onPeriodicAdvertisingParametersUpdated(int advertiserId, int status) {
-                handler.post(new Runnable() {
-                    @Override
-                    public void run() {
-                        AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId);
-                        callback.onPeriodicAdvertisingParametersUpdated(advertisingSet, status);
-                    }
-                });
-            }
-
-            @Override
-            public void onPeriodicAdvertisingDataSet(int advertiserId, int status) {
-                handler.post(new Runnable() {
-                    @Override
-                    public void run() {
-                        AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId);
-                        callback.onPeriodicAdvertisingDataSet(advertisingSet, status);
-                    }
-                });
-            }
-
-            @Override
-            public void onPeriodicAdvertisingEnabled(int advertiserId, boolean enable, int status) {
-                handler.post(new Runnable() {
-                    @Override
-                    public void run() {
-                        AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId);
-                        callback.onPeriodicAdvertisingEnabled(advertisingSet, enable, status);
-                    }
-                });
-            }
-        };
-    }
-
-    @SuppressLint("AndroidFrameworkBluetoothPermission")
-    private void postStartSetFailure(Handler handler, final AdvertisingSetCallback callback,
-            final int error) {
-        handler.post(new Runnable() {
-            @Override
-            public void run() {
-                callback.onAdvertisingSetStarted(null, 0, error);
-            }
-        });
-    }
-
-    @SuppressLint("AndroidFrameworkBluetoothPermission")
-    private void postStartFailure(final AdvertiseCallback callback, final int error) {
-        mHandler.post(new Runnable() {
-            @Override
-            public void run() {
-                callback.onStartFailure(error);
-            }
-        });
-    }
-
-    @SuppressLint("AndroidFrameworkBluetoothPermission")
-    private void postStartSuccess(final AdvertiseCallback callback,
-            final AdvertiseSettings settings) {
-        mHandler.post(new Runnable() {
-
-            @Override
-            public void run() {
-                callback.onStartSuccess(settings);
-            }
-        });
-    }
-}
diff --git a/core/java/android/bluetooth/le/BluetoothLeScanner.java b/core/java/android/bluetooth/le/BluetoothLeScanner.java
deleted file mode 100644
index 540e5a7..0000000
--- a/core/java/android/bluetooth/le/BluetoothLeScanner.java
+++ /dev/null
@@ -1,658 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package android.bluetooth.le;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.RequiresNoPermission;
-import android.annotation.RequiresPermission;
-import android.annotation.SuppressLint;
-import android.annotation.SystemApi;
-import android.app.PendingIntent;
-import android.bluetooth.Attributable;
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothGatt;
-import android.bluetooth.IBluetoothGatt;
-import android.bluetooth.IBluetoothManager;
-import android.bluetooth.annotations.RequiresBluetoothLocationPermission;
-import android.bluetooth.annotations.RequiresBluetoothScanPermission;
-import android.bluetooth.annotations.RequiresLegacyBluetoothAdminPermission;
-import android.content.AttributionSource;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.RemoteException;
-import android.os.WorkSource;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-
-/**
- * This class provides methods to perform scan related operations for Bluetooth LE devices. An
- * application can scan for a particular type of Bluetooth LE devices using {@link ScanFilter}. It
- * can also request different types of callbacks for delivering the result.
- * <p>
- * Use {@link BluetoothAdapter#getBluetoothLeScanner()} to get an instance of
- * {@link BluetoothLeScanner}.
- *
- * @see ScanFilter
- */
-public final class BluetoothLeScanner {
-
-    private static final String TAG = "BluetoothLeScanner";
-    private static final boolean DBG = true;
-    private static final boolean VDBG = false;
-
-    /**
-     * Extra containing a list of ScanResults. It can have one or more results if there was no
-     * error. In case of error, {@link #EXTRA_ERROR_CODE} will contain the error code and this
-     * extra will not be available.
-     */
-    public static final String EXTRA_LIST_SCAN_RESULT =
-            "android.bluetooth.le.extra.LIST_SCAN_RESULT";
-
-    /**
-     * Optional extra indicating the error code, if any. The error code will be one of the
-     * SCAN_FAILED_* codes in {@link ScanCallback}.
-     */
-    public static final String EXTRA_ERROR_CODE = "android.bluetooth.le.extra.ERROR_CODE";
-
-    /**
-     * Optional extra indicating the callback type, which will be one of
-     * CALLBACK_TYPE_* constants in {@link ScanSettings}.
-     *
-     * @see ScanCallback#onScanResult(int, ScanResult)
-     */
-    public static final String EXTRA_CALLBACK_TYPE = "android.bluetooth.le.extra.CALLBACK_TYPE";
-
-    private final BluetoothAdapter mBluetoothAdapter;
-    private final IBluetoothManager mBluetoothManager;
-    private final AttributionSource mAttributionSource;
-
-    private final Handler mHandler;
-    private final Map<ScanCallback, BleScanCallbackWrapper> mLeScanClients;
-
-    /**
-     * Use {@link BluetoothAdapter#getBluetoothLeScanner()} instead.
-     *
-     * @param bluetoothManager BluetoothManager that conducts overall Bluetooth Management.
-     * @param opPackageName The opPackageName of the context this object was created from
-     * @param featureId  The featureId of the context this object was created from
-     * @hide
-     */
-    public BluetoothLeScanner(BluetoothAdapter bluetoothAdapter) {
-        mBluetoothAdapter = Objects.requireNonNull(bluetoothAdapter);
-        mBluetoothManager = mBluetoothAdapter.getBluetoothManager();
-        mAttributionSource = mBluetoothAdapter.getAttributionSource();
-        mHandler = new Handler(Looper.getMainLooper());
-        mLeScanClients = new HashMap<ScanCallback, BleScanCallbackWrapper>();
-    }
-
-    /**
-     * Start Bluetooth LE scan with default parameters and no filters. The scan results will be
-     * delivered through {@code callback}. For unfiltered scans, scanning is stopped on screen
-     * off to save power. Scanning is resumed when screen is turned on again. To avoid this, use
-     * {@link #startScan(List, ScanSettings, ScanCallback)} with desired {@link ScanFilter}.
-     * <p>
-     * An app must have
-     * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION} permission
-     * in order to get results. An App targeting Android Q or later must have
-     * {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} permission
-     * in order to get results.
-     *
-     * @param callback Callback used to deliver scan results.
-     * @throws IllegalArgumentException If {@code callback} is null.
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothScanPermission
-    @RequiresBluetoothLocationPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
-    public void startScan(final ScanCallback callback) {
-        startScan(null, new ScanSettings.Builder().build(), callback);
-    }
-
-    /**
-     * Start Bluetooth LE scan. The scan results will be delivered through {@code callback}.
-     * For unfiltered scans, scanning is stopped on screen off to save power. Scanning is
-     * resumed when screen is turned on again. To avoid this, do filetered scanning by
-     * using proper {@link ScanFilter}.
-     * <p>
-     * An app must have
-     * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION} permission
-     * in order to get results. An App targeting Android Q or later must have
-     * {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} permission
-     * in order to get results.
-     *
-     * @param filters {@link ScanFilter}s for finding exact BLE devices.
-     * @param settings Settings for the scan.
-     * @param callback Callback used to deliver scan results.
-     * @throws IllegalArgumentException If {@code settings} or {@code callback} is null.
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothScanPermission
-    @RequiresBluetoothLocationPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
-    public void startScan(List<ScanFilter> filters, ScanSettings settings,
-            final ScanCallback callback) {
-        startScan(filters, settings, null, callback, /*callbackIntent=*/ null);
-    }
-
-    /**
-     * Start Bluetooth LE scan using a {@link PendingIntent}. The scan results will be delivered via
-     * the PendingIntent. Use this method of scanning if your process is not always running and it
-     * should be started when scan results are available.
-     * <p>
-     * An app must have
-     * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION} permission
-     * in order to get results. An App targeting Android Q or later must have
-     * {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} permission
-     * in order to get results.
-     * <p>
-     * When the PendingIntent is delivered, the Intent passed to the receiver or activity
-     * will contain one or more of the extras {@link #EXTRA_CALLBACK_TYPE},
-     * {@link #EXTRA_ERROR_CODE} and {@link #EXTRA_LIST_SCAN_RESULT} to indicate the result of
-     * the scan.
-     *
-     * @param filters Optional list of ScanFilters for finding exact BLE devices.
-     * @param settings Optional settings for the scan.
-     * @param callbackIntent The PendingIntent to deliver the result to.
-     * @return Returns 0 for success or an error code from {@link ScanCallback} if the scan request
-     * could not be sent.
-     * @see #stopScan(PendingIntent)
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothScanPermission
-    @RequiresBluetoothLocationPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
-    public int startScan(@Nullable List<ScanFilter> filters, @Nullable ScanSettings settings,
-            @NonNull PendingIntent callbackIntent) {
-        return startScan(filters,
-                settings != null ? settings : new ScanSettings.Builder().build(),
-                null, null, callbackIntent);
-    }
-
-    /**
-     * Start Bluetooth LE scan. Same as {@link #startScan(ScanCallback)} but allows the caller to
-     * specify on behalf of which application(s) the work is being done.
-     *
-     * @param workSource {@link WorkSource} identifying the application(s) for which to blame for
-     * the scan.
-     * @param callback Callback used to deliver scan results.
-     * @hide
-     */
-    @SystemApi
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothScanPermission
-    @RequiresBluetoothLocationPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_SCAN,
-            android.Manifest.permission.UPDATE_DEVICE_STATS
-    })
-    public void startScanFromSource(final WorkSource workSource, final ScanCallback callback) {
-        startScanFromSource(null, new ScanSettings.Builder().build(), workSource, callback);
-    }
-
-    /**
-     * Start Bluetooth LE scan. Same as {@link #startScan(List, ScanSettings, ScanCallback)} but
-     * allows the caller to specify on behalf of which application(s) the work is being done.
-     *
-     * @param filters {@link ScanFilter}s for finding exact BLE devices.
-     * @param settings Settings for the scan.
-     * @param workSource {@link WorkSource} identifying the application(s) for which to blame for
-     * the scan.
-     * @param callback Callback used to deliver scan results.
-     * @hide
-     */
-    @SystemApi
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothScanPermission
-    @RequiresBluetoothLocationPermission
-    @RequiresPermission(allOf = {
-            android.Manifest.permission.BLUETOOTH_SCAN,
-            android.Manifest.permission.UPDATE_DEVICE_STATS
-    })
-    @SuppressLint("AndroidFrameworkRequiresPermission")
-    public void startScanFromSource(List<ScanFilter> filters, ScanSettings settings,
-            final WorkSource workSource, final ScanCallback callback) {
-        startScan(filters, settings, workSource, callback, null);
-    }
-
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
-    private int startScan(List<ScanFilter> filters, ScanSettings settings,
-            final WorkSource workSource, final ScanCallback callback,
-            final PendingIntent callbackIntent) {
-        BluetoothLeUtils.checkAdapterStateOn(mBluetoothAdapter);
-        if (callback == null && callbackIntent == null) {
-            throw new IllegalArgumentException("callback is null");
-        }
-        if (settings == null) {
-            throw new IllegalArgumentException("settings is null");
-        }
-        synchronized (mLeScanClients) {
-            if (callback != null && mLeScanClients.containsKey(callback)) {
-                return postCallbackErrorOrReturn(callback,
-                            ScanCallback.SCAN_FAILED_ALREADY_STARTED);
-            }
-            IBluetoothGatt gatt;
-            try {
-                gatt = mBluetoothManager.getBluetoothGatt();
-            } catch (RemoteException e) {
-                gatt = null;
-            }
-            if (gatt == null) {
-                return postCallbackErrorOrReturn(callback, ScanCallback.SCAN_FAILED_INTERNAL_ERROR);
-            }
-            if (!isSettingsConfigAllowedForScan(settings)) {
-                return postCallbackErrorOrReturn(callback,
-                        ScanCallback.SCAN_FAILED_FEATURE_UNSUPPORTED);
-            }
-            if (!isHardwareResourcesAvailableForScan(settings)) {
-                return postCallbackErrorOrReturn(callback,
-                        ScanCallback.SCAN_FAILED_OUT_OF_HARDWARE_RESOURCES);
-            }
-            if (!isSettingsAndFilterComboAllowed(settings, filters)) {
-                return postCallbackErrorOrReturn(callback,
-                        ScanCallback.SCAN_FAILED_FEATURE_UNSUPPORTED);
-            }
-            if (callback != null) {
-                BleScanCallbackWrapper wrapper = new BleScanCallbackWrapper(gatt, filters,
-                        settings, workSource, callback);
-                wrapper.startRegistration();
-            } else {
-                try {
-                    gatt.startScanForIntent(callbackIntent, settings, filters,
-                            mAttributionSource);
-                } catch (RemoteException e) {
-                    return ScanCallback.SCAN_FAILED_INTERNAL_ERROR;
-                }
-            }
-        }
-        return ScanCallback.NO_ERROR;
-    }
-
-    /**
-     * Stops an ongoing Bluetooth LE scan.
-     *
-     * @param callback
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothScanPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
-    public void stopScan(ScanCallback callback) {
-        BluetoothLeUtils.checkAdapterStateOn(mBluetoothAdapter);
-        synchronized (mLeScanClients) {
-            BleScanCallbackWrapper wrapper = mLeScanClients.remove(callback);
-            if (wrapper == null) {
-                if (DBG) Log.d(TAG, "could not find callback wrapper");
-                return;
-            }
-            wrapper.stopLeScan();
-        }
-    }
-
-    /**
-     * Stops an ongoing Bluetooth LE scan started using a PendingIntent. When creating the
-     * PendingIntent parameter, please do not use the FLAG_CANCEL_CURRENT flag. Otherwise, the stop
-     * scan may have no effect.
-     *
-     * @param callbackIntent The PendingIntent that was used to start the scan.
-     * @see #startScan(List, ScanSettings, PendingIntent)
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothScanPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
-    public void stopScan(PendingIntent callbackIntent) {
-        BluetoothLeUtils.checkAdapterStateOn(mBluetoothAdapter);
-        IBluetoothGatt gatt;
-        try {
-            gatt = mBluetoothManager.getBluetoothGatt();
-            gatt.stopScanForIntent(callbackIntent, mAttributionSource);
-        } catch (RemoteException e) {
-        }
-    }
-
-    /**
-     * Flush pending batch scan results stored in Bluetooth controller. This will return Bluetooth
-     * LE scan results batched on bluetooth controller. Returns immediately, batch scan results data
-     * will be delivered through the {@code callback}.
-     *
-     * @param callback Callback of the Bluetooth LE Scan, it has to be the same instance as the one
-     * used to start scan.
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothScanPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
-    public void flushPendingScanResults(ScanCallback callback) {
-        BluetoothLeUtils.checkAdapterStateOn(mBluetoothAdapter);
-        if (callback == null) {
-            throw new IllegalArgumentException("callback cannot be null!");
-        }
-        synchronized (mLeScanClients) {
-            BleScanCallbackWrapper wrapper = mLeScanClients.get(callback);
-            if (wrapper == null) {
-                return;
-            }
-            wrapper.flushPendingBatchResults();
-        }
-    }
-
-    /**
-     * Start truncated scan.
-     *
-     * @deprecated this is not used anywhere
-     *
-     * @hide
-     */
-    @Deprecated
-    @SystemApi
-    @RequiresBluetoothScanPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
-    public void startTruncatedScan(List<TruncatedFilter> truncatedFilters, ScanSettings settings,
-            final ScanCallback callback) {
-        int filterSize = truncatedFilters.size();
-        List<ScanFilter> scanFilters = new ArrayList<ScanFilter>(filterSize);
-        for (TruncatedFilter filter : truncatedFilters) {
-            scanFilters.add(filter.getFilter());
-        }
-        startScan(scanFilters, settings, null, callback, null);
-    }
-
-    /**
-     * Cleans up scan clients. Should be called when bluetooth is down.
-     *
-     * @hide
-     */
-    @RequiresNoPermission
-    public void cleanup() {
-        mLeScanClients.clear();
-    }
-
-    /**
-     * Bluetooth GATT interface callbacks
-     */
-    @SuppressLint("AndroidFrameworkRequiresPermission")
-    private class BleScanCallbackWrapper extends IScannerCallback.Stub {
-        private static final int REGISTRATION_CALLBACK_TIMEOUT_MILLIS = 2000;
-
-        private final ScanCallback mScanCallback;
-        private final List<ScanFilter> mFilters;
-        private final WorkSource mWorkSource;
-        private ScanSettings mSettings;
-        private IBluetoothGatt mBluetoothGatt;
-
-        // mLeHandle 0: not registered
-        // -2: registration failed because app is scanning to frequently
-        // -1: scan stopped or registration failed
-        // > 0: registered and scan started
-        private int mScannerId;
-
-        public BleScanCallbackWrapper(IBluetoothGatt bluetoothGatt,
-                List<ScanFilter> filters, ScanSettings settings,
-                WorkSource workSource, ScanCallback scanCallback) {
-            mBluetoothGatt = bluetoothGatt;
-            mFilters = filters;
-            mSettings = settings;
-            mWorkSource = workSource;
-            mScanCallback = scanCallback;
-            mScannerId = 0;
-        }
-
-        public void startRegistration() {
-            synchronized (this) {
-                // Scan stopped.
-                if (mScannerId == -1 || mScannerId == -2) return;
-                try {
-                    mBluetoothGatt.registerScanner(this, mWorkSource, mAttributionSource);
-                    wait(REGISTRATION_CALLBACK_TIMEOUT_MILLIS);
-                } catch (InterruptedException | RemoteException e) {
-                    Log.e(TAG, "application registeration exception", e);
-                    postCallbackError(mScanCallback, ScanCallback.SCAN_FAILED_INTERNAL_ERROR);
-                }
-                if (mScannerId > 0) {
-                    mLeScanClients.put(mScanCallback, this);
-                } else {
-                    // Registration timed out or got exception, reset RscannerId to -1 so no
-                    // subsequent operations can proceed.
-                    if (mScannerId == 0) mScannerId = -1;
-
-                    // If scanning too frequently, don't report anything to the app.
-                    if (mScannerId == -2) return;
-
-                    postCallbackError(mScanCallback,
-                            ScanCallback.SCAN_FAILED_APPLICATION_REGISTRATION_FAILED);
-                }
-            }
-        }
-
-        @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
-        public void stopLeScan() {
-            synchronized (this) {
-                if (mScannerId <= 0) {
-                    Log.e(TAG, "Error state, mLeHandle: " + mScannerId);
-                    return;
-                }
-                try {
-                    mBluetoothGatt.stopScan(mScannerId, mAttributionSource);
-                    mBluetoothGatt.unregisterScanner(mScannerId, mAttributionSource);
-                } catch (RemoteException e) {
-                    Log.e(TAG, "Failed to stop scan and unregister", e);
-                }
-                mScannerId = -1;
-            }
-        }
-
-        @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
-        void flushPendingBatchResults() {
-            synchronized (this) {
-                if (mScannerId <= 0) {
-                    Log.e(TAG, "Error state, mLeHandle: " + mScannerId);
-                    return;
-                }
-                try {
-                    mBluetoothGatt.flushPendingBatchResults(mScannerId, mAttributionSource);
-                } catch (RemoteException e) {
-                    Log.e(TAG, "Failed to get pending scan results", e);
-                }
-            }
-        }
-
-        /**
-         * Application interface registered - app is ready to go
-         */
-        @Override
-        public void onScannerRegistered(int status, int scannerId) {
-            Log.d(TAG, "onScannerRegistered() - status=" + status
-                    + " scannerId=" + scannerId + " mScannerId=" + mScannerId);
-            synchronized (this) {
-                if (status == BluetoothGatt.GATT_SUCCESS) {
-                    try {
-                        if (mScannerId == -1) {
-                            // Registration succeeds after timeout, unregister scanner.
-                            mBluetoothGatt.unregisterScanner(scannerId, mAttributionSource);
-                        } else {
-                            mScannerId = scannerId;
-                            mBluetoothGatt.startScan(mScannerId, mSettings, mFilters,
-                                    mAttributionSource);
-                        }
-                    } catch (RemoteException e) {
-                        Log.e(TAG, "fail to start le scan: " + e);
-                        mScannerId = -1;
-                    }
-                } else if (status == ScanCallback.SCAN_FAILED_SCANNING_TOO_FREQUENTLY) {
-                    // applicaiton was scanning too frequently
-                    mScannerId = -2;
-                } else {
-                    // registration failed
-                    mScannerId = -1;
-                }
-                notifyAll();
-            }
-        }
-
-        /**
-         * Callback reporting an LE scan result.
-         *
-         * @hide
-         */
-        @Override
-        public void onScanResult(final ScanResult scanResult) {
-            Attributable.setAttributionSource(scanResult, mAttributionSource);
-            if (Log.isLoggable(TAG, Log.DEBUG)) {
-                Log.d(TAG, "onScanResult() - mScannerId=" + mScannerId);
-            }
-            if (VDBG) Log.d(TAG, "onScanResult() - " + scanResult.toString());
-
-            // Check null in case the scan has been stopped
-            synchronized (this) {
-                if (mScannerId <= 0) {
-                    if (Log.isLoggable(TAG, Log.DEBUG)) {
-                        Log.d(TAG, "Ignoring result as scan stopped.");
-                    }
-                    return;
-                };
-            }
-            Handler handler = new Handler(Looper.getMainLooper());
-            handler.post(new Runnable() {
-                @Override
-                public void run() {
-                    if (Log.isLoggable(TAG, Log.DEBUG)) {
-                        Log.d(TAG, "onScanResult() - handler run");
-                    }
-                    mScanCallback.onScanResult(ScanSettings.CALLBACK_TYPE_ALL_MATCHES, scanResult);
-                }
-            });
-        }
-
-        @Override
-        public void onBatchScanResults(final List<ScanResult> results) {
-            Attributable.setAttributionSource(results, mAttributionSource);
-            Handler handler = new Handler(Looper.getMainLooper());
-            handler.post(new Runnable() {
-                @Override
-                public void run() {
-                    mScanCallback.onBatchScanResults(results);
-                }
-            });
-        }
-
-        @Override
-        public void onFoundOrLost(final boolean onFound, final ScanResult scanResult) {
-            Attributable.setAttributionSource(scanResult, mAttributionSource);
-            if (VDBG) {
-                Log.d(TAG, "onFoundOrLost() - onFound = " + onFound + " " + scanResult.toString());
-            }
-
-            // Check null in case the scan has been stopped
-            synchronized (this) {
-                if (mScannerId <= 0) {
-                    return;
-                }
-            }
-            Handler handler = new Handler(Looper.getMainLooper());
-            handler.post(new Runnable() {
-                @Override
-                public void run() {
-                    if (onFound) {
-                        mScanCallback.onScanResult(ScanSettings.CALLBACK_TYPE_FIRST_MATCH,
-                                scanResult);
-                    } else {
-                        mScanCallback.onScanResult(ScanSettings.CALLBACK_TYPE_MATCH_LOST,
-                                scanResult);
-                    }
-                }
-            });
-        }
-
-        @Override
-        public void onScanManagerErrorCallback(final int errorCode) {
-            if (VDBG) {
-                Log.d(TAG, "onScanManagerErrorCallback() - errorCode = " + errorCode);
-            }
-            synchronized (this) {
-                if (mScannerId <= 0) {
-                    return;
-                }
-            }
-            postCallbackError(mScanCallback, errorCode);
-        }
-    }
-
-    private int postCallbackErrorOrReturn(final ScanCallback callback, final int errorCode) {
-        if (callback == null) {
-            return errorCode;
-        } else {
-            postCallbackError(callback, errorCode);
-            return ScanCallback.NO_ERROR;
-        }
-    }
-
-    @SuppressLint("AndroidFrameworkBluetoothPermission")
-    private void postCallbackError(final ScanCallback callback, final int errorCode) {
-        mHandler.post(new Runnable() {
-            @Override
-            public void run() {
-                callback.onScanFailed(errorCode);
-            }
-        });
-    }
-
-    private boolean isSettingsConfigAllowedForScan(ScanSettings settings) {
-        if (mBluetoothAdapter.isOffloadedFilteringSupported()) {
-            return true;
-        }
-        final int callbackType = settings.getCallbackType();
-        // Only support regular scan if no offloaded filter support.
-        if (callbackType == ScanSettings.CALLBACK_TYPE_ALL_MATCHES
-                && settings.getReportDelayMillis() == 0) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean isSettingsAndFilterComboAllowed(ScanSettings settings,
-            List<ScanFilter> filterList) {
-        final int callbackType = settings.getCallbackType();
-        // If onlost/onfound is requested, a non-empty filter is expected
-        if ((callbackType & (ScanSettings.CALLBACK_TYPE_FIRST_MATCH
-                | ScanSettings.CALLBACK_TYPE_MATCH_LOST)) != 0) {
-            if (filterList == null) {
-                return false;
-            }
-            for (ScanFilter filter : filterList) {
-                if (filter.isAllFieldsEmpty()) {
-                    return false;
-                }
-            }
-        }
-        return true;
-    }
-
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
-    private boolean isHardwareResourcesAvailableForScan(ScanSettings settings) {
-        final int callbackType = settings.getCallbackType();
-        if ((callbackType & ScanSettings.CALLBACK_TYPE_FIRST_MATCH) != 0
-                || (callbackType & ScanSettings.CALLBACK_TYPE_MATCH_LOST) != 0) {
-            // For onlost/onfound, we required hw support be available
-            return (mBluetoothAdapter.isOffloadedFilteringSupported()
-                    && mBluetoothAdapter.isHardwareTrackingFiltersAvailable());
-        }
-        return true;
-    }
-}
diff --git a/core/java/android/bluetooth/le/BluetoothLeUtils.java b/core/java/android/bluetooth/le/BluetoothLeUtils.java
deleted file mode 100644
index ed50b09..0000000
--- a/core/java/android/bluetooth/le/BluetoothLeUtils.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.le;
-
-import android.bluetooth.BluetoothAdapter;
-import android.util.SparseArray;
-
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import java.util.UUID;
-
-/**
- * Helper class for Bluetooth LE utils.
- *
- * @hide
- */
-public class BluetoothLeUtils {
-
-    /**
-     * Returns a string composed from a {@link SparseArray}.
-     */
-    static String toString(SparseArray<byte[]> array) {
-        if (array == null) {
-            return "null";
-        }
-        if (array.size() == 0) {
-            return "{}";
-        }
-        StringBuilder buffer = new StringBuilder();
-        buffer.append('{');
-        for (int i = 0; i < array.size(); ++i) {
-            buffer.append(array.keyAt(i)).append("=").append(Arrays.toString(array.valueAt(i)));
-        }
-        buffer.append('}');
-        return buffer.toString();
-    }
-
-    /**
-     * Returns a string composed from a {@link Map}.
-     */
-    static <T> String toString(Map<T, byte[]> map) {
-        if (map == null) {
-            return "null";
-        }
-        if (map.isEmpty()) {
-            return "{}";
-        }
-        StringBuilder buffer = new StringBuilder();
-        buffer.append('{');
-        Iterator<Map.Entry<T, byte[]>> it = map.entrySet().iterator();
-        while (it.hasNext()) {
-            Map.Entry<T, byte[]> entry = it.next();
-            Object key = entry.getKey();
-            buffer.append(key).append("=").append(Arrays.toString(map.get(key)));
-            if (it.hasNext()) {
-                buffer.append(", ");
-            }
-        }
-        buffer.append('}');
-        return buffer.toString();
-    }
-
-    /**
-     * Check whether two {@link SparseArray} equal.
-     */
-    static boolean equals(SparseArray<byte[]> array, SparseArray<byte[]> otherArray) {
-        if (array == otherArray) {
-            return true;
-        }
-        if (array == null || otherArray == null) {
-            return false;
-        }
-        if (array.size() != otherArray.size()) {
-            return false;
-        }
-
-        // Keys are guaranteed in ascending order when indices are in ascending order.
-        for (int i = 0; i < array.size(); ++i) {
-            if (array.keyAt(i) != otherArray.keyAt(i)
-                    || !Arrays.equals(array.valueAt(i), otherArray.valueAt(i))) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Check whether two {@link Map} equal.
-     */
-    static <T> boolean equals(Map<T, byte[]> map, Map<T, byte[]> otherMap) {
-        if (map == otherMap) {
-            return true;
-        }
-        if (map == null || otherMap == null) {
-            return false;
-        }
-        if (map.size() != otherMap.size()) {
-            return false;
-        }
-        Set<T> keys = map.keySet();
-        if (!keys.equals(otherMap.keySet())) {
-            return false;
-        }
-        for (T key : keys) {
-            if (!Objects.deepEquals(map.get(key), otherMap.get(key))) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Ensure Bluetooth is turned on.
-     *
-     * @throws IllegalStateException If {@code adapter} is null or Bluetooth state is not {@link
-     * BluetoothAdapter#STATE_ON}.
-     */
-    static void checkAdapterStateOn(BluetoothAdapter adapter) {
-        if (adapter == null || !adapter.isLeEnabled()) {
-            throw new IllegalStateException("BT Adapter is not turned ON");
-        }
-    }
-
-    /**
-     * Compares two UUIDs with a UUID mask.
-     *
-     * @param data first {@link #UUID} to compare.
-     * @param uuid second {@link #UUID} to compare.
-     * @param mask mask {@link #UUID}.
-     * @return true if both UUIDs are equals when masked, false otherwise.
-     */
-    static boolean maskedEquals(UUID data, UUID uuid, UUID mask) {
-        if (mask == null) {
-            return Objects.equals(data, uuid);
-        }
-        return (data.getLeastSignificantBits() & mask.getLeastSignificantBits())
-                == (uuid.getLeastSignificantBits() & mask.getLeastSignificantBits())
-                && (data.getMostSignificantBits() & mask.getMostSignificantBits())
-                == (uuid.getMostSignificantBits() & mask.getMostSignificantBits());
-    }
-}
diff --git a/core/java/android/bluetooth/le/OWNERS b/core/java/android/bluetooth/le/OWNERS
deleted file mode 100644
index 3523ee0..0000000
--- a/core/java/android/bluetooth/le/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-# Bug component: 27441
-
-zachoverflow@google.com
-siyuanh@google.com
diff --git a/core/java/android/bluetooth/le/PeriodicAdvertisingCallback.java b/core/java/android/bluetooth/le/PeriodicAdvertisingCallback.java
deleted file mode 100644
index 14ac911..0000000
--- a/core/java/android/bluetooth/le/PeriodicAdvertisingCallback.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.le;
-
-import android.bluetooth.BluetoothDevice;
-
-/**
- * Bluetooth LE periodic advertising callbacks, used to deliver periodic
- * advertising operation status.
- *
- * @hide
- * @see PeriodicAdvertisingManager#createSync
- */
-public abstract class PeriodicAdvertisingCallback {
-
-    /**
-     * The requested operation was successful.
-     *
-     * @hide
-     */
-    public static final int SYNC_SUCCESS = 0;
-
-    /**
-     * Sync failed to be established because remote device did not respond.
-     */
-    public static final int SYNC_NO_RESPONSE = 1;
-
-    /**
-     * Sync failed to be established because controller can't support more syncs.
-     */
-    public static final int SYNC_NO_RESOURCES = 2;
-
-
-    /**
-     * Callback when synchronization was established.
-     *
-     * @param syncHandle handle used to identify this synchronization.
-     * @param device remote device.
-     * @param advertisingSid synchronized advertising set id.
-     * @param skip The number of periodic advertising packets that can be skipped after a successful
-     * receive in force. @see PeriodicAdvertisingManager#createSync
-     * @param timeout Synchronization timeout for the periodic advertising in force. One unit is
-     * 10ms. @see PeriodicAdvertisingManager#createSync
-     * @param timeout
-     * @param status operation status.
-     */
-    public void onSyncEstablished(int syncHandle, BluetoothDevice device,
-            int advertisingSid, int skip, int timeout,
-            int status) {
-    }
-
-    /**
-     * Callback when periodic advertising report is received.
-     *
-     * @param report periodic advertising report.
-     */
-    public void onPeriodicAdvertisingReport(PeriodicAdvertisingReport report) {
-    }
-
-    /**
-     * Callback when periodic advertising synchronization was lost.
-     *
-     * @param syncHandle handle used to identify this synchronization.
-     */
-    public void onSyncLost(int syncHandle) {
-    }
-}
diff --git a/core/java/android/bluetooth/le/PeriodicAdvertisingManager.java b/core/java/android/bluetooth/le/PeriodicAdvertisingManager.java
deleted file mode 100644
index bbd3117..0000000
--- a/core/java/android/bluetooth/le/PeriodicAdvertisingManager.java
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package android.bluetooth.le;
-
-import android.annotation.RequiresPermission;
-import android.annotation.SuppressLint;
-import android.bluetooth.Attributable;
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.IBluetoothGatt;
-import android.bluetooth.IBluetoothManager;
-import android.bluetooth.annotations.RequiresBluetoothLocationPermission;
-import android.bluetooth.annotations.RequiresBluetoothScanPermission;
-import android.bluetooth.annotations.RequiresLegacyBluetoothAdminPermission;
-import android.content.AttributionSource;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.util.IdentityHashMap;
-import java.util.Map;
-import java.util.Objects;
-
-/**
- * This class provides methods to perform periodic advertising related
- * operations. An application can register for periodic advertisements using
- * {@link PeriodicAdvertisingManager#registerSync}.
- * <p>
- * Use {@link BluetoothAdapter#getPeriodicAdvertisingManager()} to get an
- * instance of {@link PeriodicAdvertisingManager}.
- *
- * @hide
- */
-public final class PeriodicAdvertisingManager {
-
-    private static final String TAG = "PeriodicAdvertisingManager";
-
-    private static final int SKIP_MIN = 0;
-    private static final int SKIP_MAX = 499;
-    private static final int TIMEOUT_MIN = 10;
-    private static final int TIMEOUT_MAX = 16384;
-
-    private static final int SYNC_STARTING = -1;
-
-    private final BluetoothAdapter mBluetoothAdapter;
-    private final IBluetoothManager mBluetoothManager;
-    private final AttributionSource mAttributionSource;
-
-    /* maps callback, to callback wrapper and sync handle */
-    Map<PeriodicAdvertisingCallback,
-            IPeriodicAdvertisingCallback /* callbackWrapper */> mCallbackWrappers;
-
-    /**
-     * Use {@link BluetoothAdapter#getBluetoothLeScanner()} instead.
-     *
-     * @param bluetoothManager BluetoothManager that conducts overall Bluetooth Management.
-     * @hide
-     */
-    public PeriodicAdvertisingManager(BluetoothAdapter bluetoothAdapter) {
-        mBluetoothAdapter = Objects.requireNonNull(bluetoothAdapter);
-        mBluetoothManager = mBluetoothAdapter.getBluetoothManager();
-        mAttributionSource = mBluetoothAdapter.getAttributionSource();
-        mCallbackWrappers = new IdentityHashMap<>();
-    }
-
-    /**
-     * Synchronize with periodic advertising pointed to by the {@code scanResult}.
-     * The {@code scanResult} used must contain a valid advertisingSid. First
-     * call to registerSync will use the {@code skip} and {@code timeout} provided.
-     * Subsequent calls from other apps, trying to sync with same set will reuse
-     * existing sync, thus {@code skip} and {@code timeout} values will not take
-     * effect. The values in effect will be returned in
-     * {@link PeriodicAdvertisingCallback#onSyncEstablished}.
-     *
-     * @param scanResult Scan result containing advertisingSid.
-     * @param skip The number of periodic advertising packets that can be skipped after a successful
-     * receive. Must be between 0 and 499.
-     * @param timeout Synchronization timeout for the periodic advertising. One unit is 10ms. Must
-     * be between 10 (100ms) and 16384 (163.84s).
-     * @param callback Callback used to deliver all operations status.
-     * @throws IllegalArgumentException if {@code scanResult} is null or {@code skip} is invalid or
-     * {@code timeout} is invalid or {@code callback} is null.
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothScanPermission
-    @RequiresBluetoothLocationPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
-    public void registerSync(ScanResult scanResult, int skip, int timeout,
-            PeriodicAdvertisingCallback callback) {
-        registerSync(scanResult, skip, timeout, callback, null);
-    }
-
-    /**
-     * Synchronize with periodic advertising pointed to by the {@code scanResult}.
-     * The {@code scanResult} used must contain a valid advertisingSid. First
-     * call to registerSync will use the {@code skip} and {@code timeout} provided.
-     * Subsequent calls from other apps, trying to sync with same set will reuse
-     * existing sync, thus {@code skip} and {@code timeout} values will not take
-     * effect. The values in effect will be returned in
-     * {@link PeriodicAdvertisingCallback#onSyncEstablished}.
-     *
-     * @param scanResult Scan result containing advertisingSid.
-     * @param skip The number of periodic advertising packets that can be skipped after a successful
-     * receive. Must be between 0 and 499.
-     * @param timeout Synchronization timeout for the periodic advertising. One unit is 10ms. Must
-     * be between 10 (100ms) and 16384 (163.84s).
-     * @param callback Callback used to deliver all operations status.
-     * @param handler thread upon which the callbacks will be invoked.
-     * @throws IllegalArgumentException if {@code scanResult} is null or {@code skip} is invalid or
-     * {@code timeout} is invalid or {@code callback} is null.
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothScanPermission
-    @RequiresBluetoothLocationPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
-    public void registerSync(ScanResult scanResult, int skip, int timeout,
-            PeriodicAdvertisingCallback callback, Handler handler) {
-        if (callback == null) {
-            throw new IllegalArgumentException("callback can't be null");
-        }
-
-        if (scanResult == null) {
-            throw new IllegalArgumentException("scanResult can't be null");
-        }
-
-        if (scanResult.getAdvertisingSid() == ScanResult.SID_NOT_PRESENT) {
-            throw new IllegalArgumentException("scanResult must contain a valid sid");
-        }
-
-        if (skip < SKIP_MIN || skip > SKIP_MAX) {
-            throw new IllegalArgumentException(
-                    "timeout must be between " + TIMEOUT_MIN + " and " + TIMEOUT_MAX);
-        }
-
-        if (timeout < TIMEOUT_MIN || timeout > TIMEOUT_MAX) {
-            throw new IllegalArgumentException(
-                    "timeout must be between " + TIMEOUT_MIN + " and " + TIMEOUT_MAX);
-        }
-
-        IBluetoothGatt gatt;
-        try {
-            gatt = mBluetoothManager.getBluetoothGatt();
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to get Bluetooth gatt - ", e);
-            callback.onSyncEstablished(0, scanResult.getDevice(), scanResult.getAdvertisingSid(),
-                    skip, timeout,
-                    PeriodicAdvertisingCallback.SYNC_NO_RESOURCES);
-            return;
-        }
-
-        if (handler == null) {
-            handler = new Handler(Looper.getMainLooper());
-        }
-
-        IPeriodicAdvertisingCallback wrapped = wrap(callback, handler);
-        mCallbackWrappers.put(callback, wrapped);
-
-        try {
-            gatt.registerSync(
-                    scanResult, skip, timeout, wrapped, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to register sync - ", e);
-            return;
-        }
-    }
-
-    /**
-     * Cancel pending attempt to create sync, or terminate existing sync.
-     *
-     * @param callback Callback used to deliver all operations status.
-     * @throws IllegalArgumentException if {@code callback} is null, or not a properly registered
-     * callback.
-     */
-    @RequiresLegacyBluetoothAdminPermission
-    @RequiresBluetoothScanPermission
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
-    public void unregisterSync(PeriodicAdvertisingCallback callback) {
-        if (callback == null) {
-            throw new IllegalArgumentException("callback can't be null");
-        }
-
-        IBluetoothGatt gatt;
-        try {
-            gatt = mBluetoothManager.getBluetoothGatt();
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to get Bluetooth gatt - ", e);
-            return;
-        }
-
-        IPeriodicAdvertisingCallback wrapper = mCallbackWrappers.remove(callback);
-        if (wrapper == null) {
-            throw new IllegalArgumentException("callback was not properly registered");
-        }
-
-        try {
-            gatt.unregisterSync(wrapper, mAttributionSource);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to cancel sync creation - ", e);
-            return;
-        }
-    }
-
-    @SuppressLint("AndroidFrameworkBluetoothPermission")
-    private IPeriodicAdvertisingCallback wrap(PeriodicAdvertisingCallback callback,
-            Handler handler) {
-        return new IPeriodicAdvertisingCallback.Stub() {
-            public void onSyncEstablished(int syncHandle, BluetoothDevice device,
-                    int advertisingSid, int skip, int timeout, int status) {
-                Attributable.setAttributionSource(device, mAttributionSource);
-                handler.post(new Runnable() {
-                    @Override
-                    public void run() {
-                        callback.onSyncEstablished(syncHandle, device, advertisingSid, skip,
-                                timeout,
-                                status);
-
-                        if (status != PeriodicAdvertisingCallback.SYNC_SUCCESS) {
-                            // App can still unregister the sync until notified it failed. Remove
-                            // callback
-                            // after app was notifed.
-                            mCallbackWrappers.remove(callback);
-                        }
-                    }
-                });
-            }
-
-            public void onPeriodicAdvertisingReport(PeriodicAdvertisingReport report) {
-                handler.post(new Runnable() {
-                    @Override
-                    public void run() {
-                        callback.onPeriodicAdvertisingReport(report);
-                    }
-                });
-            }
-
-            public void onSyncLost(int syncHandle) {
-                handler.post(new Runnable() {
-                    @Override
-                    public void run() {
-                        callback.onSyncLost(syncHandle);
-                        // App can still unregister the sync until notified it's lost.
-                        // Remove callback after app was notifed.
-                        mCallbackWrappers.remove(callback);
-                    }
-                });
-            }
-        };
-    }
-}
diff --git a/core/java/android/bluetooth/le/PeriodicAdvertisingParameters.java b/core/java/android/bluetooth/le/PeriodicAdvertisingParameters.java
deleted file mode 100644
index 4e64dbe..0000000
--- a/core/java/android/bluetooth/le/PeriodicAdvertisingParameters.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.le;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * The {@link PeriodicAdvertisingParameters} provide a way to adjust periodic
- * advertising preferences for each Bluetooth LE advertising set. Use {@link
- * PeriodicAdvertisingParameters.Builder} to create an instance of this class.
- */
-public final class PeriodicAdvertisingParameters implements Parcelable {
-
-    private static final int INTERVAL_MIN = 80;
-    private static final int INTERVAL_MAX = 65519;
-
-    private final boolean mIncludeTxPower;
-    private final int mInterval;
-
-    private PeriodicAdvertisingParameters(boolean includeTxPower, int interval) {
-        mIncludeTxPower = includeTxPower;
-        mInterval = interval;
-    }
-
-    private PeriodicAdvertisingParameters(Parcel in) {
-        mIncludeTxPower = in.readInt() != 0;
-        mInterval = in.readInt();
-    }
-
-    /**
-     * Returns whether the TX Power will be included.
-     */
-    public boolean getIncludeTxPower() {
-        return mIncludeTxPower;
-    }
-
-    /**
-     * Returns the periodic advertising interval, in 1.25ms unit.
-     * Valid values are from 80 (100ms) to 65519 (81.89875s).
-     */
-    public int getInterval() {
-        return mInterval;
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(mIncludeTxPower ? 1 : 0);
-        dest.writeInt(mInterval);
-    }
-
-    public static final Parcelable
-            .Creator<PeriodicAdvertisingParameters> CREATOR =
-            new Creator<PeriodicAdvertisingParameters>() {
-                @Override
-                public PeriodicAdvertisingParameters[] newArray(int size) {
-                    return new PeriodicAdvertisingParameters[size];
-                }
-
-                @Override
-                public PeriodicAdvertisingParameters createFromParcel(Parcel in) {
-                    return new PeriodicAdvertisingParameters(in);
-                }
-            };
-
-    public static final class Builder {
-        private boolean mIncludeTxPower = false;
-        private int mInterval = INTERVAL_MAX;
-
-        /**
-         * Whether the transmission power level should be included in the periodic
-         * packet.
-         */
-        public Builder setIncludeTxPower(boolean includeTxPower) {
-            mIncludeTxPower = includeTxPower;
-            return this;
-        }
-
-        /**
-         * Set advertising interval for periodic advertising, in 1.25ms unit.
-         * Valid values are from 80 (100ms) to 65519 (81.89875s).
-         * Value from range [interval, interval+20ms] will be picked as the actual value.
-         *
-         * @throws IllegalArgumentException If the interval is invalid.
-         */
-        public Builder setInterval(int interval) {
-            if (interval < INTERVAL_MIN || interval > INTERVAL_MAX) {
-                throw new IllegalArgumentException("Invalid interval (must be " + INTERVAL_MIN
-                        + "-" + INTERVAL_MAX + ")");
-            }
-            mInterval = interval;
-            return this;
-        }
-
-        /**
-         * Build the {@link AdvertisingSetParameters} object.
-         */
-        public PeriodicAdvertisingParameters build() {
-            return new PeriodicAdvertisingParameters(mIncludeTxPower, mInterval);
-        }
-    }
-}
diff --git a/core/java/android/bluetooth/le/PeriodicAdvertisingReport.java b/core/java/android/bluetooth/le/PeriodicAdvertisingReport.java
deleted file mode 100644
index 54b953c..0000000
--- a/core/java/android/bluetooth/le/PeriodicAdvertisingReport.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.le;
-
-import android.annotation.Nullable;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.Objects;
-
-/**
- * PeriodicAdvertisingReport for Bluetooth LE synchronized advertising.
- *
- * @hide
- */
-public final class PeriodicAdvertisingReport implements Parcelable {
-
-    /**
-     * The data returned is complete
-     */
-    public static final int DATA_COMPLETE = 0;
-
-    /**
-     * The data returned is incomplete. The controller was unsuccessfull to
-     * receive all chained packets, returning only partial data.
-     */
-    public static final int DATA_INCOMPLETE_TRUNCATED = 2;
-
-    private int mSyncHandle;
-    private int mTxPower;
-    private int mRssi;
-    private int mDataStatus;
-
-    // periodic advertising data.
-    @Nullable
-    private ScanRecord mData;
-
-    // Device timestamp when the result was last seen.
-    private long mTimestampNanos;
-
-    /**
-     * Constructor of periodic advertising result.
-     */
-    public PeriodicAdvertisingReport(int syncHandle, int txPower, int rssi,
-            int dataStatus, ScanRecord data) {
-        mSyncHandle = syncHandle;
-        mTxPower = txPower;
-        mRssi = rssi;
-        mDataStatus = dataStatus;
-        mData = data;
-    }
-
-    private PeriodicAdvertisingReport(Parcel in) {
-        readFromParcel(in);
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(mSyncHandle);
-        dest.writeInt(mTxPower);
-        dest.writeInt(mRssi);
-        dest.writeInt(mDataStatus);
-        if (mData != null) {
-            dest.writeInt(1);
-            dest.writeByteArray(mData.getBytes());
-        } else {
-            dest.writeInt(0);
-        }
-    }
-
-    private void readFromParcel(Parcel in) {
-        mSyncHandle = in.readInt();
-        mTxPower = in.readInt();
-        mRssi = in.readInt();
-        mDataStatus = in.readInt();
-        if (in.readInt() == 1) {
-            mData = ScanRecord.parseFromBytes(in.createByteArray());
-        }
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    /**
-     * Returns the synchronization handle.
-     */
-    public int getSyncHandle() {
-        return mSyncHandle;
-    }
-
-    /**
-     * Returns the transmit power in dBm. The valid range is [-127, 126]. Value
-     * of 127 means information was not available.
-     */
-    public int getTxPower() {
-        return mTxPower;
-    }
-
-    /**
-     * Returns the received signal strength in dBm. The valid range is [-127, 20].
-     */
-    public int getRssi() {
-        return mRssi;
-    }
-
-    /**
-     * Returns the data status. Can be one of {@link PeriodicAdvertisingReport#DATA_COMPLETE}
-     * or {@link PeriodicAdvertisingReport#DATA_INCOMPLETE_TRUNCATED}.
-     */
-    public int getDataStatus() {
-        return mDataStatus;
-    }
-
-    /**
-     * Returns the data contained in this periodic advertising report.
-     */
-    @Nullable
-    public ScanRecord getData() {
-        return mData;
-    }
-
-    /**
-     * Returns timestamp since boot when the scan record was observed.
-     */
-    public long getTimestampNanos() {
-        return mTimestampNanos;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(mSyncHandle, mTxPower, mRssi, mDataStatus, mData, mTimestampNanos);
-    }
-
-    @Override
-    public boolean equals(@Nullable Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj == null || getClass() != obj.getClass()) {
-            return false;
-        }
-        PeriodicAdvertisingReport other = (PeriodicAdvertisingReport) obj;
-        return (mSyncHandle == other.mSyncHandle)
-                && (mTxPower == other.mTxPower)
-                && (mRssi == other.mRssi)
-                && (mDataStatus == other.mDataStatus)
-                && Objects.equals(mData, other.mData)
-                && (mTimestampNanos == other.mTimestampNanos);
-    }
-
-    @Override
-    public String toString() {
-        return "PeriodicAdvertisingReport{syncHandle=" + mSyncHandle
-                + ", txPower=" + mTxPower + ", rssi=" + mRssi + ", dataStatus=" + mDataStatus
-                + ", data=" + Objects.toString(mData) + ", timestampNanos=" + mTimestampNanos + '}';
-    }
-
-    public static final @android.annotation.NonNull Parcelable.Creator<PeriodicAdvertisingReport> CREATOR =
-            new Creator<PeriodicAdvertisingReport>() {
-                @Override
-                public PeriodicAdvertisingReport createFromParcel(Parcel source) {
-                    return new PeriodicAdvertisingReport(source);
-                }
-
-                @Override
-                public PeriodicAdvertisingReport[] newArray(int size) {
-                    return new PeriodicAdvertisingReport[size];
-                }
-            };
-}
diff --git a/core/java/android/bluetooth/le/ResultStorageDescriptor.java b/core/java/android/bluetooth/le/ResultStorageDescriptor.java
deleted file mode 100644
index f650489..0000000
--- a/core/java/android/bluetooth/le/ResultStorageDescriptor.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.le;
-
-import android.annotation.SystemApi;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Describes the way to store scan result.
- *
- * @deprecated this is not used anywhere
- *
- * @hide
- */
-@Deprecated
-@SystemApi
-public final class ResultStorageDescriptor implements Parcelable {
-    private int mType;
-    private int mOffset;
-    private int mLength;
-
-    public int getType() {
-        return mType;
-    }
-
-    public int getOffset() {
-        return mOffset;
-    }
-
-    public int getLength() {
-        return mLength;
-    }
-
-    /**
-     * Constructor of {@link ResultStorageDescriptor}
-     *
-     * @param type Type of the data.
-     * @param offset Offset from start of the advertise packet payload.
-     * @param length Byte length of the data
-     */
-    public ResultStorageDescriptor(int type, int offset, int length) {
-        mType = type;
-        mOffset = offset;
-        mLength = length;
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(mType);
-        dest.writeInt(mOffset);
-        dest.writeInt(mLength);
-    }
-
-    private ResultStorageDescriptor(Parcel in) {
-        ReadFromParcel(in);
-    }
-
-    private void ReadFromParcel(Parcel in) {
-        mType = in.readInt();
-        mOffset = in.readInt();
-        mLength = in.readInt();
-    }
-
-    public static final @android.annotation.NonNull Parcelable.Creator<ResultStorageDescriptor> CREATOR =
-            new Creator<ResultStorageDescriptor>() {
-        @Override
-        public ResultStorageDescriptor createFromParcel(Parcel source) {
-            return new ResultStorageDescriptor(source);
-        }
-
-        @Override
-        public ResultStorageDescriptor[] newArray(int size) {
-            return new ResultStorageDescriptor[size];
-        }
-    };
-}
diff --git a/core/java/android/bluetooth/le/ScanCallback.java b/core/java/android/bluetooth/le/ScanCallback.java
deleted file mode 100644
index 53d9310..0000000
--- a/core/java/android/bluetooth/le/ScanCallback.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.le;
-
-import java.util.List;
-
-/**
- * Bluetooth LE scan callbacks. Scan results are reported using these callbacks.
- *
- * @see BluetoothLeScanner#startScan
- */
-public abstract class ScanCallback {
-    /**
-     * Fails to start scan as BLE scan with the same settings is already started by the app.
-     */
-    public static final int SCAN_FAILED_ALREADY_STARTED = 1;
-
-    /**
-     * Fails to start scan as app cannot be registered.
-     */
-    public static final int SCAN_FAILED_APPLICATION_REGISTRATION_FAILED = 2;
-
-    /**
-     * Fails to start scan due an internal error
-     */
-    public static final int SCAN_FAILED_INTERNAL_ERROR = 3;
-
-    /**
-     * Fails to start power optimized scan as this feature is not supported.
-     */
-    public static final int SCAN_FAILED_FEATURE_UNSUPPORTED = 4;
-
-    /**
-     * Fails to start scan as it is out of hardware resources.
-     *
-     * @hide
-     */
-    public static final int SCAN_FAILED_OUT_OF_HARDWARE_RESOURCES = 5;
-
-    /**
-     * Fails to start scan as application tries to scan too frequently.
-     * @hide
-     */
-    public static final int SCAN_FAILED_SCANNING_TOO_FREQUENTLY = 6;
-
-    static final int NO_ERROR = 0;
-
-    /**
-     * Callback when a BLE advertisement has been found.
-     *
-     * @param callbackType Determines how this callback was triggered. Could be one of {@link
-     * ScanSettings#CALLBACK_TYPE_ALL_MATCHES}, {@link ScanSettings#CALLBACK_TYPE_FIRST_MATCH} or
-     * {@link ScanSettings#CALLBACK_TYPE_MATCH_LOST}
-     * @param result A Bluetooth LE scan result.
-     */
-    public void onScanResult(int callbackType, ScanResult result) {
-    }
-
-    /**
-     * Callback when batch results are delivered.
-     *
-     * @param results List of scan results that are previously scanned.
-     */
-    public void onBatchScanResults(List<ScanResult> results) {
-    }
-
-    /**
-     * Callback when scan could not be started.
-     *
-     * @param errorCode Error code (one of SCAN_FAILED_*) for scan failure.
-     */
-    public void onScanFailed(int errorCode) {
-    }
-}
diff --git a/core/java/android/bluetooth/le/ScanFilter.java b/core/java/android/bluetooth/le/ScanFilter.java
deleted file mode 100644
index b059193..0000000
--- a/core/java/android/bluetooth/le/ScanFilter.java
+++ /dev/null
@@ -1,910 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.le;
-
-import static java.util.Objects.requireNonNull;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothDevice.AddressType;
-import android.os.Parcel;
-import android.os.ParcelUuid;
-import android.os.Parcelable;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.Objects;
-import java.util.UUID;
-
-/**
- * Criteria for filtering result from Bluetooth LE scans. A {@link ScanFilter} allows clients to
- * restrict scan results to only those that are of interest to them.
- * <p>
- * Current filtering on the following fields are supported:
- * <li>Service UUIDs which identify the bluetooth gatt services running on the device.
- * <li>Name of remote Bluetooth LE device.
- * <li>Mac address of the remote device.
- * <li>Service data which is the data associated with a service.
- * <li>Manufacturer specific data which is the data associated with a particular manufacturer.
- *
- * @see ScanResult
- * @see BluetoothLeScanner
- */
-public final class ScanFilter implements Parcelable {
-
-    @Nullable
-    private final String mDeviceName;
-
-    @Nullable
-    private final String mDeviceAddress;
-
-    private final @AddressType int mAddressType;
-
-    @Nullable
-    private final byte[] mIrk;
-
-    @Nullable
-    private final ParcelUuid mServiceUuid;
-    @Nullable
-    private final ParcelUuid mServiceUuidMask;
-
-    @Nullable
-    private final ParcelUuid mServiceSolicitationUuid;
-    @Nullable
-    private final ParcelUuid mServiceSolicitationUuidMask;
-
-    @Nullable
-    private final ParcelUuid mServiceDataUuid;
-    @Nullable
-    private final byte[] mServiceData;
-    @Nullable
-    private final byte[] mServiceDataMask;
-
-    private final int mManufacturerId;
-    @Nullable
-    private final byte[] mManufacturerData;
-    @Nullable
-    private final byte[] mManufacturerDataMask;
-
-    /** @hide */
-    public static final ScanFilter EMPTY = new ScanFilter.Builder().build();
-
-    private ScanFilter(String name, String deviceAddress, ParcelUuid uuid,
-            ParcelUuid uuidMask, ParcelUuid solicitationUuid,
-            ParcelUuid solicitationUuidMask, ParcelUuid serviceDataUuid,
-            byte[] serviceData, byte[] serviceDataMask,
-            int manufacturerId, byte[] manufacturerData, byte[] manufacturerDataMask,
-            @AddressType int addressType, @Nullable byte[] irk) {
-        mDeviceName = name;
-        mServiceUuid = uuid;
-        mServiceUuidMask = uuidMask;
-        mServiceSolicitationUuid = solicitationUuid;
-        mServiceSolicitationUuidMask = solicitationUuidMask;
-        mDeviceAddress = deviceAddress;
-        mServiceDataUuid = serviceDataUuid;
-        mServiceData = serviceData;
-        mServiceDataMask = serviceDataMask;
-        mManufacturerId = manufacturerId;
-        mManufacturerData = manufacturerData;
-        mManufacturerDataMask = manufacturerDataMask;
-        mAddressType = addressType;
-        mIrk = irk;
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(mDeviceName == null ? 0 : 1);
-        if (mDeviceName != null) {
-            dest.writeString(mDeviceName);
-        }
-        dest.writeInt(mDeviceAddress == null ? 0 : 1);
-        if (mDeviceAddress != null) {
-            dest.writeString(mDeviceAddress);
-        }
-        dest.writeInt(mServiceUuid == null ? 0 : 1);
-        if (mServiceUuid != null) {
-            dest.writeParcelable(mServiceUuid, flags);
-            dest.writeInt(mServiceUuidMask == null ? 0 : 1);
-            if (mServiceUuidMask != null) {
-                dest.writeParcelable(mServiceUuidMask, flags);
-            }
-        }
-        dest.writeInt(mServiceSolicitationUuid == null ? 0 : 1);
-        if (mServiceSolicitationUuid != null) {
-            dest.writeParcelable(mServiceSolicitationUuid, flags);
-            dest.writeInt(mServiceSolicitationUuidMask == null ? 0 : 1);
-            if (mServiceSolicitationUuidMask != null) {
-                dest.writeParcelable(mServiceSolicitationUuidMask, flags);
-            }
-        }
-        dest.writeInt(mServiceDataUuid == null ? 0 : 1);
-        if (mServiceDataUuid != null) {
-            dest.writeParcelable(mServiceDataUuid, flags);
-            dest.writeInt(mServiceData == null ? 0 : 1);
-            if (mServiceData != null) {
-                dest.writeInt(mServiceData.length);
-                dest.writeByteArray(mServiceData);
-
-                dest.writeInt(mServiceDataMask == null ? 0 : 1);
-                if (mServiceDataMask != null) {
-                    dest.writeInt(mServiceDataMask.length);
-                    dest.writeByteArray(mServiceDataMask);
-                }
-            }
-        }
-        dest.writeInt(mManufacturerId);
-        dest.writeInt(mManufacturerData == null ? 0 : 1);
-        if (mManufacturerData != null) {
-            dest.writeInt(mManufacturerData.length);
-            dest.writeByteArray(mManufacturerData);
-
-            dest.writeInt(mManufacturerDataMask == null ? 0 : 1);
-            if (mManufacturerDataMask != null) {
-                dest.writeInt(mManufacturerDataMask.length);
-                dest.writeByteArray(mManufacturerDataMask);
-            }
-        }
-
-        // IRK
-        if (mDeviceAddress != null) {
-            dest.writeInt(mAddressType);
-            dest.writeInt(mIrk == null ? 0 : 1);
-            if (mIrk != null) {
-                dest.writeByteArray(mIrk);
-            }
-        }
-    }
-
-    /**
-     * A {@link android.os.Parcelable.Creator} to create {@link ScanFilter} from parcel.
-     */
-    public static final @android.annotation.NonNull Creator<ScanFilter> CREATOR =
-            new Creator<ScanFilter>() {
-
-        @Override
-        public ScanFilter[] newArray(int size) {
-            return new ScanFilter[size];
-        }
-
-        @Override
-        public ScanFilter createFromParcel(Parcel in) {
-            Builder builder = new Builder();
-            if (in.readInt() == 1) {
-                builder.setDeviceName(in.readString());
-            }
-            String address = null;
-            // If we have a non-null address
-            if (in.readInt() == 1) {
-                address = in.readString();
-            }
-            if (in.readInt() == 1) {
-                ParcelUuid uuid = in.readParcelable(ParcelUuid.class.getClassLoader());
-                builder.setServiceUuid(uuid);
-                if (in.readInt() == 1) {
-                    ParcelUuid uuidMask = in.readParcelable(
-                            ParcelUuid.class.getClassLoader());
-                    builder.setServiceUuid(uuid, uuidMask);
-                }
-            }
-            if (in.readInt() == 1) {
-                ParcelUuid solicitationUuid = in.readParcelable(
-                        ParcelUuid.class.getClassLoader());
-                builder.setServiceSolicitationUuid(solicitationUuid);
-                if (in.readInt() == 1) {
-                    ParcelUuid solicitationUuidMask = in.readParcelable(
-                            ParcelUuid.class.getClassLoader());
-                    builder.setServiceSolicitationUuid(solicitationUuid,
-                            solicitationUuidMask);
-                }
-            }
-            if (in.readInt() == 1) {
-                ParcelUuid servcieDataUuid =
-                        in.readParcelable(ParcelUuid.class.getClassLoader());
-                if (in.readInt() == 1) {
-                    int serviceDataLength = in.readInt();
-                    byte[] serviceData = new byte[serviceDataLength];
-                    in.readByteArray(serviceData);
-                    if (in.readInt() == 0) {
-                        builder.setServiceData(servcieDataUuid, serviceData);
-                    } else {
-                        int serviceDataMaskLength = in.readInt();
-                        byte[] serviceDataMask = new byte[serviceDataMaskLength];
-                        in.readByteArray(serviceDataMask);
-                        builder.setServiceData(
-                                servcieDataUuid, serviceData, serviceDataMask);
-                    }
-                }
-            }
-
-            int manufacturerId = in.readInt();
-            if (in.readInt() == 1) {
-                int manufacturerDataLength = in.readInt();
-                byte[] manufacturerData = new byte[manufacturerDataLength];
-                in.readByteArray(manufacturerData);
-                if (in.readInt() == 0) {
-                    builder.setManufacturerData(manufacturerId, manufacturerData);
-                } else {
-                    int manufacturerDataMaskLength = in.readInt();
-                    byte[] manufacturerDataMask = new byte[manufacturerDataMaskLength];
-                    in.readByteArray(manufacturerDataMask);
-                    builder.setManufacturerData(manufacturerId, manufacturerData,
-                            manufacturerDataMask);
-                }
-            }
-
-            // IRK
-            if (address != null) {
-                final int addressType = in.readInt();
-                if (in.readInt() == 1) {
-                    final byte[] irk = new byte[16];
-                    in.readByteArray(irk);
-                    builder.setDeviceAddress(address, addressType, irk);
-                } else {
-                    builder.setDeviceAddress(address, addressType);
-                }
-            }
-            return builder.build();
-        }
-    };
-
-    /**
-     * Returns the filter set the device name field of Bluetooth advertisement data.
-     */
-    @Nullable
-    public String getDeviceName() {
-        return mDeviceName;
-    }
-
-    /**
-     * Returns the filter set on the service uuid.
-     */
-    @Nullable
-    public ParcelUuid getServiceUuid() {
-        return mServiceUuid;
-    }
-
-    @Nullable
-    public ParcelUuid getServiceUuidMask() {
-        return mServiceUuidMask;
-    }
-
-    /**
-     * Returns the filter set on the service Solicitation uuid.
-     */
-    @Nullable
-    public ParcelUuid getServiceSolicitationUuid() {
-        return mServiceSolicitationUuid;
-    }
-
-    /**
-     * Returns the filter set on the service Solicitation uuid mask.
-     */
-    @Nullable
-    public ParcelUuid getServiceSolicitationUuidMask() {
-        return mServiceSolicitationUuidMask;
-    }
-
-    @Nullable
-    public String getDeviceAddress() {
-        return mDeviceAddress;
-    }
-
-    /**
-     * @hide
-     */
-    @SystemApi
-    public @AddressType int getAddressType() {
-        return mAddressType;
-    }
-
-    /**
-     * @hide
-     */
-    @SystemApi
-    @Nullable
-    public byte[] getIrk() {
-        return mIrk;
-    }
-
-    @Nullable
-    public byte[] getServiceData() {
-        return mServiceData;
-    }
-
-    @Nullable
-    public byte[] getServiceDataMask() {
-        return mServiceDataMask;
-    }
-
-    @Nullable
-    public ParcelUuid getServiceDataUuid() {
-        return mServiceDataUuid;
-    }
-
-    /**
-     * Returns the manufacturer id. -1 if the manufacturer filter is not set.
-     */
-    public int getManufacturerId() {
-        return mManufacturerId;
-    }
-
-    @Nullable
-    public byte[] getManufacturerData() {
-        return mManufacturerData;
-    }
-
-    @Nullable
-    public byte[] getManufacturerDataMask() {
-        return mManufacturerDataMask;
-    }
-
-    /**
-     * Check if the scan filter matches a {@code scanResult}. A scan result is considered as a match
-     * if it matches all the field filters.
-     */
-    public boolean matches(ScanResult scanResult) {
-        if (scanResult == null) {
-            return false;
-        }
-        BluetoothDevice device = scanResult.getDevice();
-        // Device match.
-        if (mDeviceAddress != null
-                && (device == null || !mDeviceAddress.equals(device.getAddress()))) {
-            return false;
-        }
-
-        ScanRecord scanRecord = scanResult.getScanRecord();
-
-        // Scan record is null but there exist filters on it.
-        if (scanRecord == null
-                && (mDeviceName != null || mServiceUuid != null || mManufacturerData != null
-                || mServiceData != null || mServiceSolicitationUuid != null)) {
-            return false;
-        }
-
-        // Local name match.
-        if (mDeviceName != null && !mDeviceName.equals(scanRecord.getDeviceName())) {
-            return false;
-        }
-
-        // UUID match.
-        if (mServiceUuid != null && !matchesServiceUuids(mServiceUuid, mServiceUuidMask,
-                scanRecord.getServiceUuids())) {
-            return false;
-        }
-
-        // solicitation UUID match.
-        if (mServiceSolicitationUuid != null && !matchesServiceSolicitationUuids(
-                mServiceSolicitationUuid, mServiceSolicitationUuidMask,
-                scanRecord.getServiceSolicitationUuids())) {
-            return false;
-        }
-
-        // Service data match
-        if (mServiceDataUuid != null) {
-            if (!matchesPartialData(mServiceData, mServiceDataMask,
-                    scanRecord.getServiceData(mServiceDataUuid))) {
-                return false;
-            }
-        }
-
-        // Manufacturer data match.
-        if (mManufacturerId >= 0) {
-            if (!matchesPartialData(mManufacturerData, mManufacturerDataMask,
-                    scanRecord.getManufacturerSpecificData(mManufacturerId))) {
-                return false;
-            }
-        }
-        // All filters match.
-        return true;
-    }
-
-    /**
-     * Check if the uuid pattern is contained in a list of parcel uuids.
-     *
-     * @hide
-     */
-    public static boolean matchesServiceUuids(ParcelUuid uuid, ParcelUuid parcelUuidMask,
-            List<ParcelUuid> uuids) {
-        if (uuid == null) {
-            return true;
-        }
-        if (uuids == null) {
-            return false;
-        }
-
-        for (ParcelUuid parcelUuid : uuids) {
-            UUID uuidMask = parcelUuidMask == null ? null : parcelUuidMask.getUuid();
-            if (matchesServiceUuid(uuid.getUuid(), uuidMask, parcelUuid.getUuid())) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    // Check if the uuid pattern matches the particular service uuid.
-    private static boolean matchesServiceUuid(UUID uuid, UUID mask, UUID data) {
-        return BluetoothLeUtils.maskedEquals(data, uuid, mask);
-    }
-
-    /**
-     * Check if the solicitation uuid pattern is contained in a list of parcel uuids.
-     *
-     */
-    private static boolean matchesServiceSolicitationUuids(ParcelUuid solicitationUuid,
-            ParcelUuid parcelSolicitationUuidMask, List<ParcelUuid> solicitationUuids) {
-        if (solicitationUuid == null) {
-            return true;
-        }
-        if (solicitationUuids == null) {
-            return false;
-        }
-
-        for (ParcelUuid parcelSolicitationUuid : solicitationUuids) {
-            UUID solicitationUuidMask = parcelSolicitationUuidMask == null
-                    ? null : parcelSolicitationUuidMask.getUuid();
-            if (matchesServiceUuid(solicitationUuid.getUuid(), solicitationUuidMask,
-                    parcelSolicitationUuid.getUuid())) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    // Check if the solicitation uuid pattern matches the particular service solicitation uuid.
-    private static boolean matchesServiceSolicitationUuid(UUID solicitationUuid,
-            UUID solicitationUuidMask, UUID data) {
-        return BluetoothLeUtils.maskedEquals(data, solicitationUuid, solicitationUuidMask);
-    }
-
-    // Check whether the data pattern matches the parsed data.
-    private boolean matchesPartialData(byte[] data, byte[] dataMask, byte[] parsedData) {
-        if (parsedData == null || parsedData.length < data.length) {
-            return false;
-        }
-        if (dataMask == null) {
-            for (int i = 0; i < data.length; ++i) {
-                if (parsedData[i] != data[i]) {
-                    return false;
-                }
-            }
-            return true;
-        }
-        for (int i = 0; i < data.length; ++i) {
-            if ((dataMask[i] & parsedData[i]) != (dataMask[i] & data[i])) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    @Override
-    public String toString() {
-        return "BluetoothLeScanFilter [mDeviceName=" + mDeviceName + ", mDeviceAddress="
-                + mDeviceAddress
-                + ", mUuid=" + mServiceUuid + ", mUuidMask=" + mServiceUuidMask
-                + ", mServiceSolicitationUuid=" + mServiceSolicitationUuid
-                + ", mServiceSolicitationUuidMask=" + mServiceSolicitationUuidMask
-                + ", mServiceDataUuid=" + Objects.toString(mServiceDataUuid) + ", mServiceData="
-                + Arrays.toString(mServiceData) + ", mServiceDataMask="
-                + Arrays.toString(mServiceDataMask) + ", mManufacturerId=" + mManufacturerId
-                + ", mManufacturerData=" + Arrays.toString(mManufacturerData)
-                + ", mManufacturerDataMask=" + Arrays.toString(mManufacturerDataMask) + "]";
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(mDeviceName, mDeviceAddress, mManufacturerId,
-                Arrays.hashCode(mManufacturerData),
-                Arrays.hashCode(mManufacturerDataMask),
-                mServiceDataUuid,
-                Arrays.hashCode(mServiceData),
-                Arrays.hashCode(mServiceDataMask),
-                mServiceUuid, mServiceUuidMask,
-                mServiceSolicitationUuid, mServiceSolicitationUuidMask);
-    }
-
-    @Override
-    public boolean equals(@Nullable Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj == null || getClass() != obj.getClass()) {
-            return false;
-        }
-        ScanFilter other = (ScanFilter) obj;
-        return Objects.equals(mDeviceName, other.mDeviceName)
-                && Objects.equals(mDeviceAddress, other.mDeviceAddress)
-                && mManufacturerId == other.mManufacturerId
-                && Objects.deepEquals(mManufacturerData, other.mManufacturerData)
-                && Objects.deepEquals(mManufacturerDataMask, other.mManufacturerDataMask)
-                && Objects.equals(mServiceDataUuid, other.mServiceDataUuid)
-                && Objects.deepEquals(mServiceData, other.mServiceData)
-                && Objects.deepEquals(mServiceDataMask, other.mServiceDataMask)
-                && Objects.equals(mServiceUuid, other.mServiceUuid)
-                && Objects.equals(mServiceUuidMask, other.mServiceUuidMask)
-                && Objects.equals(mServiceSolicitationUuid, other.mServiceSolicitationUuid)
-                && Objects.equals(mServiceSolicitationUuidMask,
-                        other.mServiceSolicitationUuidMask);
-    }
-
-    /**
-     * Checks if the scanfilter is empty
-     *
-     * @hide
-     */
-    public boolean isAllFieldsEmpty() {
-        return EMPTY.equals(this);
-    }
-
-    /**
-     * Builder class for {@link ScanFilter}.
-     */
-    public static final class Builder {
-
-        /**
-         * @hide
-         */
-        @SystemApi
-        public static final int LEN_IRK_OCTETS = 16;
-
-        private String mDeviceName;
-        private String mDeviceAddress;
-        private @AddressType int mAddressType = BluetoothDevice.ADDRESS_TYPE_PUBLIC;
-        private byte[] mIrk;
-
-        private ParcelUuid mServiceUuid;
-        private ParcelUuid mUuidMask;
-
-        private ParcelUuid mServiceSolicitationUuid;
-        private ParcelUuid mServiceSolicitationUuidMask;
-
-        private ParcelUuid mServiceDataUuid;
-        private byte[] mServiceData;
-        private byte[] mServiceDataMask;
-
-        private int mManufacturerId = -1;
-        private byte[] mManufacturerData;
-        private byte[] mManufacturerDataMask;
-
-        /**
-         * Set filter on device name.
-         */
-        public Builder setDeviceName(String deviceName) {
-            mDeviceName = deviceName;
-            return this;
-        }
-
-        /**
-         * Set filter on device address.
-         *
-         * @param deviceAddress The device Bluetooth address for the filter. It needs to be in the
-         * format of "01:02:03:AB:CD:EF". The device address can be validated using {@link
-         * BluetoothAdapter#checkBluetoothAddress}.  The @AddressType is defaulted to {@link
-         * BluetoothDevice#ADDRESS_TYPE_PUBLIC}
-         * @throws IllegalArgumentException If the {@code deviceAddress} is invalid.
-         */
-        public Builder setDeviceAddress(String deviceAddress) {
-            if (deviceAddress == null) {
-                mDeviceAddress = deviceAddress;
-                return this;
-            }
-            return setDeviceAddress(deviceAddress, BluetoothDevice.ADDRESS_TYPE_PUBLIC);
-        }
-
-        /**
-         * Set filter on Address with AddressType
-         *
-         * <p>This key is used to resolve a private address from a public address.
-         *
-         * @param deviceAddress The device Bluetooth address for the filter. It needs to be in the
-         * format of "01:02:03:AB:CD:EF". The device address can be validated using {@link
-         * BluetoothAdapter#checkBluetoothAddress}. May be any type of address.
-         * @param addressType indication of the type of address
-         * e.g. {@link BluetoothDevice#ADDRESS_TYPE_PUBLIC}
-         * or {@link BluetoothDevice#ADDRESS_TYPE_RANDOM}
-         *
-         * @throws IllegalArgumentException If the {@code deviceAddress} is invalid.
-         * @throws IllegalArgumentException If the {@code addressType} is invalid length
-         * @throws NullPointerException if {@code deviceAddress} is null.
-         *
-         * @hide
-         */
-        @NonNull
-        @SystemApi
-        public Builder setDeviceAddress(@NonNull String deviceAddress,
-                                        @AddressType int addressType) {
-            return setDeviceAddressInternal(deviceAddress, addressType, null);
-        }
-
-        /**
-         * Set filter on Address with AddressType and the Identity Resolving Key (IRK).
-         *
-         * <p>The IRK is used to resolve a {@link BluetoothDevice#ADDRESS_TYPE_PUBLIC} from
-         * a PRIVATE_ADDRESS type.
-         *
-         * @param deviceAddress The device Bluetooth address for the filter. It needs to be in the
-         * format of "01:02:03:AB:CD:EF". The device address can be validated using {@link
-         * BluetoothAdapter#checkBluetoothAddress}.  This Address type must only be PUBLIC OR RANDOM
-         * STATIC.
-         * @param addressType indication of the type of address
-         * e.g. {@link BluetoothDevice#ADDRESS_TYPE_PUBLIC}
-         * or {@link BluetoothDevice#ADDRESS_TYPE_RANDOM}
-         * @param irk non-null byte array representing the Identity Resolving Key
-         *
-         * @throws IllegalArgumentException If the {@code deviceAddress} is invalid.
-         * @throws IllegalArgumentException if the {@code irk} is invalid length.
-         * @throws IllegalArgumentException If the {@code addressType} is invalid length or is not
-         * PUBLIC or RANDOM STATIC when an IRK is present.
-         * @throws NullPointerException if {@code deviceAddress} or {@code irk} is null.
-         *
-         * @hide
-         */
-        @NonNull
-        @SystemApi
-        public Builder setDeviceAddress(@NonNull String deviceAddress,
-                                        @AddressType int addressType,
-                                        @NonNull byte[] irk) {
-            requireNonNull(irk);
-            if (irk.length != LEN_IRK_OCTETS) {
-                throw new IllegalArgumentException("'irk' is invalid length!");
-            }
-            return setDeviceAddressInternal(deviceAddress, addressType, irk);
-        }
-
-        /**
-         * Set filter on Address with AddressType and the Identity Resolving Key (IRK).
-         *
-         * <p>Internal setter for the device address
-         *
-         * @param deviceAddress The device Bluetooth address for the filter. It needs to be in the
-         * format of "01:02:03:AB:CD:EF". The device address can be validated using {@link
-         * BluetoothAdapter#checkBluetoothAddress}.
-         * @param addressType indication of the type of address
-         * e.g. {@link BluetoothDevice#ADDRESS_TYPE_PUBLIC}
-         * @param irk non-null byte array representing the Identity Resolving Address; nullable
-         * internally.
-         *
-         * @throws IllegalArgumentException If the {@code deviceAddress} is invalid.
-         * @throws IllegalArgumentException If the {@code addressType} is invalid length.
-         * @throws NullPointerException if {@code deviceAddress} is null.
-         *
-         * @hide
-         */
-        @NonNull
-        private Builder setDeviceAddressInternal(@NonNull String deviceAddress,
-                                                 @AddressType int addressType,
-                                                 @Nullable byte[] irk) {
-
-            // Make sure our deviceAddress is valid!
-            requireNonNull(deviceAddress);
-            if (!BluetoothAdapter.checkBluetoothAddress(deviceAddress)) {
-                throw new IllegalArgumentException("invalid device address " + deviceAddress);
-            }
-
-            // Verify type range
-            if (addressType < BluetoothDevice.ADDRESS_TYPE_PUBLIC
-                || addressType > BluetoothDevice.ADDRESS_TYPE_RANDOM) {
-                throw new IllegalArgumentException("'addressType' is invalid!");
-            }
-
-            // IRK can only be used for a PUBLIC or RANDOM (STATIC) Address.
-            if (addressType == BluetoothDevice.ADDRESS_TYPE_RANDOM) {
-                // Don't want a bad combination of address and irk!
-                if (irk != null) {
-                    // Since there are 3 possible RANDOM subtypes we must check to make sure
-                    // the correct type of address is used.
-                    if (!BluetoothAdapter.isAddressRandomStatic(deviceAddress)) {
-                        throw new IllegalArgumentException(
-                                "Invalid combination: IRK requires either a PUBLIC or "
-                                + "RANDOM (STATIC) Address");
-                    }
-                }
-            }
-
-            // PUBLIC doesn't require extra work
-            // Without an IRK any address may be accepted
-
-            mDeviceAddress = deviceAddress;
-            mAddressType = addressType;
-            mIrk = irk;
-            return this;
-        }
-
-        /**
-         * Set filter on service uuid.
-         */
-        public Builder setServiceUuid(ParcelUuid serviceUuid) {
-            mServiceUuid = serviceUuid;
-            mUuidMask = null; // clear uuid mask
-            return this;
-        }
-
-        /**
-         * Set filter on partial service uuid. The {@code uuidMask} is the bit mask for the
-         * {@code serviceUuid}. Set any bit in the mask to 1 to indicate a match is needed for the
-         * bit in {@code serviceUuid}, and 0 to ignore that bit.
-         *
-         * @throws IllegalArgumentException If {@code serviceUuid} is {@code null} but {@code
-         * uuidMask} is not {@code null}.
-         */
-        public Builder setServiceUuid(ParcelUuid serviceUuid, ParcelUuid uuidMask) {
-            if (mUuidMask != null && mServiceUuid == null) {
-                throw new IllegalArgumentException("uuid is null while uuidMask is not null!");
-            }
-            mServiceUuid = serviceUuid;
-            mUuidMask = uuidMask;
-            return this;
-        }
-
-
-        /**
-         * Set filter on service solicitation uuid.
-         */
-        public @NonNull Builder setServiceSolicitationUuid(
-                @Nullable ParcelUuid serviceSolicitationUuid) {
-            mServiceSolicitationUuid = serviceSolicitationUuid;
-            if (serviceSolicitationUuid == null) {
-                mServiceSolicitationUuidMask = null;
-            }
-            return this;
-        }
-
-
-        /**
-         * Set filter on partial service Solicitation uuid. The {@code SolicitationUuidMask} is the
-         * bit mask for the {@code serviceSolicitationUuid}. Set any bit in the mask to 1 to
-         * indicate a match is needed for the bit in {@code serviceSolicitationUuid}, and 0 to
-         * ignore that bit.
-         *
-         * @param serviceSolicitationUuid can only be null if solicitationUuidMask is null.
-         * @param solicitationUuidMask can be null or a mask with no restriction.
-         *
-         * @throws IllegalArgumentException If {@code serviceSolicitationUuid} is {@code null} but
-         *             {@code serviceSolicitationUuidMask} is not {@code null}.
-         */
-        public @NonNull Builder setServiceSolicitationUuid(
-                @Nullable ParcelUuid serviceSolicitationUuid,
-                @Nullable ParcelUuid solicitationUuidMask) {
-            if (solicitationUuidMask != null && serviceSolicitationUuid == null) {
-                throw new IllegalArgumentException(
-                        "SolicitationUuid is null while SolicitationUuidMask is not null!");
-            }
-            mServiceSolicitationUuid = serviceSolicitationUuid;
-            mServiceSolicitationUuidMask = solicitationUuidMask;
-            return this;
-        }
-
-        /**
-         * Set filtering on service data.
-         *
-         * @throws IllegalArgumentException If {@code serviceDataUuid} is null.
-         */
-        public Builder setServiceData(ParcelUuid serviceDataUuid, byte[] serviceData) {
-            if (serviceDataUuid == null) {
-                throw new IllegalArgumentException("serviceDataUuid is null");
-            }
-            mServiceDataUuid = serviceDataUuid;
-            mServiceData = serviceData;
-            mServiceDataMask = null; // clear service data mask
-            return this;
-        }
-
-        /**
-         * Set partial filter on service data. For any bit in the mask, set it to 1 if it needs to
-         * match the one in service data, otherwise set it to 0 to ignore that bit.
-         * <p>
-         * The {@code serviceDataMask} must have the same length of the {@code serviceData}.
-         *
-         * @throws IllegalArgumentException If {@code serviceDataUuid} is null or {@code
-         * serviceDataMask} is {@code null} while {@code serviceData} is not or {@code
-         * serviceDataMask} and {@code serviceData} has different length.
-         */
-        public Builder setServiceData(ParcelUuid serviceDataUuid,
-                byte[] serviceData, byte[] serviceDataMask) {
-            if (serviceDataUuid == null) {
-                throw new IllegalArgumentException("serviceDataUuid is null");
-            }
-            if (mServiceDataMask != null) {
-                if (mServiceData == null) {
-                    throw new IllegalArgumentException(
-                            "serviceData is null while serviceDataMask is not null");
-                }
-                // Since the mServiceDataMask is a bit mask for mServiceData, the lengths of the two
-                // byte array need to be the same.
-                if (mServiceData.length != mServiceDataMask.length) {
-                    throw new IllegalArgumentException(
-                            "size mismatch for service data and service data mask");
-                }
-            }
-            mServiceDataUuid = serviceDataUuid;
-            mServiceData = serviceData;
-            mServiceDataMask = serviceDataMask;
-            return this;
-        }
-
-        /**
-         * Set filter on on manufacturerData. A negative manufacturerId is considered as invalid id.
-         *
-         * @throws IllegalArgumentException If the {@code manufacturerId} is invalid.
-         */
-        public Builder setManufacturerData(int manufacturerId, byte[] manufacturerData) {
-            if (manufacturerData != null && manufacturerId < 0) {
-                throw new IllegalArgumentException("invalid manufacture id");
-            }
-            mManufacturerId = manufacturerId;
-            mManufacturerData = manufacturerData;
-            mManufacturerDataMask = null; // clear manufacturer data mask
-            return this;
-        }
-
-        /**
-         * Set filter on partial manufacture data. For any bit in the mask, set it the 1 if it needs
-         * to match the one in manufacturer data, otherwise set it to 0.
-         * <p>
-         * The {@code manufacturerDataMask} must have the same length of {@code manufacturerData}.
-         *
-         * @throws IllegalArgumentException If the {@code manufacturerId} is invalid, or {@code
-         * manufacturerData} is null while {@code manufacturerDataMask} is not, or {@code
-         * manufacturerData} and {@code manufacturerDataMask} have different length.
-         */
-        public Builder setManufacturerData(int manufacturerId, byte[] manufacturerData,
-                byte[] manufacturerDataMask) {
-            if (manufacturerData != null && manufacturerId < 0) {
-                throw new IllegalArgumentException("invalid manufacture id");
-            }
-            if (mManufacturerDataMask != null) {
-                if (mManufacturerData == null) {
-                    throw new IllegalArgumentException(
-                            "manufacturerData is null while manufacturerDataMask is not null");
-                }
-                // Since the mManufacturerDataMask is a bit mask for mManufacturerData, the lengths
-                // of the two byte array need to be the same.
-                if (mManufacturerData.length != mManufacturerDataMask.length) {
-                    throw new IllegalArgumentException(
-                            "size mismatch for manufacturerData and manufacturerDataMask");
-                }
-            }
-            mManufacturerId = manufacturerId;
-            mManufacturerData = manufacturerData;
-            mManufacturerDataMask = manufacturerDataMask;
-            return this;
-        }
-
-        /**
-         * Build {@link ScanFilter}.
-         *
-         * @throws IllegalArgumentException If the filter cannot be built.
-         */
-        public ScanFilter build() {
-            return new ScanFilter(mDeviceName, mDeviceAddress,
-                    mServiceUuid, mUuidMask, mServiceSolicitationUuid,
-                    mServiceSolicitationUuidMask,
-                    mServiceDataUuid, mServiceData, mServiceDataMask,
-                    mManufacturerId, mManufacturerData, mManufacturerDataMask,
-                    mAddressType, mIrk);
-        }
-    }
-}
diff --git a/core/java/android/bluetooth/le/ScanRecord.java b/core/java/android/bluetooth/le/ScanRecord.java
deleted file mode 100644
index 9b8c2ea..0000000
--- a/core/java/android/bluetooth/le/ScanRecord.java
+++ /dev/null
@@ -1,378 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.le;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SuppressLint;
-import android.bluetooth.BluetoothUuid;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.os.ParcelUuid;
-import android.util.ArrayMap;
-import android.util.Log;
-import android.util.SparseArray;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import java.util.function.Predicate;
-
-/**
- * Represents a scan record from Bluetooth LE scan.
- */
-@SuppressLint("AndroidFrameworkBluetoothPermission")
-public final class ScanRecord {
-
-    private static final String TAG = "ScanRecord";
-
-    // The following data type values are assigned by Bluetooth SIG.
-    // For more details refer to Bluetooth 4.1 specification, Volume 3, Part C, Section 18.
-    private static final int DATA_TYPE_FLAGS = 0x01;
-    private static final int DATA_TYPE_SERVICE_UUIDS_16_BIT_PARTIAL = 0x02;
-    private static final int DATA_TYPE_SERVICE_UUIDS_16_BIT_COMPLETE = 0x03;
-    private static final int DATA_TYPE_SERVICE_UUIDS_32_BIT_PARTIAL = 0x04;
-    private static final int DATA_TYPE_SERVICE_UUIDS_32_BIT_COMPLETE = 0x05;
-    private static final int DATA_TYPE_SERVICE_UUIDS_128_BIT_PARTIAL = 0x06;
-    private static final int DATA_TYPE_SERVICE_UUIDS_128_BIT_COMPLETE = 0x07;
-    private static final int DATA_TYPE_LOCAL_NAME_SHORT = 0x08;
-    private static final int DATA_TYPE_LOCAL_NAME_COMPLETE = 0x09;
-    private static final int DATA_TYPE_TX_POWER_LEVEL = 0x0A;
-    private static final int DATA_TYPE_SERVICE_DATA_16_BIT = 0x16;
-    private static final int DATA_TYPE_SERVICE_DATA_32_BIT = 0x20;
-    private static final int DATA_TYPE_SERVICE_DATA_128_BIT = 0x21;
-    private static final int DATA_TYPE_SERVICE_SOLICITATION_UUIDS_16_BIT = 0x14;
-    private static final int DATA_TYPE_SERVICE_SOLICITATION_UUIDS_32_BIT = 0x1F;
-    private static final int DATA_TYPE_SERVICE_SOLICITATION_UUIDS_128_BIT = 0x15;
-    private static final int DATA_TYPE_MANUFACTURER_SPECIFIC_DATA = 0xFF;
-
-    // Flags of the advertising data.
-    private final int mAdvertiseFlags;
-
-    @Nullable
-    private final List<ParcelUuid> mServiceUuids;
-    @Nullable
-    private final List<ParcelUuid> mServiceSolicitationUuids;
-
-    private final SparseArray<byte[]> mManufacturerSpecificData;
-
-    private final Map<ParcelUuid, byte[]> mServiceData;
-
-    // Transmission power level(in dB).
-    private final int mTxPowerLevel;
-
-    // Local name of the Bluetooth LE device.
-    private final String mDeviceName;
-
-    // Raw bytes of scan record.
-    private final byte[] mBytes;
-
-    /**
-     * Returns the advertising flags indicating the discoverable mode and capability of the device.
-     * Returns -1 if the flag field is not set.
-     */
-    public int getAdvertiseFlags() {
-        return mAdvertiseFlags;
-    }
-
-    /**
-     * Returns a list of service UUIDs within the advertisement that are used to identify the
-     * bluetooth GATT services.
-     */
-    public List<ParcelUuid> getServiceUuids() {
-        return mServiceUuids;
-    }
-
-    /**
-     * Returns a list of service solicitation UUIDs within the advertisement that are used to
-     * identify the Bluetooth GATT services.
-     */
-    @NonNull
-    public List<ParcelUuid> getServiceSolicitationUuids() {
-        return mServiceSolicitationUuids;
-    }
-
-    /**
-     * Returns a sparse array of manufacturer identifier and its corresponding manufacturer specific
-     * data.
-     */
-    public SparseArray<byte[]> getManufacturerSpecificData() {
-        return mManufacturerSpecificData;
-    }
-
-    /**
-     * Returns the manufacturer specific data associated with the manufacturer id. Returns
-     * {@code null} if the {@code manufacturerId} is not found.
-     */
-    @Nullable
-    public byte[] getManufacturerSpecificData(int manufacturerId) {
-        if (mManufacturerSpecificData == null) {
-            return null;
-        }
-        return mManufacturerSpecificData.get(manufacturerId);
-    }
-
-    /**
-     * Returns a map of service UUID and its corresponding service data.
-     */
-    public Map<ParcelUuid, byte[]> getServiceData() {
-        return mServiceData;
-    }
-
-    /**
-     * Returns the service data byte array associated with the {@code serviceUuid}. Returns
-     * {@code null} if the {@code serviceDataUuid} is not found.
-     */
-    @Nullable
-    public byte[] getServiceData(ParcelUuid serviceDataUuid) {
-        if (serviceDataUuid == null || mServiceData == null) {
-            return null;
-        }
-        return mServiceData.get(serviceDataUuid);
-    }
-
-    /**
-     * Returns the transmission power level of the packet in dBm. Returns {@link Integer#MIN_VALUE}
-     * if the field is not set. This value can be used to calculate the path loss of a received
-     * packet using the following equation:
-     * <p>
-     * <code>pathloss = txPowerLevel - rssi</code>
-     */
-    public int getTxPowerLevel() {
-        return mTxPowerLevel;
-    }
-
-    /**
-     * Returns the local name of the BLE device. This is a UTF-8 encoded string.
-     */
-    @Nullable
-    public String getDeviceName() {
-        return mDeviceName;
-    }
-
-    /**
-     * Returns raw bytes of scan record.
-     */
-    public byte[] getBytes() {
-        return mBytes;
-    }
-
-    /**
-     * Test if any fields contained inside this scan record are matched by the
-     * given matcher.
-     *
-     * @hide
-     */
-    public boolean matchesAnyField(@NonNull Predicate<byte[]> matcher) {
-        int pos = 0;
-        while (pos < mBytes.length) {
-            final int length = mBytes[pos] & 0xFF;
-            if (length == 0) {
-                break;
-            }
-            if (matcher.test(Arrays.copyOfRange(mBytes, pos, pos + length + 1))) {
-                return true;
-            }
-            pos += length + 1;
-        }
-        return false;
-    }
-
-    private ScanRecord(List<ParcelUuid> serviceUuids,
-            List<ParcelUuid> serviceSolicitationUuids,
-            SparseArray<byte[]> manufacturerData,
-            Map<ParcelUuid, byte[]> serviceData,
-            int advertiseFlags, int txPowerLevel,
-            String localName, byte[] bytes) {
-        mServiceSolicitationUuids = serviceSolicitationUuids;
-        mServiceUuids = serviceUuids;
-        mManufacturerSpecificData = manufacturerData;
-        mServiceData = serviceData;
-        mDeviceName = localName;
-        mAdvertiseFlags = advertiseFlags;
-        mTxPowerLevel = txPowerLevel;
-        mBytes = bytes;
-    }
-
-    /**
-     * Parse scan record bytes to {@link ScanRecord}.
-     * <p>
-     * The format is defined in Bluetooth 4.1 specification, Volume 3, Part C, Section 11 and 18.
-     * <p>
-     * All numerical multi-byte entities and values shall use little-endian <strong>byte</strong>
-     * order.
-     *
-     * @param scanRecord The scan record of Bluetooth LE advertisement and/or scan response.
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public static ScanRecord parseFromBytes(byte[] scanRecord) {
-        if (scanRecord == null) {
-            return null;
-        }
-
-        int currentPos = 0;
-        int advertiseFlag = -1;
-        List<ParcelUuid> serviceUuids = new ArrayList<ParcelUuid>();
-        List<ParcelUuid> serviceSolicitationUuids = new ArrayList<ParcelUuid>();
-        String localName = null;
-        int txPowerLevel = Integer.MIN_VALUE;
-
-        SparseArray<byte[]> manufacturerData = new SparseArray<byte[]>();
-        Map<ParcelUuid, byte[]> serviceData = new ArrayMap<ParcelUuid, byte[]>();
-
-        try {
-            while (currentPos < scanRecord.length) {
-                // length is unsigned int.
-                int length = scanRecord[currentPos++] & 0xFF;
-                if (length == 0) {
-                    break;
-                }
-                // Note the length includes the length of the field type itself.
-                int dataLength = length - 1;
-                // fieldType is unsigned int.
-                int fieldType = scanRecord[currentPos++] & 0xFF;
-                switch (fieldType) {
-                    case DATA_TYPE_FLAGS:
-                        advertiseFlag = scanRecord[currentPos] & 0xFF;
-                        break;
-                    case DATA_TYPE_SERVICE_UUIDS_16_BIT_PARTIAL:
-                    case DATA_TYPE_SERVICE_UUIDS_16_BIT_COMPLETE:
-                        parseServiceUuid(scanRecord, currentPos,
-                                dataLength, BluetoothUuid.UUID_BYTES_16_BIT, serviceUuids);
-                        break;
-                    case DATA_TYPE_SERVICE_UUIDS_32_BIT_PARTIAL:
-                    case DATA_TYPE_SERVICE_UUIDS_32_BIT_COMPLETE:
-                        parseServiceUuid(scanRecord, currentPos, dataLength,
-                                BluetoothUuid.UUID_BYTES_32_BIT, serviceUuids);
-                        break;
-                    case DATA_TYPE_SERVICE_UUIDS_128_BIT_PARTIAL:
-                    case DATA_TYPE_SERVICE_UUIDS_128_BIT_COMPLETE:
-                        parseServiceUuid(scanRecord, currentPos, dataLength,
-                                BluetoothUuid.UUID_BYTES_128_BIT, serviceUuids);
-                        break;
-                    case DATA_TYPE_SERVICE_SOLICITATION_UUIDS_16_BIT:
-                        parseServiceSolicitationUuid(scanRecord, currentPos, dataLength,
-                                BluetoothUuid.UUID_BYTES_16_BIT, serviceSolicitationUuids);
-                        break;
-                    case DATA_TYPE_SERVICE_SOLICITATION_UUIDS_32_BIT:
-                        parseServiceSolicitationUuid(scanRecord, currentPos, dataLength,
-                                BluetoothUuid.UUID_BYTES_32_BIT, serviceSolicitationUuids);
-                        break;
-                    case DATA_TYPE_SERVICE_SOLICITATION_UUIDS_128_BIT:
-                        parseServiceSolicitationUuid(scanRecord, currentPos, dataLength,
-                                BluetoothUuid.UUID_BYTES_128_BIT, serviceSolicitationUuids);
-                        break;
-                    case DATA_TYPE_LOCAL_NAME_SHORT:
-                    case DATA_TYPE_LOCAL_NAME_COMPLETE:
-                        localName = new String(
-                                extractBytes(scanRecord, currentPos, dataLength));
-                        break;
-                    case DATA_TYPE_TX_POWER_LEVEL:
-                        txPowerLevel = scanRecord[currentPos];
-                        break;
-                    case DATA_TYPE_SERVICE_DATA_16_BIT:
-                    case DATA_TYPE_SERVICE_DATA_32_BIT:
-                    case DATA_TYPE_SERVICE_DATA_128_BIT:
-                        int serviceUuidLength = BluetoothUuid.UUID_BYTES_16_BIT;
-                        if (fieldType == DATA_TYPE_SERVICE_DATA_32_BIT) {
-                            serviceUuidLength = BluetoothUuid.UUID_BYTES_32_BIT;
-                        } else if (fieldType == DATA_TYPE_SERVICE_DATA_128_BIT) {
-                            serviceUuidLength = BluetoothUuid.UUID_BYTES_128_BIT;
-                        }
-
-                        byte[] serviceDataUuidBytes = extractBytes(scanRecord, currentPos,
-                                serviceUuidLength);
-                        ParcelUuid serviceDataUuid = BluetoothUuid.parseUuidFrom(
-                                serviceDataUuidBytes);
-                        byte[] serviceDataArray = extractBytes(scanRecord,
-                                currentPos + serviceUuidLength, dataLength - serviceUuidLength);
-                        serviceData.put(serviceDataUuid, serviceDataArray);
-                        break;
-                    case DATA_TYPE_MANUFACTURER_SPECIFIC_DATA:
-                        // The first two bytes of the manufacturer specific data are
-                        // manufacturer ids in little endian.
-                        int manufacturerId = ((scanRecord[currentPos + 1] & 0xFF) << 8)
-                                + (scanRecord[currentPos] & 0xFF);
-                        byte[] manufacturerDataBytes = extractBytes(scanRecord, currentPos + 2,
-                                dataLength - 2);
-                        manufacturerData.put(manufacturerId, manufacturerDataBytes);
-                        break;
-                    default:
-                        // Just ignore, we don't handle such data type.
-                        break;
-                }
-                currentPos += dataLength;
-            }
-
-            if (serviceUuids.isEmpty()) {
-                serviceUuids = null;
-            }
-            return new ScanRecord(serviceUuids, serviceSolicitationUuids, manufacturerData,
-                    serviceData, advertiseFlag, txPowerLevel, localName, scanRecord);
-        } catch (Exception e) {
-            Log.e(TAG, "unable to parse scan record: " + Arrays.toString(scanRecord));
-            // As the record is invalid, ignore all the parsed results for this packet
-            // and return an empty record with raw scanRecord bytes in results
-            return new ScanRecord(null, null, null, null, -1, Integer.MIN_VALUE, null, scanRecord);
-        }
-    }
-
-    @Override
-    public String toString() {
-        return "ScanRecord [mAdvertiseFlags=" + mAdvertiseFlags + ", mServiceUuids=" + mServiceUuids
-                + ", mServiceSolicitationUuids=" + mServiceSolicitationUuids
-                + ", mManufacturerSpecificData=" + BluetoothLeUtils.toString(
-                mManufacturerSpecificData)
-                + ", mServiceData=" + BluetoothLeUtils.toString(mServiceData)
-                + ", mTxPowerLevel=" + mTxPowerLevel + ", mDeviceName=" + mDeviceName + "]";
-    }
-
-    // Parse service UUIDs.
-    private static int parseServiceUuid(byte[] scanRecord, int currentPos, int dataLength,
-            int uuidLength, List<ParcelUuid> serviceUuids) {
-        while (dataLength > 0) {
-            byte[] uuidBytes = extractBytes(scanRecord, currentPos,
-                    uuidLength);
-            serviceUuids.add(BluetoothUuid.parseUuidFrom(uuidBytes));
-            dataLength -= uuidLength;
-            currentPos += uuidLength;
-        }
-        return currentPos;
-    }
-
-    /**
-     * Parse service Solicitation UUIDs.
-     */
-    private static int parseServiceSolicitationUuid(byte[] scanRecord, int currentPos,
-            int dataLength, int uuidLength, List<ParcelUuid> serviceSolicitationUuids) {
-        while (dataLength > 0) {
-            byte[] uuidBytes = extractBytes(scanRecord, currentPos, uuidLength);
-            serviceSolicitationUuids.add(BluetoothUuid.parseUuidFrom(uuidBytes));
-            dataLength -= uuidLength;
-            currentPos += uuidLength;
-        }
-        return currentPos;
-    }
-
-    // Helper method to extract bytes from byte array.
-    private static byte[] extractBytes(byte[] scanRecord, int start, int length) {
-        byte[] bytes = new byte[length];
-        System.arraycopy(scanRecord, start, bytes, 0, length);
-        return bytes;
-    }
-}
diff --git a/core/java/android/bluetooth/le/ScanResult.java b/core/java/android/bluetooth/le/ScanResult.java
deleted file mode 100644
index f437d86..0000000
--- a/core/java/android/bluetooth/le/ScanResult.java
+++ /dev/null
@@ -1,361 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.le;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.bluetooth.Attributable;
-import android.bluetooth.BluetoothDevice;
-import android.content.AttributionSource;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.Objects;
-
-/**
- * ScanResult for Bluetooth LE scan.
- */
-public final class ScanResult implements Parcelable, Attributable {
-
-    /**
-     * For chained advertisements, inidcates tha the data contained in this
-     * scan result is complete.
-     */
-    public static final int DATA_COMPLETE = 0x00;
-
-    /**
-     * For chained advertisements, indicates that the controller was
-     * unable to receive all chained packets and the scan result contains
-     * incomplete truncated data.
-     */
-    public static final int DATA_TRUNCATED = 0x02;
-
-    /**
-     * Indicates that the secondary physical layer was not used.
-     */
-    public static final int PHY_UNUSED = 0x00;
-
-    /**
-     * Advertising Set ID is not present in the packet.
-     */
-    public static final int SID_NOT_PRESENT = 0xFF;
-
-    /**
-     * TX power is not present in the packet.
-     */
-    public static final int TX_POWER_NOT_PRESENT = 0x7F;
-
-    /**
-     * Periodic advertising interval is not present in the packet.
-     */
-    public static final int PERIODIC_INTERVAL_NOT_PRESENT = 0x00;
-
-    /**
-     * Mask for checking whether event type represents legacy advertisement.
-     */
-    private static final int ET_LEGACY_MASK = 0x10;
-
-    /**
-     * Mask for checking whether event type represents connectable advertisement.
-     */
-    private static final int ET_CONNECTABLE_MASK = 0x01;
-
-    // Remote Bluetooth device.
-    private BluetoothDevice mDevice;
-
-    // Scan record, including advertising data and scan response data.
-    @Nullable
-    private ScanRecord mScanRecord;
-
-    // Received signal strength.
-    private int mRssi;
-
-    // Device timestamp when the result was last seen.
-    private long mTimestampNanos;
-
-    private int mEventType;
-    private int mPrimaryPhy;
-    private int mSecondaryPhy;
-    private int mAdvertisingSid;
-    private int mTxPower;
-    private int mPeriodicAdvertisingInterval;
-
-    /**
-     * Constructs a new ScanResult.
-     *
-     * @param device Remote Bluetooth device found.
-     * @param scanRecord Scan record including both advertising data and scan response data.
-     * @param rssi Received signal strength.
-     * @param timestampNanos Timestamp at which the scan result was observed.
-     * @deprecated use {@link #ScanResult(BluetoothDevice, int, int, int, int, int, int, int,
-     * ScanRecord, long)}
-     */
-    @Deprecated
-    public ScanResult(BluetoothDevice device, ScanRecord scanRecord, int rssi,
-            long timestampNanos) {
-        mDevice = device;
-        mScanRecord = scanRecord;
-        mRssi = rssi;
-        mTimestampNanos = timestampNanos;
-        mEventType = (DATA_COMPLETE << 5) | ET_LEGACY_MASK | ET_CONNECTABLE_MASK;
-        mPrimaryPhy = BluetoothDevice.PHY_LE_1M;
-        mSecondaryPhy = PHY_UNUSED;
-        mAdvertisingSid = SID_NOT_PRESENT;
-        mTxPower = 127;
-        mPeriodicAdvertisingInterval = 0;
-    }
-
-    /**
-     * Constructs a new ScanResult.
-     *
-     * @param device Remote Bluetooth device found.
-     * @param eventType Event type.
-     * @param primaryPhy Primary advertising phy.
-     * @param secondaryPhy Secondary advertising phy.
-     * @param advertisingSid Advertising set ID.
-     * @param txPower Transmit power.
-     * @param rssi Received signal strength.
-     * @param periodicAdvertisingInterval Periodic advertising interval.
-     * @param scanRecord Scan record including both advertising data and scan response data.
-     * @param timestampNanos Timestamp at which the scan result was observed.
-     */
-    public ScanResult(BluetoothDevice device, int eventType, int primaryPhy, int secondaryPhy,
-            int advertisingSid, int txPower, int rssi, int periodicAdvertisingInterval,
-            ScanRecord scanRecord, long timestampNanos) {
-        mDevice = device;
-        mEventType = eventType;
-        mPrimaryPhy = primaryPhy;
-        mSecondaryPhy = secondaryPhy;
-        mAdvertisingSid = advertisingSid;
-        mTxPower = txPower;
-        mRssi = rssi;
-        mPeriodicAdvertisingInterval = periodicAdvertisingInterval;
-        mScanRecord = scanRecord;
-        mTimestampNanos = timestampNanos;
-    }
-
-    private ScanResult(Parcel in) {
-        readFromParcel(in);
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        if (mDevice != null) {
-            dest.writeInt(1);
-            mDevice.writeToParcel(dest, flags);
-        } else {
-            dest.writeInt(0);
-        }
-        if (mScanRecord != null) {
-            dest.writeInt(1);
-            dest.writeByteArray(mScanRecord.getBytes());
-        } else {
-            dest.writeInt(0);
-        }
-        dest.writeInt(mRssi);
-        dest.writeLong(mTimestampNanos);
-        dest.writeInt(mEventType);
-        dest.writeInt(mPrimaryPhy);
-        dest.writeInt(mSecondaryPhy);
-        dest.writeInt(mAdvertisingSid);
-        dest.writeInt(mTxPower);
-        dest.writeInt(mPeriodicAdvertisingInterval);
-    }
-
-    private void readFromParcel(Parcel in) {
-        if (in.readInt() == 1) {
-            mDevice = BluetoothDevice.CREATOR.createFromParcel(in);
-        }
-        if (in.readInt() == 1) {
-            mScanRecord = ScanRecord.parseFromBytes(in.createByteArray());
-        }
-        mRssi = in.readInt();
-        mTimestampNanos = in.readLong();
-        mEventType = in.readInt();
-        mPrimaryPhy = in.readInt();
-        mSecondaryPhy = in.readInt();
-        mAdvertisingSid = in.readInt();
-        mTxPower = in.readInt();
-        mPeriodicAdvertisingInterval = in.readInt();
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    /** {@hide} */
-    public void setAttributionSource(@NonNull AttributionSource attributionSource) {
-        Attributable.setAttributionSource(mDevice, attributionSource);
-    }
-
-    /**
-     * Returns the remote Bluetooth device identified by the Bluetooth device address.
-     */
-    public BluetoothDevice getDevice() {
-        return mDevice;
-    }
-
-    /**
-     * Returns the scan record, which is a combination of advertisement and scan response.
-     */
-    @Nullable
-    public ScanRecord getScanRecord() {
-        return mScanRecord;
-    }
-
-    /**
-     * Returns the received signal strength in dBm. The valid range is [-127, 126].
-     */
-    public int getRssi() {
-        return mRssi;
-    }
-
-    /**
-     * Returns timestamp since boot when the scan record was observed.
-     */
-    public long getTimestampNanos() {
-        return mTimestampNanos;
-    }
-
-    /**
-     * Returns true if this object represents legacy scan result.
-     * Legacy scan results do not contain advanced advertising information
-     * as specified in the Bluetooth Core Specification v5.
-     */
-    public boolean isLegacy() {
-        return (mEventType & ET_LEGACY_MASK) != 0;
-    }
-
-    /**
-     * Returns true if this object represents connectable scan result.
-     */
-    public boolean isConnectable() {
-        return (mEventType & ET_CONNECTABLE_MASK) != 0;
-    }
-
-    /**
-     * Returns the data status.
-     * Can be one of {@link ScanResult#DATA_COMPLETE} or
-     * {@link ScanResult#DATA_TRUNCATED}.
-     */
-    public int getDataStatus() {
-        // return bit 5 and 6
-        return (mEventType >> 5) & 0x03;
-    }
-
-    /**
-     * Returns the primary Physical Layer
-     * on which this advertisment was received.
-     * Can be one of {@link BluetoothDevice#PHY_LE_1M} or
-     * {@link BluetoothDevice#PHY_LE_CODED}.
-     */
-    public int getPrimaryPhy() {
-        return mPrimaryPhy;
-    }
-
-    /**
-     * Returns the secondary Physical Layer
-     * on which this advertisment was received.
-     * Can be one of {@link BluetoothDevice#PHY_LE_1M},
-     * {@link BluetoothDevice#PHY_LE_2M}, {@link BluetoothDevice#PHY_LE_CODED}
-     * or {@link ScanResult#PHY_UNUSED} - if the advertisement
-     * was not received on a secondary physical channel.
-     */
-    public int getSecondaryPhy() {
-        return mSecondaryPhy;
-    }
-
-    /**
-     * Returns the advertising set id.
-     * May return {@link ScanResult#SID_NOT_PRESENT} if
-     * no set id was is present.
-     */
-    public int getAdvertisingSid() {
-        return mAdvertisingSid;
-    }
-
-    /**
-     * Returns the transmit power in dBm.
-     * Valid range is [-127, 126]. A value of {@link ScanResult#TX_POWER_NOT_PRESENT}
-     * indicates that the TX power is not present.
-     */
-    public int getTxPower() {
-        return mTxPower;
-    }
-
-    /**
-     * Returns the periodic advertising interval in units of 1.25ms.
-     * Valid range is 6 (7.5ms) to 65536 (81918.75ms). A value of
-     * {@link ScanResult#PERIODIC_INTERVAL_NOT_PRESENT} means periodic
-     * advertising interval is not present.
-     */
-    public int getPeriodicAdvertisingInterval() {
-        return mPeriodicAdvertisingInterval;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(mDevice, mRssi, mScanRecord, mTimestampNanos,
-                mEventType, mPrimaryPhy, mSecondaryPhy,
-                mAdvertisingSid, mTxPower,
-                mPeriodicAdvertisingInterval);
-    }
-
-    @Override
-    public boolean equals(@Nullable Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj == null || getClass() != obj.getClass()) {
-            return false;
-        }
-        ScanResult other = (ScanResult) obj;
-        return Objects.equals(mDevice, other.mDevice) && (mRssi == other.mRssi)
-                && Objects.equals(mScanRecord, other.mScanRecord)
-                && (mTimestampNanos == other.mTimestampNanos)
-                && mEventType == other.mEventType
-                && mPrimaryPhy == other.mPrimaryPhy
-                && mSecondaryPhy == other.mSecondaryPhy
-                && mAdvertisingSid == other.mAdvertisingSid
-                && mTxPower == other.mTxPower
-                && mPeriodicAdvertisingInterval == other.mPeriodicAdvertisingInterval;
-    }
-
-    @Override
-    public String toString() {
-        return "ScanResult{" + "device=" + mDevice + ", scanRecord="
-                + Objects.toString(mScanRecord) + ", rssi=" + mRssi
-                + ", timestampNanos=" + mTimestampNanos + ", eventType=" + mEventType
-                + ", primaryPhy=" + mPrimaryPhy + ", secondaryPhy=" + mSecondaryPhy
-                + ", advertisingSid=" + mAdvertisingSid + ", txPower=" + mTxPower
-                + ", periodicAdvertisingInterval=" + mPeriodicAdvertisingInterval + '}';
-    }
-
-    public static final @android.annotation.NonNull Parcelable.Creator<ScanResult> CREATOR = new Creator<ScanResult>() {
-        @Override
-        public ScanResult createFromParcel(Parcel source) {
-            return new ScanResult(source);
-        }
-
-        @Override
-        public ScanResult[] newArray(int size) {
-            return new ScanResult[size];
-        }
-    };
-
-}
diff --git a/core/java/android/bluetooth/le/ScanSettings.java b/core/java/android/bluetooth/le/ScanSettings.java
deleted file mode 100644
index 1aa7cb5..0000000
--- a/core/java/android/bluetooth/le/ScanSettings.java
+++ /dev/null
@@ -1,438 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.le;
-
-import android.annotation.SystemApi;
-import android.bluetooth.BluetoothDevice;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Bluetooth LE scan settings are passed to {@link BluetoothLeScanner#startScan} to define the
- * parameters for the scan.
- */
-public final class ScanSettings implements Parcelable {
-
-    /**
-     * A special Bluetooth LE scan mode. Applications using this scan mode will passively listen for
-     * other scan results without starting BLE scans themselves.
-     */
-    public static final int SCAN_MODE_OPPORTUNISTIC = -1;
-
-    /**
-     * Perform Bluetooth LE scan in low power mode. This is the default scan mode as it consumes the
-     * least power. This mode is enforced if the scanning application is not in foreground.
-     */
-    public static final int SCAN_MODE_LOW_POWER = 0;
-
-    /**
-     * Perform Bluetooth LE scan in balanced power mode. Scan results are returned at a rate that
-     * provides a good trade-off between scan frequency and power consumption.
-     */
-    public static final int SCAN_MODE_BALANCED = 1;
-
-    /**
-     * Scan using highest duty cycle. It's recommended to only use this mode when the application is
-     * running in the foreground.
-     */
-    public static final int SCAN_MODE_LOW_LATENCY = 2;
-
-    /**
-     * Perform Bluetooth LE scan in ambient discovery mode. This mode has lower duty cycle and more
-     * aggressive scan interval than balanced mode that provides a good trade-off between scan
-     * latency and power consumption.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int SCAN_MODE_AMBIENT_DISCOVERY = 3;
-
-    /**
-     * Trigger a callback for every Bluetooth advertisement found that matches the filter criteria.
-     * If no filter is active, all advertisement packets are reported.
-     */
-    public static final int CALLBACK_TYPE_ALL_MATCHES = 1;
-
-    /**
-     * A result callback is only triggered for the first advertisement packet received that matches
-     * the filter criteria.
-     */
-    public static final int CALLBACK_TYPE_FIRST_MATCH = 2;
-
-    /**
-     * Receive a callback when advertisements are no longer received from a device that has been
-     * previously reported by a first match callback.
-     */
-    public static final int CALLBACK_TYPE_MATCH_LOST = 4;
-
-
-    /**
-     * Determines how many advertisements to match per filter, as this is scarce hw resource
-     */
-    /**
-     * Match one advertisement per filter
-     */
-    public static final int MATCH_NUM_ONE_ADVERTISEMENT = 1;
-
-    /**
-     * Match few advertisement per filter, depends on current capability and availibility of
-     * the resources in hw
-     */
-    public static final int MATCH_NUM_FEW_ADVERTISEMENT = 2;
-
-    /**
-     * Match as many advertisement per filter as hw could allow, depends on current
-     * capability and availibility of the resources in hw
-     */
-    public static final int MATCH_NUM_MAX_ADVERTISEMENT = 3;
-
-
-    /**
-     * In Aggressive mode, hw will determine a match sooner even with feeble signal strength
-     * and few number of sightings/match in a duration.
-     */
-    public static final int MATCH_MODE_AGGRESSIVE = 1;
-
-    /**
-     * For sticky mode, higher threshold of signal strength and sightings is required
-     * before reporting by hw
-     */
-    public static final int MATCH_MODE_STICKY = 2;
-
-    /**
-     * Request full scan results which contain the device, rssi, advertising data, scan response
-     * as well as the scan timestamp.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int SCAN_RESULT_TYPE_FULL = 0;
-
-    /**
-     * Request abbreviated scan results which contain the device, rssi and scan timestamp.
-     * <p>
-     * <b>Note:</b> It is possible for an application to get more scan results than it asked for, if
-     * there are multiple apps using this type.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final int SCAN_RESULT_TYPE_ABBREVIATED = 1;
-
-    /**
-     * Use all supported PHYs for scanning.
-     * This will check the controller capabilities, and start
-     * the scan on 1Mbit and LE Coded PHYs if supported, or on
-     * the 1Mbit PHY only.
-     */
-    public static final int PHY_LE_ALL_SUPPORTED = 255;
-
-    // Bluetooth LE scan mode.
-    private int mScanMode;
-
-    // Bluetooth LE scan callback type
-    private int mCallbackType;
-
-    // Bluetooth LE scan result type
-    private int mScanResultType;
-
-    // Time of delay for reporting the scan result
-    private long mReportDelayMillis;
-
-    private int mMatchMode;
-
-    private int mNumOfMatchesPerFilter;
-
-    // Include only legacy advertising results
-    private boolean mLegacy;
-
-    private int mPhy;
-
-    public int getScanMode() {
-        return mScanMode;
-    }
-
-    public int getCallbackType() {
-        return mCallbackType;
-    }
-
-    public int getScanResultType() {
-        return mScanResultType;
-    }
-
-    /**
-     * @hide
-     */
-    public int getMatchMode() {
-        return mMatchMode;
-    }
-
-    /**
-     * @hide
-     */
-    public int getNumOfMatches() {
-        return mNumOfMatchesPerFilter;
-    }
-
-    /**
-     * Returns whether only legacy advertisements will be returned.
-     * Legacy advertisements include advertisements as specified
-     * by the Bluetooth core specification 4.2 and below.
-     */
-    public boolean getLegacy() {
-        return mLegacy;
-    }
-
-    /**
-     * Returns the physical layer used during a scan.
-     */
-    public int getPhy() {
-        return mPhy;
-    }
-
-    /**
-     * Returns report delay timestamp based on the device clock.
-     */
-    public long getReportDelayMillis() {
-        return mReportDelayMillis;
-    }
-
-    private ScanSettings(int scanMode, int callbackType, int scanResultType,
-            long reportDelayMillis, int matchMode,
-            int numOfMatchesPerFilter, boolean legacy, int phy) {
-        mScanMode = scanMode;
-        mCallbackType = callbackType;
-        mScanResultType = scanResultType;
-        mReportDelayMillis = reportDelayMillis;
-        mNumOfMatchesPerFilter = numOfMatchesPerFilter;
-        mMatchMode = matchMode;
-        mLegacy = legacy;
-        mPhy = phy;
-    }
-
-    private ScanSettings(Parcel in) {
-        mScanMode = in.readInt();
-        mCallbackType = in.readInt();
-        mScanResultType = in.readInt();
-        mReportDelayMillis = in.readLong();
-        mMatchMode = in.readInt();
-        mNumOfMatchesPerFilter = in.readInt();
-        mLegacy = in.readInt() != 0;
-        mPhy = in.readInt();
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(mScanMode);
-        dest.writeInt(mCallbackType);
-        dest.writeInt(mScanResultType);
-        dest.writeLong(mReportDelayMillis);
-        dest.writeInt(mMatchMode);
-        dest.writeInt(mNumOfMatchesPerFilter);
-        dest.writeInt(mLegacy ? 1 : 0);
-        dest.writeInt(mPhy);
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    public static final @android.annotation.NonNull Parcelable.Creator<ScanSettings> CREATOR =
-            new Creator<ScanSettings>() {
-        @Override
-        public ScanSettings[] newArray(int size) {
-            return new ScanSettings[size];
-        }
-
-        @Override
-        public ScanSettings createFromParcel(Parcel in) {
-            return new ScanSettings(in);
-        }
-    };
-
-    /**
-     * Builder for {@link ScanSettings}.
-     */
-    public static final class Builder {
-        private int mScanMode = SCAN_MODE_LOW_POWER;
-        private int mCallbackType = CALLBACK_TYPE_ALL_MATCHES;
-        private int mScanResultType = SCAN_RESULT_TYPE_FULL;
-        private long mReportDelayMillis = 0;
-        private int mMatchMode = MATCH_MODE_AGGRESSIVE;
-        private int mNumOfMatchesPerFilter = MATCH_NUM_MAX_ADVERTISEMENT;
-        private boolean mLegacy = true;
-        private int mPhy = PHY_LE_ALL_SUPPORTED;
-
-        /**
-         * Set scan mode for Bluetooth LE scan.
-         *
-         * @param scanMode The scan mode can be one of {@link ScanSettings#SCAN_MODE_LOW_POWER},
-         * {@link ScanSettings#SCAN_MODE_BALANCED} or {@link ScanSettings#SCAN_MODE_LOW_LATENCY}.
-         * @throws IllegalArgumentException If the {@code scanMode} is invalid.
-         */
-        public Builder setScanMode(int scanMode) {
-            switch (scanMode) {
-                case SCAN_MODE_OPPORTUNISTIC:
-                case SCAN_MODE_LOW_POWER:
-                case SCAN_MODE_BALANCED:
-                case SCAN_MODE_LOW_LATENCY:
-                case SCAN_MODE_AMBIENT_DISCOVERY:
-                    mScanMode = scanMode;
-                    break;
-                default:
-                    throw new IllegalArgumentException("invalid scan mode " + scanMode);
-            }
-            return this;
-        }
-
-        /**
-         * Set callback type for Bluetooth LE scan.
-         *
-         * @param callbackType The callback type flags for the scan.
-         * @throws IllegalArgumentException If the {@code callbackType} is invalid.
-         */
-        public Builder setCallbackType(int callbackType) {
-
-            if (!isValidCallbackType(callbackType)) {
-                throw new IllegalArgumentException("invalid callback type - " + callbackType);
-            }
-            mCallbackType = callbackType;
-            return this;
-        }
-
-        // Returns true if the callbackType is valid.
-        private boolean isValidCallbackType(int callbackType) {
-            if (callbackType == CALLBACK_TYPE_ALL_MATCHES
-                    || callbackType == CALLBACK_TYPE_FIRST_MATCH
-                    || callbackType == CALLBACK_TYPE_MATCH_LOST) {
-                return true;
-            }
-            return callbackType == (CALLBACK_TYPE_FIRST_MATCH | CALLBACK_TYPE_MATCH_LOST);
-        }
-
-        /**
-         * Set scan result type for Bluetooth LE scan.
-         *
-         * @param scanResultType Type for scan result, could be either {@link
-         * ScanSettings#SCAN_RESULT_TYPE_FULL} or {@link ScanSettings#SCAN_RESULT_TYPE_ABBREVIATED}.
-         * @throws IllegalArgumentException If the {@code scanResultType} is invalid.
-         * @hide
-         */
-        @SystemApi
-        public Builder setScanResultType(int scanResultType) {
-            if (scanResultType < SCAN_RESULT_TYPE_FULL
-                    || scanResultType > SCAN_RESULT_TYPE_ABBREVIATED) {
-                throw new IllegalArgumentException(
-                        "invalid scanResultType - " + scanResultType);
-            }
-            mScanResultType = scanResultType;
-            return this;
-        }
-
-        /**
-         * Set report delay timestamp for Bluetooth LE scan. If set to 0, you will be notified of
-         * scan results immediately. If &gt; 0, scan results are queued up and delivered after the
-         * requested delay or 5000 milliseconds (whichever is higher). Note scan results may be
-         * delivered sooner if the internal buffers fill up.
-         *
-         * @param reportDelayMillis         how frequently scan results should be delivered in
-         *                                  milliseconds
-         * @throws IllegalArgumentException if {@code reportDelayMillis} &lt; 0
-         */
-        public Builder setReportDelay(long reportDelayMillis) {
-            if (reportDelayMillis < 0) {
-                throw new IllegalArgumentException("reportDelay must be > 0");
-            }
-            mReportDelayMillis = reportDelayMillis;
-            return this;
-        }
-
-        /**
-         * Set the number of matches for Bluetooth LE scan filters hardware match
-         *
-         * @param numOfMatches The num of matches can be one of
-         * {@link ScanSettings#MATCH_NUM_ONE_ADVERTISEMENT}
-         * or {@link ScanSettings#MATCH_NUM_FEW_ADVERTISEMENT} or {@link
-         * ScanSettings#MATCH_NUM_MAX_ADVERTISEMENT}
-         * @throws IllegalArgumentException If the {@code matchMode} is invalid.
-         */
-        public Builder setNumOfMatches(int numOfMatches) {
-            if (numOfMatches < MATCH_NUM_ONE_ADVERTISEMENT
-                    || numOfMatches > MATCH_NUM_MAX_ADVERTISEMENT) {
-                throw new IllegalArgumentException("invalid numOfMatches " + numOfMatches);
-            }
-            mNumOfMatchesPerFilter = numOfMatches;
-            return this;
-        }
-
-        /**
-         * Set match mode for Bluetooth LE scan filters hardware match
-         *
-         * @param matchMode The match mode can be one of {@link ScanSettings#MATCH_MODE_AGGRESSIVE}
-         * or {@link ScanSettings#MATCH_MODE_STICKY}
-         * @throws IllegalArgumentException If the {@code matchMode} is invalid.
-         */
-        public Builder setMatchMode(int matchMode) {
-            if (matchMode < MATCH_MODE_AGGRESSIVE
-                    || matchMode > MATCH_MODE_STICKY) {
-                throw new IllegalArgumentException("invalid matchMode " + matchMode);
-            }
-            mMatchMode = matchMode;
-            return this;
-        }
-
-        /**
-         * Set whether only legacy advertisments should be returned in scan results.
-         * Legacy advertisements include advertisements as specified by the
-         * Bluetooth core specification 4.2 and below. This is true by default
-         * for compatibility with older apps.
-         *
-         * @param legacy true if only legacy advertisements will be returned
-         */
-        public Builder setLegacy(boolean legacy) {
-            mLegacy = legacy;
-            return this;
-        }
-
-        /**
-         * Set the Physical Layer to use during this scan.
-         * This is used only if {@link ScanSettings.Builder#setLegacy}
-         * is set to false.
-         * {@link android.bluetooth.BluetoothAdapter#isLeCodedPhySupported}
-         * may be used to check whether LE Coded phy is supported by calling
-         * {@link android.bluetooth.BluetoothAdapter#isLeCodedPhySupported}.
-         * Selecting an unsupported phy will result in failure to start scan.
-         *
-         * @param phy Can be one of {@link BluetoothDevice#PHY_LE_1M}, {@link
-         * BluetoothDevice#PHY_LE_CODED} or {@link ScanSettings#PHY_LE_ALL_SUPPORTED}
-         */
-        public Builder setPhy(int phy) {
-            mPhy = phy;
-            return this;
-        }
-
-        /**
-         * Build {@link ScanSettings}.
-         */
-        public ScanSettings build() {
-            return new ScanSettings(mScanMode, mCallbackType, mScanResultType,
-                    mReportDelayMillis, mMatchMode,
-                    mNumOfMatchesPerFilter, mLegacy, mPhy);
-        }
-    }
-}
diff --git a/core/java/android/bluetooth/le/TransportBlock.java b/core/java/android/bluetooth/le/TransportBlock.java
deleted file mode 100644
index 18bad9c..0000000
--- a/core/java/android/bluetooth/le/TransportBlock.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.le;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.Log;
-
-import java.nio.BufferOverflowException;
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-
-/**
- * Wrapper for Transport Discovery Data Transport Blocks.
- * This class represents a Transport Block from a Transport Discovery Data.
- *
- * @see TransportDiscoveryData
- * @see AdvertiseData
- */
-public final class TransportBlock implements Parcelable {
-    private static final String TAG = "TransportBlock";
-    private final int mOrgId;
-    private final int mTdsFlags;
-    private final int mTransportDataLength;
-    private final byte[] mTransportData;
-
-    /**
-     * Creates an instance of TransportBlock from raw data.
-     *
-     * @param orgId the Organization ID
-     * @param tdsFlags the TDS flags
-     * @param transportDataLength the total length of the Transport Data
-     * @param transportData the Transport Data
-     */
-    public TransportBlock(int orgId, int tdsFlags, int transportDataLength,
-            @Nullable byte[] transportData) {
-        mOrgId = orgId;
-        mTdsFlags = tdsFlags;
-        mTransportDataLength = transportDataLength;
-        mTransportData = transportData;
-    }
-
-    private TransportBlock(Parcel in) {
-        mOrgId = in.readInt();
-        mTdsFlags = in.readInt();
-        mTransportDataLength = in.readInt();
-        if (mTransportDataLength > 0) {
-            mTransportData = new byte[mTransportDataLength];
-            in.readByteArray(mTransportData);
-        } else {
-            mTransportData = null;
-        }
-    }
-
-    @Override
-    public void writeToParcel(@NonNull Parcel dest, int flags) {
-        dest.writeInt(mOrgId);
-        dest.writeInt(mTdsFlags);
-        dest.writeInt(mTransportDataLength);
-        if (mTransportData != null) {
-            dest.writeByteArray(mTransportData);
-        }
-    }
-
-    /**
-     * @hide
-     */
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    /**
-     * @hide
-     */
-    @Override
-    public boolean equals(@Nullable Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj == null || getClass() != obj.getClass()) {
-            return false;
-        }
-        TransportBlock other = (TransportBlock) obj;
-        return Arrays.equals(toByteArray(), other.toByteArray());
-    }
-
-    public static final @NonNull Creator<TransportBlock> CREATOR = new Creator<TransportBlock>() {
-        @Override
-        public TransportBlock createFromParcel(Parcel in) {
-            return new TransportBlock(in);
-        }
-
-        @Override
-        public TransportBlock[] newArray(int size) {
-            return new TransportBlock[size];
-        }
-    };
-
-    /**
-     * Gets the Organization ID of the Transport Block which corresponds to one of the
-     * the Bluetooth SIG Assigned Numbers.
-     */
-    public int getOrgId() {
-        return mOrgId;
-    }
-
-    /**
-     * Gets the TDS flags of the Transport Block which represents the role of the device and
-     * information about its state and supported features.
-     */
-    public int getTdsFlags() {
-        return mTdsFlags;
-    }
-
-    /**
-     * Gets the total number of octets in the Transport Data field in this Transport Block.
-     */
-    public int getTransportDataLength() {
-        return mTransportDataLength;
-    }
-
-    /**
-     * Gets the Transport Data of the Transport Block which contains organization-specific data.
-     */
-    @Nullable
-    public byte[] getTransportData() {
-        return mTransportData;
-    }
-
-    /**
-     * Converts this TransportBlock to byte array
-     *
-     * @return byte array representation of this Transport Block or null if the conversion failed
-     */
-    @Nullable
-    public byte[] toByteArray() {
-        try {
-            ByteBuffer buffer = ByteBuffer.allocate(totalBytes());
-            buffer.put((byte) mOrgId);
-            buffer.put((byte) mTdsFlags);
-            buffer.put((byte) mTransportDataLength);
-            if (mTransportData != null) {
-                buffer.put(mTransportData);
-            }
-            return buffer.array();
-        } catch (BufferOverflowException e) {
-            Log.e(TAG, "Error converting to byte array: " + e.toString());
-            return null;
-        }
-    }
-
-    /**
-     * @return total byte count of this TransportBlock
-     */
-    public int totalBytes() {
-        // 3 uint8 + byte[] length
-        int size = 3 + mTransportDataLength;
-        return size;
-    }
-}
diff --git a/core/java/android/bluetooth/le/TransportDiscoveryData.java b/core/java/android/bluetooth/le/TransportDiscoveryData.java
deleted file mode 100644
index 2b52f19..0000000
--- a/core/java/android/bluetooth/le/TransportDiscoveryData.java
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.le;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.Log;
-
-import java.nio.BufferOverflowException;
-import java.nio.BufferUnderflowException;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Wrapper for Transport Discovery Data AD Type.
- * This class contains the Transport Discovery Data AD Type Code as well as
- * a list of potential Transport Blocks.
- *
- * @see AdvertiseData
- */
-public final class TransportDiscoveryData implements Parcelable {
-    private static final String TAG = "TransportDiscoveryData";
-    private final int mTransportDataType;
-    private final List<TransportBlock> mTransportBlocks;
-
-    /**
-     * Creates a TransportDiscoveryData instance.
-     *
-     * @param transportDataType the Transport Discovery Data AD Type
-     * @param transportBlocks the list of Transport Blocks
-     */
-    public TransportDiscoveryData(int transportDataType,
-            @NonNull List<TransportBlock> transportBlocks) {
-        mTransportDataType = transportDataType;
-        mTransportBlocks = transportBlocks;
-    }
-
-    /**
-     * Creates a TransportDiscoveryData instance from byte arrays.
-     *
-     * Uses the transport discovery data bytes and parses them into an usable class.
-     *
-     * @param transportDiscoveryData the raw discovery data
-     */
-    public TransportDiscoveryData(@NonNull byte[] transportDiscoveryData) {
-        ByteBuffer byteBuffer = ByteBuffer.wrap(transportDiscoveryData);
-        mTransportBlocks = new ArrayList();
-        if (byteBuffer.remaining() > 0) {
-            mTransportDataType = byteBuffer.get();
-        } else {
-            mTransportDataType = -1;
-        }
-        try {
-            while (byteBuffer.remaining() > 0) {
-                int orgId = byteBuffer.get();
-                int tdsFlags = byteBuffer.get();
-                int transportDataLength = byteBuffer.get();
-                byte[] transportData = new byte[transportDataLength];
-                byteBuffer.get(transportData, 0, transportDataLength);
-                mTransportBlocks.add(new TransportBlock(orgId, tdsFlags,
-                        transportDataLength, transportData));
-            }
-        } catch (BufferUnderflowException e) {
-            Log.e(TAG, "Error while parsing data: " + e.toString());
-        }
-    }
-
-    private TransportDiscoveryData(Parcel in) {
-        mTransportDataType = in.readInt();
-        mTransportBlocks = in.createTypedArrayList(TransportBlock.CREATOR);
-    }
-
-    /**
-     * @hide
-     */
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    /**
-     * @hide
-     */
-    @Override
-    public boolean equals(@Nullable Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj == null || getClass() != obj.getClass()) {
-            return false;
-        }
-        TransportDiscoveryData other = (TransportDiscoveryData) obj;
-        return Arrays.equals(toByteArray(), other.toByteArray());
-    }
-
-    @Override
-    public void writeToParcel(@NonNull Parcel dest, int flags) {
-        dest.writeInt(mTransportDataType);
-        dest.writeTypedList(mTransportBlocks);
-    }
-
-    public static final @NonNull Creator<TransportDiscoveryData> CREATOR =
-            new Creator<TransportDiscoveryData>() {
-                @Override
-                public TransportDiscoveryData createFromParcel(Parcel in) {
-                    return new TransportDiscoveryData(in);
-                }
-
-                @Override
-                public TransportDiscoveryData[] newArray(int size) {
-                    return new TransportDiscoveryData[size];
-                }
-    };
-
-    /**
-     * Gets the transport data type.
-     */
-    public int getTransportDataType() {
-        return mTransportDataType;
-    }
-
-    /**
-     * @return the list of {@link TransportBlock} in this TransportDiscoveryData
-     *         or an empty list if there are no Transport Blocks
-     */
-    @NonNull
-    public List<TransportBlock> getTransportBlocks() {
-        if (mTransportBlocks == null) {
-            return Collections.emptyList();
-        }
-        return mTransportBlocks;
-    }
-
-    /**
-     * Converts this TransportDiscoveryData to byte array
-     *
-     * @return byte array representation of this Transport Discovery Data or null if the
-     *         conversion failed
-     */
-    @Nullable
-    public byte[] toByteArray() {
-        try {
-            ByteBuffer buffer = ByteBuffer.allocate(totalBytes());
-            buffer.put((byte) mTransportDataType);
-            for (TransportBlock transportBlock : getTransportBlocks()) {
-                buffer.put(transportBlock.toByteArray());
-            }
-            return buffer.array();
-        } catch (BufferOverflowException e) {
-            Log.e(TAG, "Error converting to byte array: " + e.toString());
-            return null;
-        }
-    }
-
-    /**
-     * @return total byte count of this TransportDataDiscovery
-     */
-    public int totalBytes() {
-        int size = 1; // Counting Transport Data Type here.
-        for (TransportBlock transportBlock : getTransportBlocks()) {
-            size += transportBlock.totalBytes();
-        }
-        return size;
-    }
-}
diff --git a/core/java/android/bluetooth/le/TruncatedFilter.java b/core/java/android/bluetooth/le/TruncatedFilter.java
deleted file mode 100644
index 2592588..0000000
--- a/core/java/android/bluetooth/le/TruncatedFilter.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.le;
-
-import android.annotation.SuppressLint;
-import android.annotation.SystemApi;
-
-import java.util.List;
-
-/**
- * A special scan filter that lets the client decide how the scan record should be stored.
- *
- * @deprecated this is not used anywhere
- *
- * @hide
- */
-@Deprecated
-@SystemApi
-@SuppressLint("AndroidFrameworkBluetoothPermission")
-public final class TruncatedFilter {
-    private final ScanFilter mFilter;
-    private final List<ResultStorageDescriptor> mStorageDescriptors;
-
-    /**
-     * Constructor for {@link TruncatedFilter}.
-     *
-     * @param filter Scan filter of the truncated filter.
-     * @param storageDescriptors Describes how the scan should be stored.
-     */
-    public TruncatedFilter(ScanFilter filter, List<ResultStorageDescriptor> storageDescriptors) {
-        mFilter = filter;
-        mStorageDescriptors = storageDescriptors;
-    }
-
-    /**
-     * Returns the scan filter.
-     */
-    public ScanFilter getFilter() {
-        return mFilter;
-    }
-
-    /**
-     * Returns a list of descriptor for scan result storage.
-     */
-    public List<ResultStorageDescriptor> getStorageDescriptors() {
-        return mStorageDescriptors;
-    }
-
-
-}
diff --git a/core/java/android/bluetooth/package.html b/core/java/android/bluetooth/package.html
deleted file mode 100644
index d9ca4f1..0000000
--- a/core/java/android/bluetooth/package.html
+++ /dev/null
@@ -1,38 +0,0 @@
-<HTML>
-<BODY>
-<p>Provides classes that manage Bluetooth functionality, such as scanning for
-devices, connecting with devices, and managing data transfer between devices.
-The Bluetooth API supports both "Classic Bluetooth" and Bluetooth Low Energy.</p>
-
-<p>For more information about Classic Bluetooth, see the
-<a href="{@docRoot}guide/topics/connectivity/bluetooth.html">Bluetooth</a> guide.
-For more information about Bluetooth Low Energy, see the
-<a href="{@docRoot}guide/topics/connectivity/bluetooth-le.html">
-Bluetooth Low Energy</a> (BLE) guide.</p>
-{@more}
-
-<p>The Bluetooth APIs let applications:</p>
-<ul>
-  <li>Scan for other Bluetooth devices (including BLE devices).</li>
-  <li>Query the local Bluetooth adapter for paired Bluetooth devices.</li>
-  <li>Establish RFCOMM channels/sockets.</li>
-  <li>Connect to specified sockets on other devices.</li>
-  <li>Transfer data to and from other devices.</li>
-  <li>Communicate with BLE devices, such as proximity sensors, heart rate
-    monitors, fitness devices, and so on.</li>
-  <li>Act as a GATT client or a GATT server (BLE).</li>
-</ul>
-
-<p>
-To perform Bluetooth communication using these APIs, an application must
-declare the {@link android.Manifest.permission#BLUETOOTH} permission. Some
-additional functionality, such as requesting device discovery,
-also requires the {@link android.Manifest.permission#BLUETOOTH_ADMIN}
-permission.
-</p>
-
-<p class="note"><strong>Note:</strong>
-Not all Android-powered devices provide Bluetooth functionality.</p>
-
-</BODY>
-</HTML>
diff --git a/core/java/android/content/pm/parsing/component/ParsedApexSystemService.java b/core/java/android/content/pm/parsing/component/ParsedApexSystemService.java
index c89d3b2..fe821e0 100644
--- a/core/java/android/content/pm/parsing/component/ParsedApexSystemService.java
+++ b/core/java/android/content/pm/parsing/component/ParsedApexSystemService.java
@@ -35,6 +35,4 @@
     @Nullable
     String getMaxSdkVersion();
 
-    int getInitOrder();
-
 }
diff --git a/core/java/android/content/pm/parsing/component/ParsedApexSystemServiceImpl.java b/core/java/android/content/pm/parsing/component/ParsedApexSystemServiceImpl.java
index 65d26b9..54196fd 100644
--- a/core/java/android/content/pm/parsing/component/ParsedApexSystemServiceImpl.java
+++ b/core/java/android/content/pm/parsing/component/ParsedApexSystemServiceImpl.java
@@ -45,11 +45,10 @@
     @Nullable
     private String maxSdkVersion;
 
-    private int initOrder;
-
     public ParsedApexSystemServiceImpl() {
     }
 
+
     // Code below generated by codegen v1.0.23.
     //
     // DO NOT MODIFY!
@@ -68,15 +67,13 @@
             @NonNull String name,
             @Nullable String jarPath,
             @Nullable String minSdkVersion,
-            @Nullable String maxSdkVersion,
-            int initOrder) {
+            @Nullable String maxSdkVersion) {
         this.name = name;
         com.android.internal.util.AnnotationValidations.validate(
                 NonNull.class, null, name);
         this.jarPath = jarPath;
         this.minSdkVersion = minSdkVersion;
         this.maxSdkVersion = maxSdkVersion;
-        this.initOrder = initOrder;
 
         // onConstructed(); // You can define this method to get a callback
     }
@@ -102,11 +99,6 @@
     }
 
     @DataClass.Generated.Member
-    public int getInitOrder() {
-        return initOrder;
-    }
-
-    @DataClass.Generated.Member
     public @NonNull ParsedApexSystemServiceImpl setName(@NonNull String value) {
         name = value;
         com.android.internal.util.AnnotationValidations.validate(
@@ -133,12 +125,6 @@
     }
 
     @DataClass.Generated.Member
-    public @NonNull ParsedApexSystemServiceImpl setInitOrder( int value) {
-        initOrder = value;
-        return this;
-    }
-
-    @DataClass.Generated.Member
     static Parcelling<String> sParcellingForName =
             Parcelling.Cache.get(
                     Parcelling.BuiltIn.ForInternedString.class);
@@ -197,7 +183,6 @@
         sParcellingForJarPath.parcel(jarPath, dest, flags);
         sParcellingForMinSdkVersion.parcel(minSdkVersion, dest, flags);
         sParcellingForMaxSdkVersion.parcel(maxSdkVersion, dest, flags);
-        dest.writeInt(initOrder);
     }
 
     @Override
@@ -216,7 +201,6 @@
         String _jarPath = sParcellingForJarPath.unparcel(in);
         String _minSdkVersion = sParcellingForMinSdkVersion.unparcel(in);
         String _maxSdkVersion = sParcellingForMaxSdkVersion.unparcel(in);
-        int _initOrder = in.readInt();
 
         this.name = _name;
         com.android.internal.util.AnnotationValidations.validate(
@@ -224,7 +208,6 @@
         this.jarPath = _jarPath;
         this.minSdkVersion = _minSdkVersion;
         this.maxSdkVersion = _maxSdkVersion;
-        this.initOrder = _initOrder;
 
         // onConstructed(); // You can define this method to get a callback
     }
@@ -244,10 +227,10 @@
     };
 
     @DataClass.Generated(
-            time = 1641307133386L,
+            time = 1638903241144L,
             codegenVersion = "1.0.23",
             sourceFile = "frameworks/base/core/java/android/content/pm/parsing/component/ParsedApexSystemServiceImpl.java",
-            inputSignatures = "private @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForInternedString.class) @android.annotation.NonNull java.lang.String name\nprivate @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForInternedString.class) @android.annotation.Nullable java.lang.String jarPath\nprivate @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForInternedString.class) @android.annotation.Nullable java.lang.String minSdkVersion\nprivate @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForInternedString.class) @android.annotation.Nullable java.lang.String maxSdkVersion\nprivate  int initOrder\nclass ParsedApexSystemServiceImpl extends java.lang.Object implements [android.content.pm.parsing.component.ParsedApexSystemService]\n@com.android.internal.util.DataClass(genGetters=true, genAidl=false, genSetters=true, genParcelable=true)")
+            inputSignatures = "private @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForInternedString.class) @android.annotation.NonNull java.lang.String name\nprivate @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForInternedString.class) @android.annotation.Nullable java.lang.String jarPath\nprivate @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForInternedString.class) @android.annotation.Nullable java.lang.String minSdkVersion\nprivate @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForInternedString.class) @android.annotation.Nullable java.lang.String maxSdkVersion\nclass ParsedApexSystemServiceImpl extends java.lang.Object implements [android.content.pm.parsing.component.ParsedApexSystemService]\n@com.android.internal.util.DataClass(genGetters=true, genAidl=false, genSetters=true, genParcelable=true)")
     @Deprecated
     private void __metadata() {}
 
diff --git a/core/java/android/content/pm/parsing/component/ParsedApexSystemServiceUtils.java b/core/java/android/content/pm/parsing/component/ParsedApexSystemServiceUtils.java
index eca8976..26abf48 100644
--- a/core/java/android/content/pm/parsing/component/ParsedApexSystemServiceUtils.java
+++ b/core/java/android/content/pm/parsing/component/ParsedApexSystemServiceUtils.java
@@ -53,13 +53,10 @@
                     R.styleable.AndroidManifestApexSystemService_minSdkVersion);
             String maxSdkVersion = sa.getString(
                     R.styleable.AndroidManifestApexSystemService_maxSdkVersion);
-            int initOrder = sa.getInt(R.styleable.AndroidManifestApexSystemService_initOrder, 0);
 
             systemService.setName(className)
                     .setMinSdkVersion(minSdkVersion)
-                    .setMaxSdkVersion(maxSdkVersion)
-                    .setInitOrder(initOrder);
-
+                    .setMaxSdkVersion(maxSdkVersion);
             if (!TextUtils.isEmpty(jarPath)) {
                 systemService.setJarPath(jarPath);
             }
diff --git a/core/java/android/net/PrivateDnsConnectivityChecker.java b/core/java/android/net/PrivateDnsConnectivityChecker.java
index cfd458c..ac97b36 100644
--- a/core/java/android/net/PrivateDnsConnectivityChecker.java
+++ b/core/java/android/net/PrivateDnsConnectivityChecker.java
@@ -44,7 +44,7 @@
      */
     public static boolean canConnectToPrivateDnsServer(@NonNull String hostname) {
         final SocketFactory factory = SSLSocketFactory.getDefault();
-        TrafficStats.setThreadStatsTag(TrafficStats.TAG_SYSTEM_APP);
+        TrafficStats.setThreadStatsTagApp();
 
         try (SSLSocket socket = (SSLSocket) factory.createSocket()) {
             socket.setSoTimeout(CONNECTION_TIMEOUT_MS);
diff --git a/core/java/android/os/BatteryConsumer.java b/core/java/android/os/BatteryConsumer.java
index c607195..d2f788f 100644
--- a/core/java/android/os/BatteryConsumer.java
+++ b/core/java/android/os/BatteryConsumer.java
@@ -191,6 +191,7 @@
     private static final int[] SUPPORTED_POWER_COMPONENTS_PER_PROCESS_STATE = {
             POWER_COMPONENT_CPU,
             POWER_COMPONENT_MOBILE_RADIO,
+            POWER_COMPONENT_WIFI,
     };
 
     static final int COLUMN_INDEX_BATTERY_CONSUMER_TYPE = 0;
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 520730f..a453887 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -461,6 +461,12 @@
         public abstract long getCountLocked(int which);
 
         /**
+         * Returns the count accumulated by this Counter for the specified process state.
+         * If the counter does not support per-procstate tracking, returns 0.
+         */
+        public abstract long getCountForProcessState(@BatteryConsumer.ProcessState int procState);
+
+        /**
          * Temporary for debugging.
          */
         public abstract void logState(Printer pw, String prefix);
@@ -1096,6 +1102,17 @@
         public abstract long getWifiMeasuredBatteryConsumptionUC();
 
         /**
+         * Returns the battery consumption (in microcoulombs) of the uid's wifi usage when in the
+         * specified process state.
+         * Will return {@link #POWER_DATA_UNAVAILABLE} if data is unavailable.
+         *
+         * {@hide}
+         */
+        public abstract long getWifiMeasuredBatteryConsumptionUC(
+                @BatteryConsumer.ProcessState int processState);
+
+
+        /**
          * Returns the battery consumption (in microcoulombs) used by this uid for each
          * {@link android.hardware.power.stats.EnergyConsumer.ordinal} of (custom) energy consumer
          * type {@link android.hardware.power.stats.EnergyConsumerType#OTHER}).
diff --git a/core/java/android/view/DisplayCutout.java b/core/java/android/view/DisplayCutout.java
index ae323226..9889eaa 100644
--- a/core/java/android/view/DisplayCutout.java
+++ b/core/java/android/view/DisplayCutout.java
@@ -1249,4 +1249,119 @@
             return String.valueOf(mInner);
         }
     }
+
+    /**
+     * A Builder class to construct a DisplayCutout instance.
+     *
+     * <p>Note that this is only for tests purpose. For production code, developers should always
+     * use a {@link DisplayCutout} obtained from the system.</p>
+     */
+    public static final class Builder {
+        private Insets mSafeInsets = Insets.NONE;
+        private Insets mWaterfallInsets = Insets.NONE;
+        private Path mCutoutPath;
+        private final Rect mBoundingRectLeft = new Rect();
+        private final Rect mBoundingRectTop = new Rect();
+        private final Rect mBoundingRectRight = new Rect();
+        private final Rect mBoundingRectBottom = new Rect();
+
+        /**
+         * Begin building a DisplayCutout.
+         */
+        public Builder() {
+        }
+
+        /**
+         * Construct a new {@link DisplayCutout} with the set parameters.
+         */
+        @NonNull
+        public DisplayCutout build() {
+            final CutoutPathParserInfo info;
+            if (mCutoutPath != null) {
+                // Create a fake CutoutPathParserInfo and set it to sCachedCutoutPathParserInfo so
+                // that when getCutoutPath() is called, it will return the cached Path.
+                info = new CutoutPathParserInfo(0, 0, 0, "test", 0, 1f);
+                synchronized (CACHE_LOCK) {
+                    DisplayCutout.sCachedCutoutPathParserInfo = info;
+                    DisplayCutout.sCachedCutoutPath = mCutoutPath;
+                }
+            } else {
+                info = null;
+            }
+            return new DisplayCutout(mSafeInsets.toRect(), mWaterfallInsets, mBoundingRectLeft,
+                    mBoundingRectTop, mBoundingRectRight, mBoundingRectBottom, info, false);
+        }
+
+        /**
+         * Set the safe insets. If not set, the default value is {@link Insets#NONE}.
+         */
+        @SuppressWarnings("MissingGetterMatchingBuilder")
+        @NonNull
+        public Builder setSafeInsets(@NonNull Insets safeInsets) {
+            mSafeInsets = safeInsets;
+            return this;
+        }
+
+        /**
+         * Set the waterfall insets of the DisplayCutout. If not set, the default value is
+         * {@link Insets#NONE}
+         */
+        @NonNull
+        public Builder setWaterfallInsets(@NonNull Insets waterfallInsets) {
+            mWaterfallInsets = waterfallInsets;
+            return this;
+        }
+
+        /**
+         * Set a bounding rectangle for a non-functional area on the display which is located on
+         * the left of the screen. If not set, the default value is an empty rectangle.
+         */
+        @NonNull
+        public Builder setBoundingRectLeft(@NonNull Rect boundingRectLeft) {
+            mBoundingRectLeft.set(boundingRectLeft);
+            return this;
+        }
+
+        /**
+         * Set a bounding rectangle for a non-functional area on the display which is located on
+         * the top of the screen. If not set, the default value is an empty rectangle.
+         */
+        @NonNull
+        public Builder setBoundingRectTop(@NonNull Rect boundingRectTop) {
+            mBoundingRectTop.set(boundingRectTop);
+            return this;
+        }
+
+        /**
+         * Set a bounding rectangle for a non-functional area on the display which is located on
+         * the right of the screen. If not set, the default value is an empty rectangle.
+         */
+        @NonNull
+        public Builder setBoundingRectRight(@NonNull Rect boundingRectRight) {
+            mBoundingRectRight.set(boundingRectRight);
+            return this;
+        }
+
+        /**
+         * Set a bounding rectangle for a non-functional area on the display which is located on
+         * the bottom of the screen. If not set, the default value is an empty rectangle.
+         */
+        @NonNull
+        public Builder setBoundingRectBottom(@NonNull Rect boundingRectBottom) {
+            mBoundingRectBottom.set(boundingRectBottom);
+            return this;
+        }
+
+        /**
+         * Set the cutout {@link Path}.
+         *
+         * Note that not support creating/testing multiple display cutouts with setCutoutPath() in
+         * parallel.
+         */
+        @NonNull
+        public Builder setCutoutPath(@NonNull Path cutoutPath) {
+            mCutoutPath = cutoutPath;
+            return this;
+        }
+    }
 }
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 9429c79..a4183ca8 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -164,7 +164,7 @@
     private static final int MAGIC = 0xBA757475; // 'BATSTATS'
 
     // Current on-disk Parcel version
-    static final int VERSION = 205;
+    static final int VERSION = 206;
 
     // The maximum number of names wakelocks we will keep track of
     // per uid; once the limit is reached, we batch the remaining wakelocks
@@ -214,6 +214,26 @@
     private static final double MILLISECONDS_IN_HOUR = 3600 * 1000;
     private static final long MILLISECONDS_IN_YEAR = 365 * 24 * 3600 * 1000L;
 
+    private static final LongCounter ZERO_LONG_COUNTER = new LongCounter() {
+        @Override
+        public long getCountLocked(int which) {
+            return 0;
+        }
+
+        @Override
+        public long getCountForProcessState(int procState) {
+            return 0;
+        }
+
+        @Override
+        public void logState(Printer pw, String prefix) {
+            pw.println(prefix + "mCount=0");
+        }
+    };
+
+    private static final LongCounter[] ZERO_LONG_COUNTER_ARRAY =
+            new LongCounter[]{ZERO_LONG_COUNTER};
+
     private final KernelWakelockReader mKernelWakelockReader = new KernelWakelockReader();
     private final KernelWakelockStats mTmpWakelockStats = new KernelWakelockStats();
 
@@ -244,6 +264,7 @@
     private static final int[] SUPPORTED_PER_PROCESS_STATE_STANDARD_ENERGY_BUCKETS = {
             MeasuredEnergyStats.POWER_BUCKET_CPU,
             MeasuredEnergyStats.POWER_BUCKET_MOBILE_RADIO,
+            MeasuredEnergyStats.POWER_BUCKET_WIFI,
     };
 
     // TimeInState counters need NUM_PROCESS_STATE states in order to accommodate
@@ -1742,7 +1763,7 @@
         }
     }
 
-    private static class TimeMultiStateCounter implements TimeBaseObs {
+    private static class TimeMultiStateCounter extends LongCounter implements TimeBaseObs {
         private final TimeBase mTimeBase;
         private final LongMultiStateCounter mCounter;
 
@@ -1794,7 +1815,7 @@
         /**
          * Returns accumulated count for the specified state.
          */
-        public long getCountLocked(int procState) {
+        public long getCountForProcessState(@BatteryConsumer.ProcessState int procState) {
             return mCounter.getCount(procState);
         }
 
@@ -1802,6 +1823,12 @@
             return mCounter.getTotalCount();
         }
 
+        @Override
+        public long getCountLocked(int statsType) {
+            return getTotalCountLocked();
+        }
+
+        @Override
         public void logState(Printer pw, String prefix) {
             pw.println(prefix + "mCounter=" + mCounter);
         }
@@ -1947,6 +1974,14 @@
         }
 
         @Override
+        public long getCountForProcessState(int procState) {
+            if (procState == BatteryConsumer.PROCESS_STATE_ANY) {
+                return getCountLocked(STATS_SINCE_CHARGED);
+            }
+            return 0;
+        }
+
+        @Override
         public void logState(Printer pw, String prefix) {
             pw.println(prefix + "mCount=" + mCount);
         }
@@ -3226,57 +3261,50 @@
 
     public static class ControllerActivityCounterImpl extends ControllerActivityCounter
             implements Parcelable {
-        private final LongSamplingCounter mIdleTimeMillis;
+        private final Clock mClock;
+        private final TimeBase mTimeBase;
+        private int mNumTxStates;
+        private int mProcessState;
+        private TimeMultiStateCounter mIdleTimeMillis;
         private final LongSamplingCounter mScanTimeMillis;
         private final LongSamplingCounter mSleepTimeMillis;
-        private final LongSamplingCounter mRxTimeMillis;
-        private final LongSamplingCounter[] mTxTimeMillis;
+        private TimeMultiStateCounter mRxTimeMillis;
+        private TimeMultiStateCounter[] mTxTimeMillis;
         private final LongSamplingCounter mPowerDrainMaMs;
         private final LongSamplingCounter mMonitoredRailChargeConsumedMaMs;
 
-        public ControllerActivityCounterImpl(TimeBase timeBase, int numTxStates) {
-            mIdleTimeMillis = new LongSamplingCounter(timeBase);
+        public ControllerActivityCounterImpl(Clock clock, TimeBase timeBase, int numTxStates) {
+            mClock = clock;
+            mTimeBase = timeBase;
+            mNumTxStates = numTxStates;
             mScanTimeMillis = new LongSamplingCounter(timeBase);
             mSleepTimeMillis = new LongSamplingCounter(timeBase);
-            mRxTimeMillis = new LongSamplingCounter(timeBase);
-            mTxTimeMillis = new LongSamplingCounter[numTxStates];
-            for (int i = 0; i < numTxStates; i++) {
-                mTxTimeMillis[i] = new LongSamplingCounter(timeBase);
-            }
             mPowerDrainMaMs = new LongSamplingCounter(timeBase);
             mMonitoredRailChargeConsumedMaMs = new LongSamplingCounter(timeBase);
         }
 
-        public ControllerActivityCounterImpl(TimeBase timeBase, int numTxStates, Parcel in) {
-            mIdleTimeMillis = new LongSamplingCounter(timeBase, in);
+        public ControllerActivityCounterImpl(Clock clock, TimeBase timeBase, int numTxStates,
+                Parcel in) {
+            mClock = clock;
+            mTimeBase = timeBase;
+            mNumTxStates = numTxStates;
+            mIdleTimeMillis = readTimeMultiStateCounter(in, timeBase);
             mScanTimeMillis = new LongSamplingCounter(timeBase, in);
             mSleepTimeMillis = new LongSamplingCounter(timeBase, in);
-            mRxTimeMillis = new LongSamplingCounter(timeBase, in);
-            final int recordedTxStates = in.readInt();
-            if (recordedTxStates != numTxStates) {
-                throw new ParcelFormatException("inconsistent tx state lengths");
-            }
+            mRxTimeMillis = readTimeMultiStateCounter(in, timeBase);
+            mTxTimeMillis = readTimeMultiStateCounters(in, timeBase, numTxStates);
 
-            mTxTimeMillis = new LongSamplingCounter[numTxStates];
-            for (int i = 0; i < numTxStates; i++) {
-                mTxTimeMillis[i] = new LongSamplingCounter(timeBase, in);
-            }
             mPowerDrainMaMs = new LongSamplingCounter(timeBase, in);
             mMonitoredRailChargeConsumedMaMs = new LongSamplingCounter(timeBase, in);
         }
 
         public void readSummaryFromParcel(Parcel in) {
-            mIdleTimeMillis.readSummaryFromParcelLocked(in);
+            mIdleTimeMillis = readTimeMultiStateCounter(in, mTimeBase);
             mScanTimeMillis.readSummaryFromParcelLocked(in);
             mSleepTimeMillis.readSummaryFromParcelLocked(in);
-            mRxTimeMillis.readSummaryFromParcelLocked(in);
-            final int recordedTxStates = in.readInt();
-            if (recordedTxStates != mTxTimeMillis.length) {
-                throw new ParcelFormatException("inconsistent tx state lengths");
-            }
-            for (LongSamplingCounter counter : mTxTimeMillis) {
-                counter.readSummaryFromParcelLocked(in);
-            }
+            mRxTimeMillis = readTimeMultiStateCounter(in, mTimeBase);
+            mTxTimeMillis = readTimeMultiStateCounters(in, mTimeBase, mNumTxStates);
+
             mPowerDrainMaMs.readSummaryFromParcelLocked(in);
             mMonitoredRailChargeConsumedMaMs.readSummaryFromParcelLocked(in);
         }
@@ -3287,52 +3315,98 @@
         }
 
         public void writeSummaryToParcel(Parcel dest) {
-            mIdleTimeMillis.writeSummaryFromParcelLocked(dest);
+            writeTimeMultiStateCounter(dest, mIdleTimeMillis);
             mScanTimeMillis.writeSummaryFromParcelLocked(dest);
             mSleepTimeMillis.writeSummaryFromParcelLocked(dest);
-            mRxTimeMillis.writeSummaryFromParcelLocked(dest);
-            dest.writeInt(mTxTimeMillis.length);
-            for (LongSamplingCounter counter : mTxTimeMillis) {
-                counter.writeSummaryFromParcelLocked(dest);
-            }
+            writeTimeMultiStateCounter(dest, mRxTimeMillis);
+            writeTimeMultiStateCounters(dest, mTxTimeMillis);
             mPowerDrainMaMs.writeSummaryFromParcelLocked(dest);
             mMonitoredRailChargeConsumedMaMs.writeSummaryFromParcelLocked(dest);
         }
 
         @Override
         public void writeToParcel(Parcel dest, int flags) {
-            mIdleTimeMillis.writeToParcel(dest);
+            writeTimeMultiStateCounter(dest, mIdleTimeMillis);
             mScanTimeMillis.writeToParcel(dest);
             mSleepTimeMillis.writeToParcel(dest);
-            mRxTimeMillis.writeToParcel(dest);
-            dest.writeInt(mTxTimeMillis.length);
-            for (LongSamplingCounter counter : mTxTimeMillis) {
-                counter.writeToParcel(dest);
-            }
+            writeTimeMultiStateCounter(dest, mRxTimeMillis);
+            writeTimeMultiStateCounters(dest, mTxTimeMillis);
             mPowerDrainMaMs.writeToParcel(dest);
             mMonitoredRailChargeConsumedMaMs.writeToParcel(dest);
         }
 
+        private TimeMultiStateCounter readTimeMultiStateCounter(Parcel in, TimeBase timeBase) {
+            if (in.readBoolean()) {
+                final TimeMultiStateCounter counter =
+                        new TimeMultiStateCounter(timeBase, in, mClock.elapsedRealtime());
+                if (counter.getStateCount() == BatteryConsumer.PROCESS_STATE_COUNT) {
+                    return counter;
+                }
+            }
+            return null;
+        }
+
+        private void writeTimeMultiStateCounter(Parcel dest, TimeMultiStateCounter counter) {
+            if (counter != null) {
+                dest.writeBoolean(true);
+                counter.writeToParcel(dest);
+            } else {
+                dest.writeBoolean(false);
+            }
+        }
+
+        private TimeMultiStateCounter[] readTimeMultiStateCounters(Parcel in, TimeBase timeBase,
+                int expectedNumCounters) {
+            if (in.readBoolean()) {
+                final int numCounters = in.readInt();
+                boolean valid = (numCounters == expectedNumCounters);
+                // Need to read counters out of the Parcel, even if all or some of them are
+                // invalid.
+                TimeMultiStateCounter[] counters = new TimeMultiStateCounter[numCounters];
+                for (int i = 0; i < numCounters; i++) {
+                    final TimeMultiStateCounter counter =
+                            new TimeMultiStateCounter(timeBase, in, mClock.elapsedRealtime());
+                    if (counter.getStateCount() == BatteryConsumer.PROCESS_STATE_COUNT) {
+                        counters[i] = counter;
+                    } else {
+                        valid = false;
+                    }
+                }
+                if (valid) {
+                    return counters;
+                }
+            }
+            return null;
+        }
+
+        private void writeTimeMultiStateCounters(Parcel dest, TimeMultiStateCounter[] counters) {
+            if (counters != null) {
+                dest.writeBoolean(true);
+                dest.writeInt(counters.length);
+                for (TimeMultiStateCounter counter : counters) {
+                    counter.writeToParcel(dest);
+                }
+            } else {
+                dest.writeBoolean(false);
+            }
+        }
+
         public void reset(boolean detachIfReset, long elapsedRealtimeUs) {
-            mIdleTimeMillis.reset(detachIfReset, elapsedRealtimeUs);
+            resetIfNotNull(mIdleTimeMillis, detachIfReset, elapsedRealtimeUs);
             mScanTimeMillis.reset(detachIfReset, elapsedRealtimeUs);
             mSleepTimeMillis.reset(detachIfReset, elapsedRealtimeUs);
-            mRxTimeMillis.reset(detachIfReset, elapsedRealtimeUs);
-            for (LongSamplingCounter counter : mTxTimeMillis) {
-                counter.reset(detachIfReset, elapsedRealtimeUs);
-            }
+            resetIfNotNull(mRxTimeMillis, detachIfReset, elapsedRealtimeUs);
+            resetIfNotNull(mTxTimeMillis, detachIfReset, elapsedRealtimeUs);
             mPowerDrainMaMs.reset(detachIfReset, elapsedRealtimeUs);
             mMonitoredRailChargeConsumedMaMs.reset(detachIfReset, elapsedRealtimeUs);
         }
 
         public void detach() {
-            mIdleTimeMillis.detach();
+            detachIfNotNull(mIdleTimeMillis);
             mScanTimeMillis.detach();
             mSleepTimeMillis.detach();
-            mRxTimeMillis.detach();
-            for (LongSamplingCounter counter : mTxTimeMillis) {
-                counter.detach();
-            }
+            detachIfNotNull(mRxTimeMillis);
+            detachIfNotNull(mTxTimeMillis);
             mPowerDrainMaMs.detach();
             mMonitoredRailChargeConsumedMaMs.detach();
         }
@@ -3342,7 +3416,17 @@
          * milliseconds.
          */
         @Override
-        public LongSamplingCounter getIdleTimeCounter() {
+        public LongCounter getIdleTimeCounter() {
+            if (mIdleTimeMillis == null) {
+                return ZERO_LONG_COUNTER;
+            }
+            return mIdleTimeMillis;
+        }
+
+        private TimeMultiStateCounter getOrCreateIdleTimeCounter() {
+            if (mIdleTimeMillis == null) {
+                mIdleTimeMillis = createTimeMultiStateCounter();
+            }
             return mIdleTimeMillis;
         }
 
@@ -3369,7 +3453,17 @@
          * milliseconds.
          */
         @Override
-        public LongSamplingCounter getRxTimeCounter() {
+        public LongCounter getRxTimeCounter() {
+            if (mRxTimeMillis == null) {
+                return ZERO_LONG_COUNTER;
+            }
+            return mRxTimeMillis;
+        }
+
+        private TimeMultiStateCounter getOrCreateRxTimeCounter() {
+            if (mRxTimeMillis == null) {
+                mRxTimeMillis = createTimeMultiStateCounter();
+            }
             return mRxTimeMillis;
         }
 
@@ -3378,10 +3472,33 @@
          * milliseconds.
          */
         @Override
-        public LongSamplingCounter[] getTxTimeCounters() {
+        public LongCounter[] getTxTimeCounters() {
+            if (mTxTimeMillis == null) {
+                return ZERO_LONG_COUNTER_ARRAY;
+            }
             return mTxTimeMillis;
         }
 
+        private TimeMultiStateCounter[] getOrCreateTxTimeCounters() {
+            if (mTxTimeMillis == null) {
+                mTxTimeMillis = new TimeMultiStateCounter[mNumTxStates];
+                for (int i = 0; i < mNumTxStates; i++) {
+                    mTxTimeMillis[i] = createTimeMultiStateCounter();
+                }
+            }
+            return mTxTimeMillis;
+        }
+
+        private TimeMultiStateCounter createTimeMultiStateCounter() {
+            final long timestampMs = mClock.elapsedRealtime();
+            TimeMultiStateCounter counter = new TimeMultiStateCounter(mTimeBase,
+                    BatteryConsumer.PROCESS_STATE_COUNT, timestampMs);
+            counter.setState(mapUidProcessStateToBatteryConsumerProcessState(mProcessState),
+                    timestampMs);
+            counter.update(0, timestampMs);
+            return counter;
+        }
+
         /**
          * @return a LongSamplingCounter, measuring power use in milli-ampere milliseconds (mAmS).
          */
@@ -3398,6 +3515,21 @@
         public LongSamplingCounter getMonitoredRailChargeConsumedMaMs() {
             return mMonitoredRailChargeConsumedMaMs;
         }
+
+        private void setState(int processState, long elapsedTimeMs) {
+            mProcessState = processState;
+            if (mIdleTimeMillis != null) {
+                mIdleTimeMillis.setState(processState, elapsedTimeMs);
+            }
+            if (mRxTimeMillis != null) {
+                mRxTimeMillis.setState(processState, elapsedTimeMs);
+            }
+            if (mTxTimeMillis != null) {
+                for (int i = 0; i < mTxTimeMillis.length; i++) {
+                    mTxTimeMillis[i].setState(processState, elapsedTimeMs);
+                }
+            }
+        }
     }
 
     /** Get Resource Power Manager stats. Create a new one if it doesn't already exist. */
@@ -8234,6 +8366,11 @@
                     mapUidProcessStateToBatteryConsumerProcessState(procState);
             getCpuActiveTimeCounter().setState(batteryConsumerProcessState, elapsedTimeMs);
             getMobileRadioActiveTimeCounter().setState(batteryConsumerProcessState, elapsedTimeMs);
+            final ControllerActivityCounterImpl wifiControllerActivity =
+                    getWifiControllerActivity();
+            if (wifiControllerActivity != null) {
+                wifiControllerActivity.setState(batteryConsumerProcessState, elapsedTimeMs);
+            }
             final MeasuredEnergyStats energyStats =
                     getOrCreateMeasuredEnergyStatsIfSupportedLocked();
             if (energyStats != null) {
@@ -8271,7 +8408,7 @@
 
             long activeTime = 0;
             for (int procState = 0; procState < BatteryConsumer.PROCESS_STATE_COUNT; procState++) {
-                activeTime += mCpuActiveTimeMs.getCountLocked(procState);
+                activeTime += mCpuActiveTimeMs.getCountForProcessState(procState);
             }
             return activeTime;
         }
@@ -8283,7 +8420,7 @@
                 return 0;
             }
 
-            return mCpuActiveTimeMs.getCountLocked(procState);
+            return mCpuActiveTimeMs.getCountForProcessState(procState);
         }
 
         @Override
@@ -8576,7 +8713,7 @@
         }
 
         @Override
-        public ControllerActivityCounter getWifiControllerActivity() {
+        public ControllerActivityCounterImpl getWifiControllerActivity() {
             return mWifiControllerActivity;
         }
 
@@ -8592,24 +8729,24 @@
 
         public ControllerActivityCounterImpl getOrCreateWifiControllerActivityLocked() {
             if (mWifiControllerActivity == null) {
-                mWifiControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase,
-                        NUM_BT_TX_LEVELS);
+                mWifiControllerActivity = new ControllerActivityCounterImpl(mBsi.mClock,
+                        mBsi.mOnBatteryTimeBase, NUM_WIFI_TX_LEVELS);
             }
             return mWifiControllerActivity;
         }
 
         public ControllerActivityCounterImpl getOrCreateBluetoothControllerActivityLocked() {
             if (mBluetoothControllerActivity == null) {
-                mBluetoothControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase,
-                        NUM_BT_TX_LEVELS);
+                mBluetoothControllerActivity = new ControllerActivityCounterImpl(mBsi.mClock,
+                        mBsi.mOnBatteryTimeBase, NUM_BT_TX_LEVELS);
             }
             return mBluetoothControllerActivity;
         }
 
         public ControllerActivityCounterImpl getOrCreateModemControllerActivityLocked() {
             if (mModemControllerActivity == null) {
-                mModemControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase,
-                        ModemActivityInfo.getNumTxPowerLevels());
+                mModemControllerActivity = new ControllerActivityCounterImpl(mBsi.mClock,
+                        mBsi.mOnBatteryTimeBase, ModemActivityInfo.getNumTxPowerLevels());
             }
             return mModemControllerActivity;
         }
@@ -8745,6 +8882,13 @@
             return getMeasuredBatteryConsumptionUC(MeasuredEnergyStats.POWER_BUCKET_WIFI);
         }
 
+        @GuardedBy("mBsi")
+        @Override
+        public long getWifiMeasuredBatteryConsumptionUC(int processState) {
+            return getMeasuredBatteryConsumptionUC(MeasuredEnergyStats.POWER_BUCKET_WIFI,
+                    processState);
+        }
+
         /**
          * Gets the minimum of the uid's foreground activity time and its PROCESS_STATE_TOP time
          * since last marked. Also sets the mark time for both these timers.
@@ -9341,7 +9485,7 @@
             if (processState == BatteryConsumer.PROCESS_STATE_ANY) {
                 return mMobileRadioActiveTime.getTotalCountLocked();
             } else {
-                return mMobileRadioActiveTime.getCountLocked(processState);
+                return mMobileRadioActiveTime.getCountForProcessState(processState);
             }
         }
 
@@ -10291,22 +10435,22 @@
             }
 
             if (in.readInt() != 0) {
-                mWifiControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase,
-                        NUM_WIFI_TX_LEVELS, in);
+                mWifiControllerActivity = new ControllerActivityCounterImpl(mBsi.mClock,
+                        mBsi.mOnBatteryTimeBase, NUM_WIFI_TX_LEVELS, in);
             } else {
                 mWifiControllerActivity = null;
             }
 
             if (in.readInt() != 0) {
-                mBluetoothControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase,
-                        NUM_BT_TX_LEVELS, in);
+                mBluetoothControllerActivity = new ControllerActivityCounterImpl(mBsi.mClock,
+                        mBsi.mOnBatteryTimeBase, NUM_BT_TX_LEVELS, in);
             } else {
                 mBluetoothControllerActivity = null;
             }
 
             if (in.readInt() != 0) {
-                mModemControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase,
-                        ModemActivityInfo.getNumTxPowerLevels(), in);
+                mModemControllerActivity = new ControllerActivityCounterImpl(mBsi.mClock,
+                        mBsi.mOnBatteryTimeBase, ModemActivityInfo.getNumTxPowerLevels(), in);
             } else {
                 mModemControllerActivity = null;
             }
@@ -11273,6 +11417,13 @@
 
                 getMobileRadioActiveTimeCounter()
                         .setState(batteryConsumerProcessState, elapsedRealtimeMs);
+
+                final ControllerActivityCounterImpl wifiControllerActivity =
+                        getWifiControllerActivity();
+                if (wifiControllerActivity != null) {
+                    wifiControllerActivity.setState(batteryConsumerProcessState, elapsedRealtimeMs);
+                }
+
                 final MeasuredEnergyStats energyStats =
                         getOrCreateMeasuredEnergyStatsIfSupportedLocked();
                 if (energyStats != null) {
@@ -11681,10 +11832,11 @@
             mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase);
             mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase);
         }
-        mWifiActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, NUM_WIFI_TX_LEVELS);
-        mBluetoothActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase,
+        mWifiActivity = new ControllerActivityCounterImpl(mClock, mOnBatteryTimeBase,
+                NUM_WIFI_TX_LEVELS);
+        mBluetoothActivity = new ControllerActivityCounterImpl(mClock, mOnBatteryTimeBase,
                 NUM_BT_TX_LEVELS);
-        mModemActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase,
+        mModemActivity = new ControllerActivityCounterImpl(mClock, mOnBatteryTimeBase,
                 ModemActivityInfo.getNumTxPowerLevels());
         mMobileRadioActiveTimer = new StopwatchTimer(mClock, null, -400, null, mOnBatteryTimeBase);
         mMobileRadioActivePerAppTimer = new StopwatchTimer(mClock, null, -401, null,
@@ -12613,7 +12765,8 @@
                         continue;
                     }
 
-                    final Uid u = getUidStatsLocked(mapUid(entry.uid), elapsedRealtimeMs, uptimeMs);
+                    final int uid = mapUid(entry.uid);
+                    final Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs);
                     if (entry.rxBytes != 0) {
                         u.noteNetworkActivityLocked(NETWORK_WIFI_RX_DATA, entry.rxBytes,
                                 entry.rxPackets);
@@ -12626,8 +12779,7 @@
                         mNetworkPacketActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked(
                                 entry.rxPackets);
 
-                        // TODO(b/182845426): What if u was a mapped isolated uid? Shouldn't we sum?
-                        rxPackets.put(u.getUid(), entry.rxPackets);
+                        add(rxPackets, uid, entry.rxPackets);
 
                         // Sum the total number of packets so that the Rx Power can
                         // be evenly distributed amongst the apps.
@@ -12646,8 +12798,7 @@
                         mNetworkPacketActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked(
                                 entry.txPackets);
 
-                        // TODO(b/182845426): What if u was a mapped isolated uid? Shouldn't we sum?
-                        txPackets.put(u.getUid(), entry.txPackets);
+                        add(txPackets, uid, entry.txPackets);
 
                         // Sum the total number of packets so that the Tx Power can
                         // be evenly distributed amongst the apps.
@@ -12774,9 +12925,10 @@
 
                         ControllerActivityCounterImpl activityCounter =
                                 uid.getOrCreateWifiControllerActivityLocked();
-                        activityCounter.getRxTimeCounter().addCountLocked(scanRxTimeSinceMarkMs);
-                        activityCounter.getTxTimeCounters()[0].addCountLocked(
-                                scanTxTimeSinceMarkMs);
+                        activityCounter.getOrCreateRxTimeCounter()
+                                .increment(scanRxTimeSinceMarkMs, elapsedRealtimeMs);
+                        activityCounter.getOrCreateTxTimeCounters()[0]
+                                .increment(scanTxTimeSinceMarkMs, elapsedRealtimeMs);
                         leftOverRxTimeMs -= scanRxTimeSinceMarkMs;
                         leftOverTxTimeMs -= scanTxTimeSinceMarkMs;
                     }
@@ -12796,8 +12948,8 @@
                             Slog.d(TAG, "  IdleTime for UID " + uid.getUid() + ": "
                                     + myIdleTimeMs + " ms");
                         }
-                        uid.getOrCreateWifiControllerActivityLocked().getIdleTimeCounter()
-                                .addCountLocked(myIdleTimeMs);
+                        uid.getOrCreateWifiControllerActivityLocked().getOrCreateIdleTimeCounter()
+                                .increment(myIdleTimeMs, elapsedRealtimeMs);
                     }
 
                     if (uidEstimatedConsumptionMah != null) {
@@ -12822,8 +12974,8 @@
                     if (DEBUG_ENERGY) {
                         Slog.d(TAG, "  TxTime for UID " + uid.getUid() + ": " + myTxTimeMs + " ms");
                     }
-                    uid.getOrCreateWifiControllerActivityLocked().getTxTimeCounters()[0]
-                            .addCountLocked(myTxTimeMs);
+                    uid.getOrCreateWifiControllerActivityLocked().getOrCreateTxTimeCounters()[0]
+                            .increment(myTxTimeMs, elapsedRealtimeMs);
                     if (uidEstimatedConsumptionMah != null) {
                         uidEstimatedConsumptionMah.add(uid.getUid(),
                                 mWifiPowerCalculator.calcPowerFromControllerDataMah(
@@ -12841,8 +12993,8 @@
                     if (DEBUG_ENERGY) {
                         Slog.d(TAG, "  RxTime for UID " + uid.getUid() + ": " + myRxTimeMs + " ms");
                     }
-                    uid.getOrCreateWifiControllerActivityLocked().getRxTimeCounter()
-                            .addCountLocked(myRxTimeMs);
+                    uid.getOrCreateWifiControllerActivityLocked().getOrCreateRxTimeCounter()
+                            .increment(myRxTimeMs, elapsedRealtimeMs);
                     if (uidEstimatedConsumptionMah != null) {
                         uidEstimatedConsumptionMah.add(uid.getUid(),
                                 mWifiPowerCalculator.calcPowerFromControllerDataMah(
@@ -12854,14 +13006,14 @@
 
 
                 // Update WiFi controller stats.
-                mWifiActivity.getRxTimeCounter().addCountLocked(
-                        info.getControllerRxDurationMillis());
-                mWifiActivity.getTxTimeCounters()[0].addCountLocked(
-                        info.getControllerTxDurationMillis());
+                mWifiActivity.getOrCreateRxTimeCounter().increment(
+                        info.getControllerRxDurationMillis(), elapsedRealtimeMs);
+                mWifiActivity.getOrCreateTxTimeCounters()[0].increment(
+                        info.getControllerTxDurationMillis(), elapsedRealtimeMs);
                 mWifiActivity.getScanTimeCounter().addCountLocked(
                         info.getControllerScanDurationMillis());
-                mWifiActivity.getIdleTimeCounter().addCountLocked(
-                        info.getControllerIdleDurationMillis());
+                mWifiActivity.getOrCreateIdleTimeCounter().increment(
+                        info.getControllerIdleDurationMillis(), elapsedRealtimeMs);
 
                 // POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V.
                 final double opVolt = mPowerProfile.getAveragePower(
@@ -12961,14 +13113,16 @@
 
             if (deltaInfo != null) {
                 mHasModemReporting = true;
-                mModemActivity.getIdleTimeCounter().addCountLocked(
-                        deltaInfo.getIdleTimeMillis());
+                mModemActivity.getOrCreateIdleTimeCounter()
+                        .increment(deltaInfo.getIdleTimeMillis(), elapsedRealtimeMs);
                 mModemActivity.getSleepTimeCounter().addCountLocked(
                         deltaInfo.getSleepTimeMillis());
-                mModemActivity.getRxTimeCounter().addCountLocked(deltaInfo.getReceiveTimeMillis());
+                mModemActivity.getOrCreateRxTimeCounter()
+                        .increment(deltaInfo.getReceiveTimeMillis(), elapsedRealtimeMs);
                 for (int lvl = 0; lvl < ModemActivityInfo.getNumTxPowerLevels(); lvl++) {
-                    mModemActivity.getTxTimeCounters()[lvl]
-                        .addCountLocked(deltaInfo.getTransmitDurationMillisAtPowerLevel(lvl));
+                    mModemActivity.getOrCreateTxTimeCounters()[lvl]
+                            .increment(deltaInfo.getTransmitDurationMillisAtPowerLevel(lvl),
+                                    elapsedRealtimeMs);
                 }
 
                 // POWER_MODEM_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V.
@@ -13086,7 +13240,8 @@
                             if (totalRxPackets > 0 && entry.rxPackets > 0) {
                                 final long rxMs = (entry.rxPackets
                                     * deltaInfo.getReceiveTimeMillis()) / totalRxPackets;
-                                activityCounter.getRxTimeCounter().addCountLocked(rxMs);
+                                activityCounter.getOrCreateRxTimeCounter()
+                                        .increment(rxMs, elapsedRealtimeMs);
                             }
 
                             if (totalTxPackets > 0 && entry.txPackets > 0) {
@@ -13095,7 +13250,8 @@
                                     long txMs = entry.txPackets
                                             * deltaInfo.getTransmitDurationMillisAtPowerLevel(lvl);
                                     txMs /= totalTxPackets;
-                                    activityCounter.getTxTimeCounters()[lvl].addCountLocked(txMs);
+                                    activityCounter.getOrCreateTxTimeCounters()[lvl]
+                                            .increment(txMs, elapsedRealtimeMs);
                                 }
                             }
                         }
@@ -13193,8 +13349,8 @@
             energy = info.getControllerEnergyUsed();
             if (!info.getUidTraffic().isEmpty()) {
                 for (UidTraffic traffic : info.getUidTraffic()) {
-                    uidRxBytes.put(traffic.getUid(), traffic.getRxBytes());
-                    uidTxBytes.put(traffic.getUid(), traffic.getTxBytes());
+                    add(uidRxBytes, traffic.getUid(), traffic.getRxBytes());
+                    add(uidTxBytes, traffic.getUid(), traffic.getTxBytes());
                 }
             }
         }
@@ -13317,8 +13473,10 @@
 
                 final ControllerActivityCounterImpl counter =
                         u.getOrCreateBluetoothControllerActivityLocked();
-                counter.getRxTimeCounter().addCountLocked(scanTimeRxSinceMarkMs);
-                counter.getTxTimeCounters()[0].addCountLocked(scanTimeTxSinceMarkMs);
+                counter.getOrCreateRxTimeCounter()
+                        .increment(scanTimeRxSinceMarkMs, elapsedRealtimeMs);
+                counter.getOrCreateTxTimeCounters()[0]
+                        .increment(scanTimeTxSinceMarkMs, elapsedRealtimeMs);
 
                 if (uidEstimatedConsumptionMah != null) {
                     uidEstimatedConsumptionMah.add(u.getUid(),
@@ -13385,7 +13543,7 @@
                     if (DEBUG_ENERGY) {
                         Slog.d(TAG, "UID=" + uid + " rx_bytes=" + rxBytes + " rx_time=" + timeRxMs);
                     }
-                    counter.getRxTimeCounter().addCountLocked(timeRxMs);
+                    counter.getOrCreateRxTimeCounter().increment(timeRxMs, elapsedRealtimeMs);
 
                     if (uidEstimatedConsumptionMah != null) {
                         uidEstimatedConsumptionMah.add(u.getUid(),
@@ -13398,7 +13556,8 @@
                     if (DEBUG_ENERGY) {
                         Slog.d(TAG, "UID=" + uid + " tx_bytes=" + txBytes + " tx_time=" + timeTxMs);
                     }
-                    counter.getTxTimeCounters()[0].addCountLocked(timeTxMs);
+                    counter.getOrCreateTxTimeCounters()[0]
+                            .increment(timeTxMs, elapsedRealtimeMs);
 
                     if (uidEstimatedConsumptionMah != null) {
                         uidEstimatedConsumptionMah.add(u.getUid(),
@@ -13408,9 +13567,9 @@
             }
         }
 
-        mBluetoothActivity.getRxTimeCounter().addCountLocked(rxTimeMs);
-        mBluetoothActivity.getTxTimeCounters()[0].addCountLocked(txTimeMs);
-        mBluetoothActivity.getIdleTimeCounter().addCountLocked(idleTimeMs);
+        mBluetoothActivity.getOrCreateRxTimeCounter().increment(rxTimeMs, elapsedRealtimeMs);
+        mBluetoothActivity.getOrCreateTxTimeCounters()[0].increment(txTimeMs, elapsedRealtimeMs);
+        mBluetoothActivity.getOrCreateIdleTimeCounter().increment(idleTimeMs, elapsedRealtimeMs);
 
         // POWER_BLUETOOTH_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V.
         final double opVolt = mPowerProfile.getAveragePower(
@@ -16288,6 +16447,7 @@
     @GuardedBy("this")
     public void readSummaryFromParcel(Parcel in) throws ParcelFormatException {
         final int version = in.readInt();
+
         if (version != VERSION) {
             Slog.w("BatteryStats", "readFromParcel: version got " + version
                 + ", expected " + VERSION + "; erasing old stats");
@@ -17447,15 +17607,15 @@
         }
         mWifiActiveTimer = new StopwatchTimer(mClock, null, -900, null,
             mOnBatteryTimeBase, in);
-        mWifiActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase,
+        mWifiActivity = new ControllerActivityCounterImpl(mClock, mOnBatteryTimeBase,
                 NUM_WIFI_TX_LEVELS, in);
         for (int i=0; i<mGpsSignalQualityTimer.length; i++) {
             mGpsSignalQualityTimer[i] = new StopwatchTimer(mClock, null, -1000 - i,
                 null, mOnBatteryTimeBase, in);
         }
-        mBluetoothActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase,
+        mBluetoothActivity = new ControllerActivityCounterImpl(mClock, mOnBatteryTimeBase,
                 NUM_BT_TX_LEVELS, in);
-        mModemActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase,
+        mModemActivity = new ControllerActivityCounterImpl(mClock, mOnBatteryTimeBase,
                 ModemActivityInfo.getNumTxPowerLevels(), in);
         mHasWifiReporting = in.readInt() != 0;
         mHasBluetoothReporting = in.readInt() != 0;
@@ -17980,4 +18140,8 @@
         pw.println();
         dumpMeasuredEnergyStatsLocked(pw);
     }
+
+    private static void add(SparseLongArray array, int key, long delta) {
+        array.put(key, array.get(key) + delta);
+    }
 }
diff --git a/core/java/com/android/internal/os/WifiPowerCalculator.java b/core/java/com/android/internal/os/WifiPowerCalculator.java
index 3915b0e..2a71ac6 100644
--- a/core/java/com/android/internal/os/WifiPowerCalculator.java
+++ b/core/java/com/android/internal/os/WifiPowerCalculator.java
@@ -25,6 +25,7 @@
 import android.util.Log;
 import android.util.SparseArray;
 
+import java.util.Arrays;
 import java.util.List;
 
 /**
@@ -34,6 +35,9 @@
 public class WifiPowerCalculator extends PowerCalculator {
     private static final boolean DEBUG = BatteryStatsHelper.DEBUG;
     private static final String TAG = "WifiPowerCalculator";
+
+    private static final BatteryConsumer.Key[] UNINITIALIZED_KEYS = new BatteryConsumer.Key[0];
+
     private final UsageBasedPowerEstimator mIdlePowerEstimator;
     private final UsageBasedPowerEstimator mTxPowerEstimator;
     private final UsageBasedPowerEstimator mRxPowerEstimator;
@@ -51,6 +55,9 @@
         public long wifiTxPackets;
         public long wifiRxBytes;
         public long wifiTxBytes;
+
+        public BatteryConsumer.Key[] keys;
+        public double[] powerPerKeyMah;
     }
 
     public WifiPowerCalculator(PowerProfile profile) {
@@ -77,7 +84,7 @@
     @Override
     public void calculate(BatteryUsageStats.Builder builder, BatteryStats batteryStats,
             long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) {
-
+        BatteryConsumer.Key[] keys = UNINITIALIZED_KEYS;
         long totalAppDurationMs = 0;
         double totalAppPowerMah = 0;
         final PowerDurationAndTraffic powerDurationAndTraffic = new PowerDurationAndTraffic();
@@ -85,9 +92,20 @@
                 builder.getUidBatteryConsumerBuilders();
         for (int i = uidBatteryConsumerBuilders.size() - 1; i >= 0; i--) {
             final UidBatteryConsumer.Builder app = uidBatteryConsumerBuilders.valueAt(i);
+            if (keys == UNINITIALIZED_KEYS) {
+                if (query.isProcessStateDataNeeded()) {
+                    keys = app.getKeys(BatteryConsumer.POWER_COMPONENT_WIFI);
+                    powerDurationAndTraffic.keys = keys;
+                    powerDurationAndTraffic.powerPerKeyMah = new double[keys.length];
+                } else {
+                    keys = null;
+                }
+            }
+
             final long consumptionUC =
                     app.getBatteryStatsUid().getWifiMeasuredBatteryConsumptionUC();
             final int powerModel = getPowerModel(consumptionUC, query);
+
             calculateApp(powerDurationAndTraffic, app.getBatteryStatsUid(), powerModel,
                     rawRealtimeUs, BatteryStats.STATS_SINCE_CHARGED,
                     batteryStats.hasWifiActivityReporting(), consumptionUC);
@@ -99,6 +117,20 @@
                     powerDurationAndTraffic.durationMs);
             app.setConsumedPower(BatteryConsumer.POWER_COMPONENT_WIFI,
                     powerDurationAndTraffic.powerMah, powerModel);
+
+            if (query.isProcessStateDataNeeded() && keys != null) {
+                for (int j = 0; j < keys.length; j++) {
+                    BatteryConsumer.Key key = keys[j];
+                    final int processState = key.processState;
+                    if (processState == BatteryConsumer.PROCESS_STATE_UNSPECIFIED) {
+                        // Already populated with the total across all process states
+                        continue;
+                    }
+
+                    app.setConsumedPower(key, powerDurationAndTraffic.powerPerKeyMah[j],
+                            powerModel);
+                }
+            }
         }
 
         final long consumptionUC = batteryStats.getWifiMeasuredBatteryConsumptionUC();
@@ -193,21 +225,23 @@
                 BatteryStats.NETWORK_WIFI_TX_DATA,
                 statsType);
 
-        if (powerModel == BatteryConsumer.POWER_MODEL_MEASURED_ENERGY) {
-            powerDurationAndTraffic.powerMah = uCtoMah(consumptionUC);
-        }
-
         if (hasWifiActivityReporting && mHasWifiPowerController) {
             final BatteryStats.ControllerActivityCounter counter = u.getWifiControllerActivity();
             if (counter != null) {
-                final long idleTime = counter.getIdleTimeCounter().getCountLocked(statsType);
-                final long txTime = counter.getTxTimeCounters()[0].getCountLocked(statsType);
-                final long rxTime = counter.getRxTimeCounter().getCountLocked(statsType);
+                final BatteryStats.LongCounter rxTimeCounter = counter.getRxTimeCounter();
+                final BatteryStats.LongCounter txTimeCounter = counter.getTxTimeCounters()[0];
+                final BatteryStats.LongCounter idleTimeCounter = counter.getIdleTimeCounter();
+
+                final long rxTime = rxTimeCounter.getCountLocked(statsType);
+                final long txTime = txTimeCounter.getCountLocked(statsType);
+                final long idleTime = idleTimeCounter.getCountLocked(statsType);
 
                 powerDurationAndTraffic.durationMs = idleTime + rxTime + txTime;
                 if (powerModel == BatteryConsumer.POWER_MODEL_POWER_PROFILE) {
                     powerDurationAndTraffic.powerMah
                             = calcPowerFromControllerDataMah(rxTime, txTime, idleTime);
+                } else {
+                    powerDurationAndTraffic.powerMah = uCtoMah(consumptionUC);
                 }
 
                 if (DEBUG && powerDurationAndTraffic.powerMah != 0) {
@@ -215,9 +249,32 @@
                             + "ms tx=" + txTime + "ms power=" + formatCharge(
                             powerDurationAndTraffic.powerMah));
                 }
+
+                if (powerDurationAndTraffic.keys != null) {
+                    for (int i = 0; i < powerDurationAndTraffic.keys.length; i++) {
+                        final int processState = powerDurationAndTraffic.keys[i].processState;
+                        if (processState == BatteryConsumer.PROCESS_STATE_UNSPECIFIED) {
+                            continue;
+                        }
+
+                        if (powerModel == BatteryConsumer.POWER_MODEL_POWER_PROFILE) {
+                            powerDurationAndTraffic.powerPerKeyMah[i] =
+                                    calcPowerFromControllerDataMah(
+                                            rxTimeCounter.getCountForProcessState(processState),
+                                            txTimeCounter.getCountForProcessState(processState),
+                                            idleTimeCounter.getCountForProcessState(processState));
+                        } else {
+                            powerDurationAndTraffic.powerPerKeyMah[i] =
+                                    uCtoMah(u.getWifiMeasuredBatteryConsumptionUC(processState));
+                        }
+                    }
+                }
             } else {
                 powerDurationAndTraffic.durationMs = 0;
                 powerDurationAndTraffic.powerMah = 0;
+                if (powerDurationAndTraffic.powerPerKeyMah != null) {
+                    Arrays.fill(powerDurationAndTraffic.powerPerKeyMah, 0);
+                }
             }
         } else {
             final long wifiRunningTime = u.getWifiRunningTime(rawRealtimeUs, statsType) / 1000;
@@ -233,6 +290,14 @@
                         powerDurationAndTraffic.wifiRxPackets,
                         powerDurationAndTraffic.wifiTxPackets,
                         wifiRunningTime, wifiScanTimeMs, batchTimeMs);
+            } else {
+                powerDurationAndTraffic.powerMah = uCtoMah(consumptionUC);
+            }
+
+            if (powerDurationAndTraffic.powerPerKeyMah != null) {
+                // Per-process state attribution is not supported in the absence of WiFi
+                // activity reporting
+                Arrays.fill(powerDurationAndTraffic.powerPerKeyMah, 0);
             }
 
             if (DEBUG && powerDurationAndTraffic.powerMah != 0) {
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index d6bbe71..d0b9f88 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -716,6 +716,7 @@
 
     <!-- Added in T -->
     <protected-broadcast android:name="android.intent.action.REFRESH_SAFETY_SOURCES" />
+    <protected-broadcast android:name="android.app.action.DEVICE_POLICY_RESOURCE_UPDATED" />
 
     <!-- ====================================================================== -->
     <!--                          RUNTIME PERMISSIONS                           -->
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index e055749..a595433 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -2829,14 +2829,6 @@
         <attr name="path" />
         <attr name="minSdkVersion" />
         <attr name="maxSdkVersion" />
-        <!-- The order in which the apex system services are initiated. When there are dependencies
-        among apex system services, setting this attribute for each of them ensures that they are
-        created in the order required by those dependencies. The apex-system-services that are
-        started manually within SystemServer ignore the initOrder and are not considered for
-        automatic starting of the other services.
-        The value is a simple integer, with higher number being initialized first. If not specified,
-        the default order is 0. -->
-        <attr name="initOrder" format="integer" />
     </declare-styleable>
 
     <!-- The <code>receiver</code> tag declares an
diff --git a/core/tests/batterystatstests/BatteryStatsViewer/AndroidManifest.xml b/core/tests/batterystatstests/BatteryStatsViewer/AndroidManifest.xml
index 1b1f64a..bd987a0 100644
--- a/core/tests/batterystatstests/BatteryStatsViewer/AndroidManifest.xml
+++ b/core/tests/batterystatstests/BatteryStatsViewer/AndroidManifest.xml
@@ -16,8 +16,7 @@
   -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.frameworks.core.batterystatsviewer"
-          android:sharedUserId="android.uid.system">
+          package="com.android.frameworks.core.batterystatsviewer">
 
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
     <uses-permission android:name="android.permission.BATTERY_STATS"/>
diff --git a/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerData.java b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerData.java
index eb378b9..6a53f68 100644
--- a/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerData.java
+++ b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerData.java
@@ -130,23 +130,20 @@
                     || powerModel == BatteryConsumer.POWER_MODEL_UNDEFINED) {
                 addEntry(metricTitle, EntryType.UID_POWER_MODELED,
                         requestedBatteryConsumer.getConsumedPower(component),
-                        totalPowerByComponentMah[component]
-                );
+                        totalPowerByComponentMah[component]);
+                addProcessStateEntries(metricTitle, EntryType.UID_POWER_MODELED_PROCESS_STATE,
+                        requestedBatteryConsumer, component);
             } else {
                 addEntry(metricTitle + " (measured)", EntryType.UID_POWER_MEASURED,
                         requestedBatteryConsumer.getConsumedPower(component),
-                        totalPowerByComponentMah[component]
-                );
+                        totalPowerByComponentMah[component]);
                 addProcessStateEntries(metricTitle, EntryType.UID_POWER_MEASURED_PROCESS_STATE,
-                        requestedBatteryConsumer, component
-                );
+                        requestedBatteryConsumer, component);
                 addEntry(metricTitle + " (modeled)", EntryType.UID_POWER_MODELED,
                         requestedModeledBatteryConsumer.getConsumedPower(component),
-                        totalModeledPowerByComponentMah[component]
-                );
+                        totalModeledPowerByComponentMah[component]);
                 addProcessStateEntries(metricTitle, EntryType.UID_POWER_MODELED_PROCESS_STATE,
-                        requestedModeledBatteryConsumer, component
-                );
+                        requestedModeledBatteryConsumer, component);
             }
         }
 
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 8eb6ebc..0000000
--- a/core/tests/bluetoothtests/src/android/bluetooth/BluetoothTestUtils.java
+++ /dev/null
@@ -1,1651 +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);
-        assertEquals(adapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE),
-                BluetoothStatusCodes.SUCCESS);
-        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);
-        assertEquals(adapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE),
-                BluetoothStatusCodes.SUCCESS);
-        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/BatteryUsageStatsTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsTest.java
index 69e617a..9699275 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsTest.java
@@ -83,7 +83,7 @@
         final Parcel parcel = Parcel.obtain();
         parcel.writeParcelable(outBatteryUsageStats, 0);
 
-        assertThat(parcel.dataSize()).isLessThan(5500);
+        assertThat(parcel.dataSize()).isLessThan(6000);
 
         parcel.setDataPosition(0);
 
diff --git a/core/tests/coretests/src/com/android/internal/os/WifiPowerCalculatorTest.java b/core/tests/coretests/src/com/android/internal/os/WifiPowerCalculatorTest.java
index e7ce9a0..a787357 100644
--- a/core/tests/coretests/src/com/android/internal/os/WifiPowerCalculatorTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/WifiPowerCalculatorTest.java
@@ -25,6 +25,8 @@
 import android.net.NetworkCapabilities;
 import android.net.NetworkStats;
 import android.os.BatteryConsumer;
+import android.os.BatteryStats;
+import android.os.BatteryUsageStatsQuery;
 import android.os.Process;
 import android.os.UidBatteryConsumer;
 import android.os.WorkSource;
@@ -40,6 +42,7 @@
 
 @RunWith(AndroidJUnit4.class)
 @SmallTest
+@SuppressWarnings("GuardedBy")
 public class WifiPowerCalculatorTest {
     private static final double PRECISION = 0.00001;
 
@@ -66,14 +69,18 @@
         batteryStats.noteNetworkInterfaceForTransports("wifi",
                 new int[]{NetworkCapabilities.TRANSPORT_WIFI});
 
-        NetworkStats networkStats = new NetworkStats(10000, 1)
-                .insertEntry("wifi", APP_UID, 0, 0, 1000, 100, 2000, 20, 100)
-                .insertEntry("wifi", Process.WIFI_UID, 0, 0, 1111, 111, 2222, 22, 111);
-        mStatsRule.setNetworkStats(networkStats);
+        mStatsRule.setNetworkStats(buildNetworkStats(10000, 1000, 100, 2000, 20));
 
         return batteryStats;
     }
 
+    private NetworkStats buildNetworkStats(long elapsedRealtime, int rxBytes, int rxPackets,
+            int txBytes, int txPackets) {
+        return new NetworkStats(elapsedRealtime, 1)
+                .insertEntry("wifi", APP_UID, 0, 0, rxBytes, rxPackets, txBytes, txPackets, 100)
+                .insertEntry("wifi", Process.WIFI_UID, 0, 0, 1111, 111, 2222, 22, 111);
+    }
+
     /** Sets up an WifiActivityEnergyInfo for ActivityController-model-based tests. */
     private WifiActivityEnergyInfo setupPowerControllerBasedModelEnergyNumbersInfo() {
         return new WifiActivityEnergyInfo(10000,
@@ -115,6 +122,61 @@
     }
 
     @Test
+    public void testPowerControllerBasedModel_powerProfile_byProcessState() {
+        final BatteryStatsImpl batteryStats = setupTestNetworkNumbers();
+
+        mStatsRule.setTime(1000, 1000);
+
+        BatteryStatsImpl.Uid uid = batteryStats.getUidStatsLocked(APP_UID);
+        uid.setProcessStateForTest(
+                BatteryStats.Uid.PROCESS_STATE_FOREGROUND, 1000);
+
+        batteryStats.updateWifiState(new WifiActivityEnergyInfo(2000,
+                        WifiActivityEnergyInfo.STACK_STATE_STATE_ACTIVE, 1000, 2000, 3000, 4000),
+                POWER_DATA_UNAVAILABLE, 2000, 2000,
+                mNetworkStatsManager);
+
+        uid.setProcessStateForTest(
+                BatteryStats.Uid.PROCESS_STATE_BACKGROUND, 3000);
+
+        mStatsRule.setNetworkStats(buildNetworkStats(4000, 5000, 200, 7000, 80));
+
+        batteryStats.updateWifiState(new WifiActivityEnergyInfo(4000,
+                        WifiActivityEnergyInfo.STACK_STATE_STATE_ACTIVE, 5000, 6000, 7000, 8000),
+                POWER_DATA_UNAVAILABLE, 4000, 4000,
+                mNetworkStatsManager);
+
+        WifiPowerCalculator calculator = new WifiPowerCalculator(mStatsRule.getPowerProfile());
+        mStatsRule.apply(new BatteryUsageStatsQuery.Builder()
+                .powerProfileModeledOnly()
+                .includePowerModels()
+                .includeProcessStateData()
+                .build(), calculator);
+
+        UidBatteryConsumer uidConsumer = mStatsRule.getUidBatteryConsumer(APP_UID);
+        assertThat(uidConsumer.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_WIFI))
+                .isEqualTo(12423);
+        assertThat(uidConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_WIFI))
+                .isWithin(PRECISION).of(2.0214666);
+        assertThat(uidConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_WIFI))
+                .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE);
+
+        final BatteryConsumer.Key foreground = uidConsumer.getKey(
+                BatteryConsumer.POWER_COMPONENT_WIFI,
+                BatteryConsumer.PROCESS_STATE_FOREGROUND);
+        final BatteryConsumer.Key background = uidConsumer.getKey(
+                BatteryConsumer.POWER_COMPONENT_WIFI,
+                BatteryConsumer.PROCESS_STATE_BACKGROUND);
+        final BatteryConsumer.Key fgs = uidConsumer.getKey(
+                BatteryConsumer.POWER_COMPONENT_WIFI,
+                BatteryConsumer.PROCESS_STATE_FOREGROUND_SERVICE);
+
+        assertThat(uidConsumer.getConsumedPower(foreground)).isWithin(PRECISION).of(1.1214666);
+        assertThat(uidConsumer.getConsumedPower(background)).isWithin(PRECISION).of(0.9);
+        assertThat(uidConsumer.getConsumedPower(fgs)).isWithin(PRECISION).of(0);
+    }
+
+    @Test
     public void testPowerControllerBasedModel_measured() {
         final BatteryStatsImpl batteryStats = setupTestNetworkNumbers();
         final WifiActivityEnergyInfo energyInfo = setupPowerControllerBasedModelEnergyNumbersInfo();
@@ -148,6 +210,60 @@
                 .isEqualTo(BatteryConsumer.POWER_MODEL_MEASURED_ENERGY);
     }
 
+    @Test
+    public void testPowerControllerBasedModel_measured_byProcessState() {
+        final BatteryStatsImpl batteryStats = setupTestNetworkNumbers();
+
+        mStatsRule.setTime(1000, 1000);
+
+        BatteryStatsImpl.Uid uid = batteryStats.getUidStatsLocked(APP_UID);
+        uid.setProcessStateForTest(
+                BatteryStats.Uid.PROCESS_STATE_FOREGROUND, 1000);
+
+        batteryStats.updateWifiState(new WifiActivityEnergyInfo(2000,
+                        WifiActivityEnergyInfo.STACK_STATE_STATE_ACTIVE, 1000, 2000, 3000, 4000),
+                1_000_000, 2000, 2000,
+                mNetworkStatsManager);
+
+        uid.setProcessStateForTest(
+                BatteryStats.Uid.PROCESS_STATE_BACKGROUND, 3000);
+
+        mStatsRule.setNetworkStats(buildNetworkStats(4000, 5000, 200, 7000, 80));
+
+        batteryStats.updateWifiState(new WifiActivityEnergyInfo(4000,
+                        WifiActivityEnergyInfo.STACK_STATE_STATE_ACTIVE, 5000, 6000, 7000, 8000),
+                5_000_000, 4000, 4000,
+                mNetworkStatsManager);
+
+        WifiPowerCalculator calculator = new WifiPowerCalculator(mStatsRule.getPowerProfile());
+        mStatsRule.apply(new BatteryUsageStatsQuery.Builder()
+                .includePowerModels()
+                .includeProcessStateData()
+                .build(), calculator);
+
+        UidBatteryConsumer uidConsumer = mStatsRule.getUidBatteryConsumer(APP_UID);
+        assertThat(uidConsumer.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_WIFI))
+                .isEqualTo(12423);
+        assertThat(uidConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_WIFI))
+                .isWithin(PRECISION).of(1.0325211);
+        assertThat(uidConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_WIFI))
+                .isEqualTo(BatteryConsumer.POWER_MODEL_MEASURED_ENERGY);
+
+        final BatteryConsumer.Key foreground = uidConsumer.getKey(
+                BatteryConsumer.POWER_COMPONENT_WIFI,
+                BatteryConsumer.PROCESS_STATE_FOREGROUND);
+        final BatteryConsumer.Key background = uidConsumer.getKey(
+                BatteryConsumer.POWER_COMPONENT_WIFI,
+                BatteryConsumer.PROCESS_STATE_BACKGROUND);
+        final BatteryConsumer.Key fgs = uidConsumer.getKey(
+                BatteryConsumer.POWER_COMPONENT_WIFI,
+                BatteryConsumer.PROCESS_STATE_FOREGROUND_SERVICE);
+
+        assertThat(uidConsumer.getConsumedPower(foreground)).isWithin(PRECISION).of(0.5517519);
+        assertThat(uidConsumer.getConsumedPower(background)).isWithin(PRECISION).of(0.4807691);
+        assertThat(uidConsumer.getConsumedPower(fgs)).isWithin(PRECISION).of(0);
+    }
+
     /** Sets up batterystats object with prepopulated network & timer data for Timer-model tests. */
     private BatteryStatsImpl setupTimerBasedModelTestNumbers() {
         final BatteryStatsImpl batteryStats = setupTestNetworkNumbers();
diff --git a/graphics/java/android/graphics/BitmapShader.java b/graphics/java/android/graphics/BitmapShader.java
index e6ff187..43cb5ee 100644
--- a/graphics/java/android/graphics/BitmapShader.java
+++ b/graphics/java/android/graphics/BitmapShader.java
@@ -16,8 +16,12 @@
 
 package android.graphics;
 
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * Shader used to draw a bitmap as a texture. The bitmap can be repeated or
  * mirrored by setting the tiling mode.
@@ -31,6 +35,47 @@
     private int mTileX;
     private int mTileY;
 
+    /** @hide */
+    @IntDef(prefix = {"FILTER_MODE"}, value = {
+            FILTER_MODE_DEFAULT,
+            FILTER_MODE_NEAREST,
+            FILTER_MODE_LINEAR
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface FilterMode {}
+
+    /**
+     * This FilterMode value will respect the value of the Paint#isFilterBitmap flag while the
+     * shader is attached to the Paint.
+     *
+     * <p>The exception to this rule is when a Shader is attached as input to a RuntimeShader. In
+     *    that case this mode will default to FILTER_MODE_NEAREST.</p>
+     *
+     * @see #setFilterMode(int)
+     */
+    public static final int FILTER_MODE_DEFAULT = 0;
+    /**
+     * This FilterMode value will cause the shader to sample from the nearest pixel to the requested
+     * sample point.
+     *
+     * <p>This value will override the effect of Paint#isFilterBitmap.</p>
+     *
+     * @see #setFilterMode(int)
+     */
+    public static final int FILTER_MODE_NEAREST = 1;
+    /**
+     * This FilterMode value will cause the shader to interpolate the output of the shader from a
+     * 2x2 grid of pixels nearest to the sample point (i.e. bilinear interpolation).
+     *
+     * <p>This value will override the effect of Paint#isFilterBitmap.</p>
+     *
+     * @see #setFilterMode(int)
+     */
+    public static final int FILTER_MODE_LINEAR = 2;
+
+    @FilterMode
+    private int mFilterMode;
+
     /*
      *  This is cache of the last value from the Paint of bitmap-filtering.
      *  In the future, BitmapShaders will carry their own (expanded) data for this
@@ -49,6 +94,15 @@
     private boolean mFilterFromPaint;
 
     /**
+     *  Stores whether or not the contents of this shader's bitmap will be sampled
+     *  without modification or if the bitmap's properties, like colorspace and
+     *  premultiplied alpha, will be respected when sampling from the bitmap's buffer.
+     */
+    private boolean mIsDirectSampled;
+
+    private boolean mRequestDirectSampling;
+
+    /**
      * Call this to create a new shader that will draw with a bitmap.
      *
      * @param bitmap The bitmap to use inside the shader
@@ -66,24 +120,60 @@
         mBitmap = bitmap;
         mTileX = tileX;
         mTileY = tileY;
+        mFilterMode = FILTER_MODE_DEFAULT;
         mFilterFromPaint = false;
+        mIsDirectSampled = false;
+        mRequestDirectSampling = false;
+    }
+
+    /**
+     * Returns the filter mode used when sampling from this shader
+     */
+    @FilterMode
+    public int getFilterMode() {
+        return mFilterMode;
+    }
+
+    /**
+     * Set the filter mode to be used when sampling from this shader
+     */
+    public void setFilterMode(@FilterMode int mode) {
+        if (mode != mFilterMode) {
+            mFilterMode = mode;
+            discardNativeInstance();
+        }
+    }
+
+    /** @hide */
+    /* package */ synchronized long getNativeInstanceWithDirectSampling() {
+        mRequestDirectSampling = true;
+        return getNativeInstance();
     }
 
     /** @hide */
     @Override
     protected long createNativeInstance(long nativeMatrix, boolean filterFromPaint) {
-        mFilterFromPaint = filterFromPaint;
+        boolean enableLinearFilter = mFilterMode == FILTER_MODE_LINEAR;
+        if (mFilterMode == FILTER_MODE_DEFAULT) {
+            mFilterFromPaint = filterFromPaint;
+            enableLinearFilter = mFilterFromPaint;
+        }
+
+        mIsDirectSampled = mRequestDirectSampling;
+        mRequestDirectSampling = false;
+
         return nativeCreate(nativeMatrix, mBitmap.getNativeInstance(), mTileX, mTileY,
-                            mFilterFromPaint);
+                            enableLinearFilter, mIsDirectSampled);
     }
 
     /** @hide */
     @Override
     protected boolean shouldDiscardNativeInstance(boolean filterFromPaint) {
-        return mFilterFromPaint != filterFromPaint;
+        return mIsDirectSampled != mRequestDirectSampling
+                || (mFilterMode == FILTER_MODE_DEFAULT && mFilterFromPaint != filterFromPaint);
     }
 
     private static native long nativeCreate(long nativeMatrix, long bitmapHandle,
-            int shaderTileModeX, int shaderTileModeY, boolean filter);
+            int shaderTileModeX, int shaderTileModeY, boolean filter, boolean isDirectSampled);
 }
 
diff --git a/graphics/java/android/graphics/RuntimeShader.java b/graphics/java/android/graphics/RuntimeShader.java
index ef57f4a..57046f5 100644
--- a/graphics/java/android/graphics/RuntimeShader.java
+++ b/graphics/java/android/graphics/RuntimeShader.java
@@ -279,11 +279,11 @@
     }
 
     /**
-     * Sets the uniform shader that is declares as input to this shader.  If the shader does not
+     * Assigns the uniform shader to the provided shader parameter.  If the shader program does not
      * have a uniform shader with that name then an IllegalArgumentException is thrown.
      *
-     * @param shaderName name matching the uniform declared in the SKSL shader
-     * @param shader shader passed into the SKSL shader for sampling
+     * @param shaderName name matching the uniform declared in the AGSL shader program
+     * @param shader shader passed into the AGSL shader program for sampling
      */
     public void setInputShader(@NonNull String shaderName, @NonNull Shader shader) {
         if (shaderName == null) {
@@ -297,6 +297,28 @@
         discardNativeInstance();
     }
 
+    /**
+     * Assigns the uniform shader to the provided shader parameter.  If the shader program does not
+     * have a uniform shader with that name then an IllegalArgumentException is thrown.
+     *
+     * Unlike setInputShader this method returns samples directly from the bitmap's buffer. This
+     * means that there will be no transformation of the sampled pixels, such as colorspace
+     * conversion or alpha premultiplication.
+     */
+    public void setInputBuffer(@NonNull String shaderName, @NonNull BitmapShader shader) {
+        if (shaderName == null) {
+            throw new NullPointerException("The shaderName parameter must not be null");
+        }
+        if (shader == null) {
+            throw new NullPointerException("The shader parameter must not be null");
+        }
+
+        nativeUpdateShader(mNativeInstanceRuntimeShaderBuilder, shaderName,
+                shader.getNativeInstanceWithDirectSampling());
+        discardNativeInstance();
+    }
+
+
     /** @hide */
     @Override
     protected long createNativeInstance(long nativeMatrix, boolean filterFromPaint) {
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/PipAppHelper.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/PipAppHelper.kt
index 8e6fa5f..7e232ea 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/PipAppHelper.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/PipAppHelper.kt
@@ -66,7 +66,7 @@
         stringExtras: Map<String, String>
     ) {
         super.launchViaIntent(wmHelper, expectedWindowName, action, stringExtras)
-        wmHelper.waitFor("hasPipWindow") { it.wmState.hasPipWindow() }
+        wmHelper.waitPipShown()
     }
 
     private fun focusOnObject(selector: BySelector): Boolean {
@@ -88,7 +88,7 @@
         clickObject(ENTER_PIP_BUTTON_ID)
 
         // Wait on WMHelper or simply wait for 3 seconds
-        wmHelper?.waitFor("hasPipWindow") { it.wmState.hasPipWindow() } ?: SystemClock.sleep(3_000)
+        wmHelper?.waitPipShown() ?: SystemClock.sleep(3_000)
         // when entering pip, the dismiss button is visible at the start. to ensure the pip
         // animation is complete, wait until the pip dismiss button is no longer visible. 
         // b/176822698: dismiss-only state will be removed in the future
@@ -148,7 +148,7 @@
         }
 
         // Wait for animation to complete.
-        wmHelper.waitFor("!hasPipWindow") { !it.wmState.hasPipWindow() }
+        wmHelper.waitPipGone()
         wmHelper.waitForHomeActivityVisible()
     }
 
@@ -165,7 +165,7 @@
                 ?: error("PIP window expand button not found")
         val expandButtonBounds = expandPipObject.visibleBounds
         uiDevice.click(expandButtonBounds.centerX(), expandButtonBounds.centerY())
-        wmHelper.waitFor("!hasPipWindow") { !it.wmState.hasPipWindow() }
+        wmHelper.waitPipGone()
         wmHelper.waitForAppTransitionIdle()
     }
 
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt
index 2deff7b..db94de2 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.wm.shell.flicker.pip
 
+import android.platform.test.annotations.Postsubmit
 import android.platform.test.annotations.Presubmit
 import android.view.Surface
 import androidx.test.filters.FlakyTest
@@ -181,13 +182,14 @@
     }
 
     /**
-     * Checks the focus doesn't change during the animation
+     * Checks that the focus changes between the [pipApp] window and the launcher when
+     * closing the pip window
      */
-    @FlakyTest
+    @Postsubmit
     @Test
-    fun focusDoesNotChange() {
+    fun focusChanges() {
         testSpec.assertEventLog {
-            this.focusDoesNotChange()
+            this.focusChanges(pipApp.`package`, "NexusLauncherActivity")
         }
     }
 
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTest.kt
index 0e73463..dee13c1 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTest.kt
@@ -98,7 +98,7 @@
                 // Enter PiP, and assert that the PiP is within bounds now that the device is back
                 // in portrait
                 broadcastActionTrigger.doAction(ACTION_ENTER_PIP)
-                wmHelper.waitFor { it.wmState.hasPipWindow() }
+                wmHelper.waitPipShown()
                 wmHelper.waitForAppTransitionIdle()
                 // during rotation the status bar becomes invisible and reappears at the end
                 wmHelper.waitForNavBarStatusBarVisible()
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipTransition.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipTransition.kt
index 9a22007..173140d 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipTransition.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipTransition.kt
@@ -16,9 +16,9 @@
 
 package com.android.wm.shell.flicker.pip
 
+import android.platform.test.annotations.Postsubmit
 import android.platform.test.annotations.Presubmit
 import android.view.Surface
-import androidx.test.filters.FlakyTest
 import com.android.server.wm.flicker.FlickerTestParameter
 import com.android.server.wm.flicker.LAUNCHER_COMPONENT
 import com.android.server.wm.flicker.dsl.FlickerBuilder
@@ -96,14 +96,13 @@
     }
 
     /**
-     * Checks that the focus changes between the [pipApp] window and the launcher when
-     * closing the pip window
+     * Checks that the focus doesn't change between windows during the transition
      */
-    @FlakyTest(bugId = 151179149)
+    @Postsubmit
     @Test
-    open fun focusChanges() {
+    open fun focusDoesNotChange() {
         testSpec.assertEventLog {
-            this.focusChanges(pipApp.launcherName, "NexusLauncherActivity")
+            this.focusDoesNotChange()
         }
     }
 }
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithSwipeDownTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithSwipeDownTest.kt
index c036515..6524182 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithSwipeDownTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithSwipeDownTest.kt
@@ -63,7 +63,7 @@
                 val pipCenterY = pipRegion.centerY()
                 val displayCenterX = device.displayWidth / 2
                 device.swipe(pipCenterX, pipCenterY, displayCenterX, device.displayHeight, 10)
-                wmHelper.waitFor("!hasPipWindow") { !it.wmState.hasPipWindow() }
+                wmHelper.waitPipGone()
                 wmHelper.waitForWindowSurfaceDisappeared(pipApp.component)
                 wmHelper.waitForAppTransitionIdle()
             }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt
index ef9ff4f..8d14f70 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.wm.shell.flicker.pip
 
+import android.platform.test.annotations.Postsubmit
 import android.platform.test.annotations.Presubmit
 import android.view.Surface
 import androidx.test.filters.FlakyTest
@@ -148,7 +149,7 @@
     /**
      * Checks that the focus doesn't change between windows during the transition
      */
-    @FlakyTest
+    @Postsubmit
     @Test
     fun focusDoesNotChange() {
         testSpec.assertEventLog {
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTransition.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTransition.kt
index 93a4e1b..bb66f7b 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTransition.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTransition.kt
@@ -125,13 +125,13 @@
                     removeAllTasksButHome()
                     if (!eachRun) {
                         pipApp.launchViaIntent(wmHelper, stringExtras = stringExtras)
-                        wmHelper.waitFor { it.wmState.hasPipWindow() }
+                        wmHelper.waitPipShown()
                     }
                 }
                 eachRun {
                     if (eachRun) {
                         pipApp.launchViaIntent(wmHelper, stringExtras = stringExtras)
-                        wmHelper.waitFor { it.wmState.hasPipWindow() }
+                        wmHelper.waitPipShown()
                     }
                 }
             }
diff --git a/libs/hwui/jni/Shader.cpp b/libs/hwui/jni/Shader.cpp
index c4366f75..c505b53 100644
--- a/libs/hwui/jni/Shader.cpp
+++ b/libs/hwui/jni/Shader.cpp
@@ -64,7 +64,8 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////
 
 static jlong BitmapShader_constructor(JNIEnv* env, jobject o, jlong matrixPtr, jlong bitmapHandle,
-        jint tileModeX, jint tileModeY, bool filter) {
+                                      jint tileModeX, jint tileModeY, bool filter,
+                                      bool isDirectSampled) {
     const SkMatrix* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
     sk_sp<SkImage> image;
     if (bitmapHandle) {
@@ -79,8 +80,12 @@
     }
     SkSamplingOptions sampling(filter ? SkFilterMode::kLinear : SkFilterMode::kNearest,
                                SkMipmapMode::kNone);
-    sk_sp<SkShader> shader = image->makeShader(
-            (SkTileMode)tileModeX, (SkTileMode)tileModeY, sampling);
+    sk_sp<SkShader> shader;
+    if (isDirectSampled) {
+        shader = image->makeRawShader((SkTileMode)tileModeX, (SkTileMode)tileModeY, sampling);
+    } else {
+        shader = image->makeShader((SkTileMode)tileModeX, (SkTileMode)tileModeY, sampling);
+    }
     ThrowIAE_IfNull(env, shader.get());
 
     if (matrix) {
@@ -393,7 +398,7 @@
 };
 
 static const JNINativeMethod gBitmapShaderMethods[] = {
-    { "nativeCreate",      "(JJIIZ)J",  (void*)BitmapShader_constructor },
+        {"nativeCreate", "(JJIIZZ)J", (void*)BitmapShader_constructor},
 };
 
 static const JNINativeMethod gLinearGradientMethods[] = {
diff --git a/media/java/Android.bp b/media/java/Android.bp
index eeaf6e9..c7c1d54 100644
--- a/media/java/Android.bp
+++ b/media/java/Android.bp
@@ -8,7 +8,7 @@
 }
 
 filegroup {
-    name: "framework-media-sources",
+    name: "framework-media-non-updatable-sources",
     srcs: [
         "**/*.java",
         "**/*.aidl",
diff --git a/media/java/android/media/Spatializer.java b/media/java/android/media/Spatializer.java
index f3f8bbe..030d212 100644
--- a/media/java/android/media/Spatializer.java
+++ b/media/java/android/media/Spatializer.java
@@ -215,6 +215,29 @@
     public static final int HEAD_TRACKING_MODE_RELATIVE_DEVICE = 2;
 
     /**
+     * @hide
+     * Head tracking mode to string conversion
+     * @param mode a valid head tracking mode
+     * @return a string containing the matching constant name
+     */
+    public static final String headtrackingModeToString(int mode) {
+        switch(mode) {
+            case HEAD_TRACKING_MODE_UNSUPPORTED:
+                return "HEAD_TRACKING_MODE_UNSUPPORTED";
+            case HEAD_TRACKING_MODE_DISABLED:
+                return "HEAD_TRACKING_MODE_DISABLED";
+            case HEAD_TRACKING_MODE_OTHER:
+                return "HEAD_TRACKING_MODE_OTHER";
+            case HEAD_TRACKING_MODE_RELATIVE_WORLD:
+                return "HEAD_TRACKING_MODE_RELATIVE_WORLD";
+            case HEAD_TRACKING_MODE_RELATIVE_DEVICE:
+                return "HEAD_TRACKING_MODE_RELATIVE_DEVICE";
+            default:
+                return "head tracking mode unknown " + mode;
+        }
+    }
+
+    /**
      * Return the level of support for the spatialization feature on this device.
      * This level of support is independent of whether the {@code Spatializer} is currently
      * enabled or available and will not change over time.
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/BtProfileConnectionInfoTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/BtProfileConnectionInfoTest.java
new file mode 100644
index 0000000..fd66d3b
--- /dev/null
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/BtProfileConnectionInfoTest.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.mediaframeworktest.unit;
+
+import static org.junit.Assert.assertEquals;
+
+import android.bluetooth.BluetoothProfile;
+import android.media.BtProfileConnectionInfo;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class BtProfileConnectionInfoTest {
+
+    @Test
+    public void testCoverageA2dp() {
+        final boolean supprNoisy = false;
+        final int volume = 42;
+        final BtProfileConnectionInfo info = BtProfileConnectionInfo.a2dpInfo(supprNoisy, volume);
+        assertEquals(info.getProfile(), BluetoothProfile.A2DP);
+        assertEquals(info.getSuppressNoisyIntent(), supprNoisy);
+        assertEquals(info.getVolume(), volume);
+    }
+
+    @Test
+    public void testCoverageA2dpSink() {
+        final int volume = 42;
+        final BtProfileConnectionInfo info = BtProfileConnectionInfo.a2dpSinkInfo(volume);
+        assertEquals(info.getProfile(), BluetoothProfile.A2DP_SINK);
+        assertEquals(info.getVolume(), volume);
+    }
+
+    @Test
+    public void testCoveragehearingAid() {
+        final boolean supprNoisy = true;
+        final BtProfileConnectionInfo info = BtProfileConnectionInfo.hearingAidInfo(supprNoisy);
+        assertEquals(info.getProfile(), BluetoothProfile.HEARING_AID);
+        assertEquals(info.getSuppressNoisyIntent(), supprNoisy);
+    }
+
+    @Test
+    public void testCoverageLeAudio() {
+        final boolean supprNoisy = false;
+        final boolean isLeOutput = true;
+        final BtProfileConnectionInfo info = BtProfileConnectionInfo.leAudio(supprNoisy,
+                isLeOutput);
+        assertEquals(info.getProfile(), BluetoothProfile.LE_AUDIO);
+        assertEquals(info.getSuppressNoisyIntent(), supprNoisy);
+        assertEquals(info.getIsLeOutput(), isLeOutput);
+    }
+}
+
diff --git a/packages/ConnectivityT/framework-t/src/android/net/TrafficStats.java b/packages/ConnectivityT/framework-t/src/android/net/TrafficStats.java
index d8feb88..1af32bf 100644
--- a/packages/ConnectivityT/framework-t/src/android/net/TrafficStats.java
+++ b/packages/ConnectivityT/framework-t/src/android/net/TrafficStats.java
@@ -17,6 +17,7 @@
 package android.net;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.SuppressLint;
 import android.annotation.SystemApi;
 import android.annotation.TestApi;
@@ -27,8 +28,8 @@
 import android.content.Context;
 import android.media.MediaPlayer;
 import android.os.Build;
+import android.os.IBinder;
 import android.os.RemoteException;
-import android.os.ServiceManager;
 
 import com.android.server.NetworkManagementSocketTagger;
 
@@ -36,6 +37,8 @@
 
 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;
@@ -53,6 +56,7 @@
  * use {@link NetworkStatsManager} instead.
  */
 public class TrafficStats {
+    private static final String TAG = TrafficStats.class.getSimpleName();
     /**
      * The return value to indicate that the device does not support the statistic.
      */
@@ -173,12 +177,25 @@
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 130143562)
     private synchronized static INetworkStatsService getStatsService() {
         if (sStatsService == null) {
-            sStatsService = INetworkStatsService.Stub.asInterface(
-                    ServiceManager.getService(Context.NETWORK_STATS_SERVICE));
+            sStatsService = getStatsBinder();
         }
         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.
@@ -265,6 +282,18 @@
     }
 
     /**
+     * Set active tag to use when accounting {@link Socket} traffic originating
+     * from the current thread. The tag used internally is well-defined to
+     * distinguish all download provider traffic.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static void setThreadStatsTagDownload() {
+        setThreadStatsTag(TAG_SYSTEM_DOWNLOAD);
+    }
+
+    /**
      * Get the active tag used when accounting {@link Socket} traffic originating
      * from the current thread. Only one active tag per thread is supported.
      * {@link #tagSocket(Socket)}.
diff --git a/packages/ConnectivityT/framework-t/src/com/android/server/NetworkManagementSocketTagger.java b/packages/ConnectivityT/framework-t/src/com/android/server/NetworkManagementSocketTagger.java
index e35f6a6..1eb52fb 100644
--- a/packages/ConnectivityT/framework-t/src/com/android/server/NetworkManagementSocketTagger.java
+++ b/packages/ConnectivityT/framework-t/src/com/android/server/NetworkManagementSocketTagger.java
@@ -26,6 +26,7 @@
 
 /**
  * Assigns tags to sockets for traffic stats.
+ * @hide
  */
 public final class NetworkManagementSocketTagger extends SocketTagger {
     private static final String TAG = "NetworkManagementSocketTagger";
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginManagerImpl.java b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginManagerImpl.java
index 7539f99..851ea65 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginManagerImpl.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginManagerImpl.java
@@ -137,7 +137,8 @@
         filter.addAction(PLUGIN_CHANGED);
         filter.addAction(DISABLE_PLUGIN);
         filter.addDataScheme("package");
-        mContext.registerReceiver(this, filter, PluginActionManager.PLUGIN_PERMISSION, null);
+        mContext.registerReceiver(this, filter, PluginActionManager.PLUGIN_PERMISSION, null,
+                Context.RECEIVER_EXPORTED_UNAUDITED);
         filter = new IntentFilter(Intent.ACTION_USER_UNLOCKED);
         mContext.registerReceiver(this, filter);
     }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardEsimArea.java b/packages/SystemUI/src/com/android/keyguard/KeyguardEsimArea.java
index 26c227d..8bcb7c9 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardEsimArea.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardEsimArea.java
@@ -91,7 +91,8 @@
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
         mContext.registerReceiver(mReceiver, new IntentFilter(ACTION_DISABLE_ESIM),
-                PERMISSION_SELF, null /* scheduler */);
+                PERMISSION_SELF, null /* scheduler */,
+                Context.RECEIVER_EXPORTED_UNAUDITED);
     }
 
     public static boolean isEsimLocked(Context context, int subId) {
diff --git a/packages/SystemUI/src/com/android/systemui/SliceBroadcastRelayHandler.java b/packages/SystemUI/src/com/android/systemui/SliceBroadcastRelayHandler.java
index d7da63b..1f2de4c 100644
--- a/packages/SystemUI/src/com/android/systemui/SliceBroadcastRelayHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/SliceBroadcastRelayHandler.java
@@ -112,7 +112,8 @@
 
         public void register(Context context, ComponentName receiver, IntentFilter filter) {
             mReceivers.add(receiver);
-            context.registerReceiver(this, filter);
+            context.registerReceiver(this, filter,
+                    Context.RECEIVER_EXPORTED_UNAUDITED);
         }
 
         public void unregister(Context context) {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
index 1ac9016..2b12f67 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
@@ -518,7 +518,7 @@
         IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
 
-        context.registerReceiver(mBroadcastReceiver, filter);
+        context.registerReceiver(mBroadcastReceiver, filter, Context.RECEIVER_EXPORTED_UNAUDITED);
         mSensorPrivacyManager = context.getSystemService(SensorPrivacyManager.class);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index d208441..6581490 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
@@ -539,7 +539,8 @@
 
         final IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
-        context.registerReceiver(mBroadcastReceiver, filter);
+        context.registerReceiver(mBroadcastReceiver, filter,
+                Context.RECEIVER_EXPORTED_UNAUDITED);
 
         udfpsHapticsSimulator.setUdfpsController(this);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebug.java b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebug.java
index 89623f4..f3b721c 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebug.java
+++ b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebug.java
@@ -88,7 +88,8 @@
         filter.addAction(ACTION_GET_FLAGS);
         flagManager.setRestartAction(this::restartSystemUI);
         flagManager.setClearCacheAction(this::removeFromCache);
-        context.registerReceiver(mReceiver, filter, null, null);
+        context.registerReceiver(mReceiver, filter, null, null,
+                Context.RECEIVER_EXPORTED_UNAUDITED);
         dumpManager.registerDumpable(TAG, this);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 5ca2539..fdd6f65 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -894,7 +894,8 @@
         delayedActionFilter.addAction(DELAYED_KEYGUARD_ACTION);
         delayedActionFilter.addAction(DELAYED_LOCK_PROFILE_ACTION);
         mContext.registerReceiver(mDelayedLockBroadcastReceiver, delayedActionFilter,
-                SYSTEMUI_PERMISSION, null /* scheduler */);
+                SYSTEMUI_PERMISSION, null /* scheduler */,
+                Context.RECEIVER_EXPORTED_UNAUDITED);
 
         mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
 
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
index 4e039279..83d581f 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
@@ -539,7 +539,8 @@
     }
 
     boolean isVolumeControlEnabled(@NonNull MediaDevice device) {
-        return !device.getFeatures().contains(MediaRoute2Info.FEATURE_REMOTE_GROUP_PLAYBACK)
+        // TODO(b/202500642): Also enable volume control for remote non-group sessions.
+        return !isActiveRemoteDevice(device)
             || mVolumeAdjustmentForRemoteGroupSessions;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
index 9dc823b..d785059 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
@@ -293,7 +293,8 @@
 
         IntentFilter internalFilter = new IntentFilter();
         internalFilter.addAction(NOTIFICATION_UNLOCKED_BY_WORK_CHALLENGE_ACTION);
-        mContext.registerReceiver(mBaseBroadcastReceiver, internalFilter, PERMISSION_SELF, null);
+        mContext.registerReceiver(mBaseBroadcastReceiver, internalFilter, PERMISSION_SELF, null,
+                Context.RECEIVER_EXPORTED_UNAUDITED);
 
         mCurrentUserId = ActivityManager.getCurrentUser(); // in case we reg'd receiver too late
         updateCurrentProfilesCache();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 137c519..649aa42 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -1003,7 +1003,7 @@
         internalFilter.addAction(BANNER_ACTION_CANCEL);
         internalFilter.addAction(BANNER_ACTION_SETUP);
         mContext.registerReceiver(mBannerActionBroadcastReceiver, internalFilter, PERMISSION_SELF,
-                null);
+                null, Context.RECEIVER_EXPORTED_UNAUDITED);
 
         if (mWallpaperSupported) {
             IWallpaperManager wallpaperManager = IWallpaperManager.Stub.asInterface(
@@ -1332,7 +1332,8 @@
             demoFilter.addAction(ACTION_FAKE_ARTWORK);
         }
         mContext.registerReceiverAsUser(mDemoReceiver, UserHandle.ALL, demoFilter,
-                android.Manifest.permission.DUMP, null);
+                android.Manifest.permission.DUMP, null,
+                Context.RECEIVER_EXPORTED_UNAUDITED);
 
         // listen for USER_SETUP_COMPLETE setting (per-user)
         mDeviceProvisionedController.addCallback(mUserSetupObserver);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java
index c1f63b8..05a586b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java
@@ -128,7 +128,7 @@
                         update(true /* updateAlways */);
                     }
                 }
-            }, filter, null, null);
+            }, filter, null, null, Context.RECEIVER_EXPORTED_UNAUDITED);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoControllerImpl.java
index f42e388..29285f8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoControllerImpl.java
@@ -74,7 +74,7 @@
         profileFilter.addAction(ContactsContract.Intents.ACTION_PROFILE_CHANGED);
         profileFilter.addAction(Intent.ACTION_USER_INFO_CHANGED);
         mContext.registerReceiverAsUser(mProfileReceiver, UserHandle.ALL, profileFilter,
-                null, null);
+                null, null, Context.RECEIVER_EXPORTED_UNAUDITED);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
index 79ee746..9f20bc5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
@@ -229,7 +229,8 @@
 
         filter = new IntentFilter();
         mContext.registerReceiverAsUser(mReceiver, UserHandle.SYSTEM, filter,
-                PERMISSION_SELF, null /* scheduler */);
+                PERMISSION_SELF, null /* scheduler */,
+                Context.RECEIVER_EXPORTED_UNAUDITED);
 
         mSettingsObserver = new ContentObserver(mHandler) {
             @Override
diff --git a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
index 90c7f1f..cf361ec 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
@@ -167,9 +167,11 @@
         mStorageManager.registerListener(mListener);
 
         mContext.registerReceiver(mSnoozeReceiver, new IntentFilter(ACTION_SNOOZE_VOLUME),
-                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
+                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null,
+                Context.RECEIVER_EXPORTED_UNAUDITED);
         mContext.registerReceiver(mFinishReceiver, new IntentFilter(ACTION_FINISH_WIZARD),
-                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
+                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null,
+                Context.RECEIVER_EXPORTED_UNAUDITED);
 
         // Kick current state into place
         final List<DiskInfo> disks = mStorageManager.getDisks();
diff --git a/packages/SystemUI/src/com/android/systemui/volume/SafetyWarningDialog.java b/packages/SystemUI/src/com/android/systemui/volume/SafetyWarningDialog.java
index a40cf4f..5b188b2 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/SafetyWarningDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/SafetyWarningDialog.java
@@ -63,7 +63,8 @@
         setOnDismissListener(this);
 
         final IntentFilter filter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
-        context.registerReceiver(mReceiver, filter);
+        context.registerReceiver(mReceiver, filter,
+                Context.RECEIVER_EXPORTED_UNAUDITED);
     }
 
     abstract protected void cleanUp();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/SliceBroadcastRelayHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/SliceBroadcastRelayHandlerTest.java
index 7d55623..7c121e1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/SliceBroadcastRelayHandlerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/SliceBroadcastRelayHandlerTest.java
@@ -15,6 +15,7 @@
 package com.android.systemui;
 
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
@@ -79,7 +80,7 @@
         intent.putExtra(SliceBroadcastRelay.EXTRA_URI, testUri);
 
         mRelayHandler.handleIntent(intent);
-        verify(mSpyContext).registerReceiver(any(), eq(value));
+        verify(mSpyContext).registerReceiver(any(), eq(value), anyInt());
     }
 
     @Test
@@ -99,7 +100,7 @@
 
         mRelayHandler.handleIntent(intent);
         ArgumentCaptor<BroadcastReceiver> relay = ArgumentCaptor.forClass(BroadcastReceiver.class);
-        verify(mSpyContext).registerReceiver(relay.capture(), eq(value));
+        verify(mSpyContext).registerReceiver(relay.capture(), eq(value), anyInt());
 
         intent = new Intent(SliceBroadcastRelay.ACTION_UNREGISTER);
         intent.putExtra(SliceBroadcastRelay.EXTRA_URI, ContentProvider.maybeAddUserId(testUri, 0));
@@ -138,7 +139,7 @@
 
         mRelayHandler.handleIntent(intent);
         ArgumentCaptor<BroadcastReceiver> relay = ArgumentCaptor.forClass(BroadcastReceiver.class);
-        verify(mSpyContext).registerReceiver(relay.capture(), eq(value));
+        verify(mSpyContext).registerReceiver(relay.capture(), eq(value), anyInt());
         relay.getValue().onReceive(mSpyContext, new Intent(TEST_ACTION));
 
         verify(Receiver.sReceiver, timeout(2000)).onReceive(any(), any());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestableContext.java b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestableContext.java
index 3d679de..0674ea8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestableContext.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestableContext.java
@@ -83,6 +83,16 @@
     }
 
     @Override
+    public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, int flags) {
+        if (receiver != null) {
+            synchronized (mRegisteredReceivers) {
+                mRegisteredReceivers.add(receiver);
+            }
+        }
+        return super.registerReceiver(receiver, filter, flags);
+    }
+
+    @Override
     public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
             String broadcastPermission, Handler scheduler) {
         if (receiver != null) {
@@ -94,6 +104,17 @@
     }
 
     @Override
+    public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
+            String broadcastPermission, Handler scheduler, int flags) {
+        if (receiver != null) {
+            synchronized (mRegisteredReceivers) {
+                mRegisteredReceivers.add(receiver);
+            }
+        }
+        return super.registerReceiver(receiver, filter, broadcastPermission, scheduler, flags);
+    }
+
+    @Override
     public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user,
             IntentFilter filter, String broadcastPermission, Handler scheduler) {
         if (receiver != null) {
@@ -105,6 +126,18 @@
     }
 
     @Override
+    public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user,
+            IntentFilter filter, String broadcastPermission, Handler scheduler, int flags) {
+        if (receiver != null) {
+            synchronized (mRegisteredReceivers) {
+                mRegisteredReceivers.add(receiver);
+            }
+        }
+        return super.registerReceiverAsUser(receiver, user, filter, broadcastPermission, scheduler,
+                flags);
+    }
+
+    @Override
     public void unregisterReceiver(BroadcastReceiver receiver) {
         if (receiver != null) {
             synchronized (mRegisteredReceivers) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsDebugTest.kt b/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsDebugTest.kt
index cb16bec..87bc732 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsDebugTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsDebugTest.kt
@@ -76,7 +76,8 @@
         )
         verify(mFlagManager).restartAction = any()
         mBroadcastReceiver = withArgCaptor {
-            verify(mMockContext).registerReceiver(capture(), any(), nullable(), nullable())
+            verify(mMockContext).registerReceiver(capture(), any(), nullable(), nullable(),
+                any())
         }
         mClearCacheAction = withArgCaptor {
             verify(mFlagManager).clearCacheAction = capture()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java
index ba7bbfe..20a3fda 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java
@@ -102,7 +102,8 @@
 
         mReceiver = new BlockingQueueIntentReceiver();
         mContext.registerReceiver(mReceiver, new IntentFilter(TEST_ACTION), null,
-                Handler.createAsync(Dependency.get(Dependency.BG_LOOPER)));
+                Handler.createAsync(Dependency.get(Dependency.BG_LOOPER)),
+                Context.RECEIVER_EXPORTED_UNAUDITED);
 
         // Avoid SecurityException RemoteInputView#sendRemoteInput().
         mContext.addMockSystemService(ShortcutManager.class, mShortcutManager);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java
index 32aee2b..0e25d24 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java
@@ -30,6 +30,7 @@
 import android.app.Notification;
 import android.app.PendingIntent;
 import android.app.RemoteInput;
+import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.res.Resources;
@@ -119,7 +120,8 @@
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         mReceiver = new BlockingQueueIntentReceiver();
-        mContext.registerReceiver(mReceiver, new IntentFilter(TEST_ACTION));
+        mContext.registerReceiver(mReceiver, new IntentFilter(TEST_ACTION),
+                Context.RECEIVER_EXPORTED_UNAUDITED);
         mKeyguardDismissUtil.setDismissHandler((action, unused, afterKgGone) -> action.onDismiss());
         mDependency.injectMockDependency(KeyguardUpdateMonitor.class);
         mDependency.injectMockDependency(ShadeController.class);
diff --git a/services/Android.bp b/services/Android.bp
index 74d7f65..f33c8c0 100644
--- a/services/Android.bp
+++ b/services/Android.bp
@@ -77,6 +77,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",
diff --git a/services/companion/java/com/android/server/companion/AssociationStoreImpl.java b/services/companion/java/com/android/server/companion/AssociationStoreImpl.java
index 5b318d3..dbcdd0f 100644
--- a/services/companion/java/com/android/server/companion/AssociationStoreImpl.java
+++ b/services/companion/java/com/android/server/companion/AssociationStoreImpl.java
@@ -37,6 +37,7 @@
 import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
+import java.util.StringJoiner;
 
 /**
  * Implementation of the {@link AssociationStore}, with addition of the methods for modification.
@@ -58,33 +59,15 @@
     private final Object mLock = new Object();
 
     @GuardedBy("mLock")
-    private final Map<Integer, AssociationInfo> mIdMap;
+    private final Map<Integer, AssociationInfo> mIdMap = new HashMap<>();
     @GuardedBy("mLock")
-    private final Map<MacAddress, Set<Integer>> mAddressMap;
+    private final Map<MacAddress, Set<Integer>> mAddressMap = new HashMap<>();
     @GuardedBy("mLock")
     private final SparseArray<List<AssociationInfo>> mCachedPerUser = new SparseArray<>();
 
     @GuardedBy("mListeners")
     private final Set<OnChangeListener> mListeners = new LinkedHashSet<>();
 
-    AssociationStoreImpl(Collection<AssociationInfo> associations) {
-        synchronized (mLock) {
-            final int size = associations.size();
-            mIdMap = new HashMap<>(size);
-            mAddressMap = new HashMap<>(size);
-
-            for (AssociationInfo association : associations) {
-                final int id = association.getId();
-                mIdMap.put(id, association);
-
-                final MacAddress address = association.getDeviceMacAddress();
-                if (address != null) {
-                    mAddressMap.computeIfAbsent(address, it -> new HashSet<>()).add(id);
-                }
-            }
-        }
-    }
-
     void addAssociation(@NonNull AssociationInfo association) {
         final int id = association.getId();
 
@@ -301,4 +284,38 @@
             }
         }
     }
+
+    void setAssociations(Collection<AssociationInfo> allAssociations) {
+        if (DEBUG) {
+            Log.i(TAG, "setAssociations() n=" + allAssociations.size());
+            final StringJoiner stringJoiner = new StringJoiner(", ");
+            allAssociations.forEach(assoc -> stringJoiner.add(assoc.toShortString()));
+            Log.v(TAG, "  associations=" + stringJoiner);
+        }
+        synchronized (mLock) {
+            setAssociationsLocked(allAssociations);
+        }
+    }
+
+    @GuardedBy("mLock")
+    private void setAssociationsLocked(Collection<AssociationInfo> associations) {
+        clearLocked();
+
+        for (AssociationInfo association : associations) {
+            final int id = association.getId();
+            mIdMap.put(id, association);
+
+            final MacAddress address = association.getDeviceMacAddress();
+            if (address != null) {
+                mAddressMap.computeIfAbsent(address, it -> new HashSet<>()).add(id);
+            }
+        }
+    }
+
+    @GuardedBy("mLock")
+    private void clearLocked() {
+        mIdMap.clear();
+        mAddressMap.clear();
+        mCachedPerUser.clear();
+    }
 }
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
index 1c98347..1e50c80 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
@@ -159,7 +159,7 @@
 
     // Persistent data store for all Associations.
     private PersistentDataStore mPersistentStore;
-    private AssociationStoreImpl mAssociationStore;
+    private final AssociationStoreImpl mAssociationStore = new AssociationStoreImpl();
     private AssociationRequestsProcessor mAssociationRequestsProcessor;
 
     private PowerWhitelistManager mPowerWhitelistManager;
@@ -219,16 +219,8 @@
     @Override
     public void onStart() {
         mPersistentStore = new PersistentDataStore();
-        final Set<AssociationInfo> allAssociations = new ArraySet<>();
 
-        synchronized (mPreviouslyUsedIds) {
-            // The data is stored in DE directories, so we can read the data for all users now
-            // (which would not be possible if the data was stored to CE directories).
-            mPersistentStore.readStateForUsers(
-                    mUserManager.getAliveUsers(), allAssociations, mPreviouslyUsedIds);
-        }
-
-        mAssociationStore = new AssociationStoreImpl(allAssociations);
+        loadAssociationsFromDisk();
         mAssociationStore.registerListener(this);
 
         mCompanionDevicePresenceController = new CompanionDevicePresenceController(this);
@@ -239,6 +231,18 @@
         publishBinderService(Context.COMPANION_DEVICE_SERVICE, impl);
     }
 
+    void loadAssociationsFromDisk() {
+        final Set<AssociationInfo> allAssociations = new ArraySet<>();
+        synchronized (mPreviouslyUsedIds) {
+            // The data is stored in DE directories, so we can read the data for all users now
+            // (which would not be possible if the data was stored to CE directories).
+            mPersistentStore.readStateForUsers(
+                    mUserManager.getAliveUsers(), allAssociations, mPreviouslyUsedIds);
+        }
+
+        mAssociationStore.setAssociations(allAssociations);
+    }
+
     @Override
     public void onBootPhase(int phase) {
         if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceShellCommand.java b/services/companion/java/com/android/server/companion/CompanionDeviceShellCommand.java
index 5c0571d..5f46d5c 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceShellCommand.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceShellCommand.java
@@ -82,7 +82,10 @@
                     mService.onDeviceDisconnected(getNextArgRequired());
                 }
                 break;
-
+                case "clear-association-memory-cache": {
+                    mService.loadAssociationsFromDisk();
+                }
+                break;
                 default:
                     return handleDefaultCommands(cmd);
             }
@@ -110,5 +113,8 @@
         pw.println("      Create a new Association.");
         pw.println("  disassociate USER_ID PACKAGE MAC_ADDRESS");
         pw.println("      Remove an existing Association.");
+        pw.println("  clear-association-memory-cache");
+        pw.println("      Clear the in-memory association cache and reload all association "
+                + "information from persistent storage. USE FOR DEBUGGING PURPOSES ONLY.");
     }
 }
diff --git a/services/core/Android.bp b/services/core/Android.bp
index 95ec9e9..094ed37 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -103,6 +103,7 @@
         ":android.hardware.biometrics.face-V2-java-source",
         ":statslog-art-java-gen",
         ":statslog-contexthub-java-gen",
+        ":services.bluetooth-sources", // TODO(b/214988855) : Remove once apex is ready
         ":services.core-sources",
         ":services.core.protologsrc",
         ":dumpstate_aidl",
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 262933d..0000000
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ /dev/null
@@ -1,2962 +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.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 static android.permission.PermissionCheckerManager.PERMISSION_HARD_DENIED;
-
-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.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.permission.PermissionManager;
-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 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,
-                Settings.Secure.BLUETOOTH_NAME, 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, Settings.Secure.BLUETOOTH_NAME, mUserId);
-        mAddress = Settings.Secure.getStringForUser(
-                mContentResolver, Settings.Secure.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, Settings.Secure.BLUETOOTH_NAME, name,
-                    mUserId);
-            mName = name;
-            if (DBG) {
-                Slog.d(TAG, "Stored Bluetooth name: " + Settings.Secure.getStringForUser(
-                        mContentResolver, Settings.Secure.BLUETOOTH_NAME,
-                        mUserId));
-            }
-        }
-
-        if (address != null) {
-            Settings.Secure.putStringForUser(mContentResolver, Settings.Secure.BLUETOOTH_ADDRESS,
-                    address, mUserId);
-            mAddress = address;
-            if (DBG) {
-                Slog.d(TAG,
-                        "Stored Bluetoothaddress: " + Settings.Secure.getStringForUser(
-                                mContentResolver, Settings.Secure.BLUETOOTH_ADDRESS,
-                                mUserId));
-            }
-        }
-
-        if ((name != null) && (address != null)) {
-            Settings.Secure.putIntForUser(mContentResolver, Settings.Secure.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) {
-        PermissionManager pm = context.getSystemService(PermissionManager.class);
-        if (pm == null) {
-            return false;
-        }
-        AttributionSource currentAttribution = new AttributionSource
-                .Builder(context.getAttributionSource())
-                .setNext(attributionSource)
-                .build();
-        final int result = pm.checkPermissionForDataDeliveryFromDataSource(permission,
-                currentAttribution, 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/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 70bd734..e933526 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -393,6 +393,7 @@
 import com.android.server.job.JobSchedulerInternal;
 import com.android.server.os.NativeTombstoneManager;
 import com.android.server.pm.Installer;
+import com.android.server.pm.UserManagerInternal;
 import com.android.server.pm.parsing.pkg.AndroidPackage;
 import com.android.server.pm.permission.PermissionManagerServiceInternal;
 import com.android.server.uri.GrantUri;
@@ -13312,6 +13313,14 @@
             }
 
             switch (action) {
+                case Intent.ACTION_MEDIA_SCANNER_SCAN_FILE:
+                    UserManagerInternal umInternal = LocalServices.getService(
+                            UserManagerInternal.class);
+                    UserInfo userInfo = umInternal.getUserInfo(userId);
+                    if (userInfo != null && userInfo.isCloneProfile()) {
+                        userId = umInternal.getProfileParentId(userId);
+                    }
+                    break;
                 case Intent.ACTION_UID_REMOVED:
                 case Intent.ACTION_PACKAGE_REMOVED:
                 case Intent.ACTION_PACKAGE_CHANGED:
diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
index 2fcdd61..565e295 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
@@ -1219,6 +1219,7 @@
                         mDeviceInventory.onSetBtActiveDevice((BtDeviceInfo) msg.obj,
                                 mAudioService.getBluetoothContextualVolumeStream());
                     }
+                    break;
                 case MSG_BT_HEADSET_CNCT_FAILED:
                     synchronized (mSetModeLock) {
                         synchronized (mDeviceStateLock) {
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 346ae0f..57ae36ed 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -9408,6 +9408,7 @@
         pw.println("mHasSpatializerEffect:" + mHasSpatializerEffect);
         pw.println("isSpatializerEnabled:" + isSpatializerEnabled());
         pw.println("isSpatialAudioEnabled:" + isSpatialAudioEnabled());
+        mSpatializerHelper.dump(pw);
 
         mAudioSystem.dump(pw);
     }
diff --git a/services/core/java/com/android/server/audio/SpatializerHelper.java b/services/core/java/com/android/server/audio/SpatializerHelper.java
index b47ea4f..e6789d5 100644
--- a/services/core/java/com/android/server/audio/SpatializerHelper.java
+++ b/services/core/java/com/android/server/audio/SpatializerHelper.java
@@ -39,6 +39,7 @@
 import android.os.RemoteException;
 import android.util.Log;
 
+import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Locale;
@@ -84,7 +85,7 @@
     private int mSpatLevel = Spatializer.SPATIALIZER_IMMERSIVE_LEVEL_NONE;
     private int mCapableSpatLevel = Spatializer.SPATIALIZER_IMMERSIVE_LEVEL_NONE;
     private int mActualHeadTrackingMode = Spatializer.HEAD_TRACKING_MODE_UNSUPPORTED;
-    private int mDesiredHeadTrackingMode = Spatializer.HEAD_TRACKING_MODE_UNSUPPORTED;
+    private int mDesiredHeadTrackingMode = Spatializer.HEAD_TRACKING_MODE_RELATIVE_WORLD;
     private int mSpatOutput = 0;
     private @Nullable ISpatializer mSpat;
     private @Nullable SpatializerCallback mSpatCallback;
@@ -681,12 +682,13 @@
             return;
         }
         try {
-            if (mode != mDesiredHeadTrackingMode) {
-                mSpat.setDesiredHeadTrackingMode(spatializerIntToHeadTrackingModeType(mode));
+            if (mDesiredHeadTrackingMode != mode) {
                 mDesiredHeadTrackingMode = mode;
                 dispatchDesiredHeadTrackingMode(mode);
             }
-
+            if (mode != headTrackingModeTypeToSpatializerInt(mSpat.getActualHeadTrackingMode())) {
+                mSpat.setDesiredHeadTrackingMode(spatializerIntToHeadTrackingModeType(mode));
+            }
         } catch (RemoteException e) {
             Log.e(TAG, "Error calling setDesiredHeadTrackingMode", e);
         }
@@ -937,6 +939,7 @@
         } catch (Exception e) {
             Log.e(TAG, "Error calling setHeadSensor:" + headHandle, e);
         }
+        setDesiredHeadTrackingMode(mDesiredHeadTrackingMode);
     }
 
     //------------------------------------------------------
@@ -983,4 +986,22 @@
                 throw(new IllegalArgumentException("Unexpected spatializer level:" + level));
         }
     }
+
+    void dump(PrintWriter pw) {
+        pw.println("SpatializerHelper:");
+        pw.println("\tmState:" + mState);
+        pw.println("\tmSpatLevel:" + mSpatLevel);
+        pw.println("\tmCapableSpatLevel:" + mCapableSpatLevel);
+        pw.println("\tmActualHeadTrackingMode:"
+                + Spatializer.headtrackingModeToString(mActualHeadTrackingMode));
+        pw.println("\tmDesiredHeadTrackingMode:"
+                + Spatializer.headtrackingModeToString(mDesiredHeadTrackingMode));
+        String modesString = "";
+        int[] modes = getSupportedHeadTrackingModes();
+        for (int mode : modes) {
+            modesString += Spatializer.headtrackingModeToString(mode) + " ";
+        }
+        pw.println("\tsupported head tracking modes:" + modesString);
+        pw.println("\tmSpatOutput:" + mSpatOutput);
+    }
 }
diff --git a/services/core/java/com/android/server/broadcastradio/hal2/ProgramInfoCache.java b/services/core/java/com/android/server/broadcastradio/hal2/ProgramInfoCache.java
index 8c93891..6654c0c 100644
--- a/services/core/java/com/android/server/broadcastradio/hal2/ProgramInfoCache.java
+++ b/services/core/java/com/android/server/broadcastradio/hal2/ProgramInfoCache.java
@@ -189,7 +189,8 @@
                 removed.add(id);
             }
         }
-        if (modified.isEmpty() && removed.isEmpty() && mComplete == chunk.isComplete()) {
+        if (modified.isEmpty() && removed.isEmpty() && mComplete == chunk.isComplete()
+                && !chunk.isPurge()) {
             return null;
         }
         mComplete = chunk.isComplete();
@@ -239,9 +240,10 @@
         }
 
         // Determine number of chunks we need to send.
-        int numChunks = 0;
+        int numChunks = purge ? 1 : 0;
         if (modified != null) {
-            numChunks = roundUpFraction(modified.size(), maxNumModifiedPerChunk);
+            numChunks = Math.max(numChunks,
+                    roundUpFraction(modified.size(), maxNumModifiedPerChunk));
         }
         if (removed != null) {
             numChunks = Math.max(numChunks, roundUpFraction(removed.size(), maxNumRemovedPerChunk));
diff --git a/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java b/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java
index cc9efbc..fce6737 100644
--- a/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java
+++ b/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java
@@ -199,6 +199,7 @@
         private final NetworkTemplate mNetworkTemplate;
         private final UsageCallback mUsageCallback;
         private NetworkCapabilities mNetworkCapabilities;
+        private final NetworkStatsManager mStatsManager;
 
         public MultipathTracker(Network network, NetworkCapabilities nc) {
             this.network = network;
@@ -238,6 +239,13 @@
                     updateMultipathBudget();
                 }
             };
+            mStatsManager = mContext.getSystemService(NetworkStatsManager.class);
+            // Query stats from NetworkStatsService will trigger a poll by default.
+            // But since MultipathPolicyTracker listens NPMS events that triggered by
+            // stats updated event, and will query stats
+            // after the event. A polling -> updated -> query -> polling loop will be introduced
+            // if polls on open. Hence, set flag to false to prevent a polling loop.
+            mStatsManager.setPollOnOpen(false);
 
             updateMultipathBudget();
         }
@@ -262,8 +270,7 @@
         private long getNetworkTotalBytes(long start, long end) {
             try {
                 final android.app.usage.NetworkStats.Bucket ret =
-                        mContext.getSystemService(NetworkStatsManager.class)
-                        .querySummaryForDevice(mNetworkTemplate, start, end);
+                        mStatsManager.querySummaryForDevice(mNetworkTemplate, start, end);
                 return ret.getRxBytes() + ret.getTxBytes();
             } catch (RuntimeException e) {
                 Log.w(TAG, "Failed to get data usage: " + e);
diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
index ffed68e..f4c36c6 100644
--- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java
+++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
@@ -74,13 +74,6 @@
     private static final int MSG_UPDATE_FOREGROUND_APP_SYNC = 5;
     private static final int MSG_RUN_UPDATE = 6;
 
-    // Length of the ambient light horizon used to calculate the long term estimate of ambient
-    // light.
-    private static final int AMBIENT_LIGHT_LONG_HORIZON_MILLIS = 10000;
-
-    // Length of the ambient light horizon used to calculate short-term estimate of ambient light.
-    private static final int AMBIENT_LIGHT_SHORT_HORIZON_MILLIS = 2000;
-
     // Callbacks for requesting updates to the display's power state
     private final Callbacks mCallbacks;
 
@@ -125,8 +118,10 @@
     // and only then decide whether to change brightness.
     private final boolean mResetAmbientLuxAfterWarmUpConfig;
 
-    // Period of time in which to consider light samples in milliseconds.
-    private final int mAmbientLightHorizon;
+    // Period of time in which to consider light samples for a short/long-term estimate of ambient
+    // light in milliseconds.
+    private final int mAmbientLightHorizonLong;
+    private final int mAmbientLightHorizonShort;
 
     // The intercept used for the weighting calculation. This is used in order to keep all possible
     // weighting values positive.
@@ -220,6 +215,7 @@
     private Context mContext;
     private int mState = AUTO_BRIGHTNESS_DISABLED;
 
+    private Clock mClock;
     private final Injector mInjector;
 
     AutomaticBrightnessController(Callbacks callbacks, Looper looper,
@@ -231,14 +227,16 @@
             boolean resetAmbientLuxAfterWarmUpConfig, HysteresisLevels ambientBrightnessThresholds,
             HysteresisLevels screenBrightnessThresholds, Context context,
             HighBrightnessModeController hbmController,
-            BrightnessMappingStrategy idleModeBrightnessMapper) {
+            BrightnessMappingStrategy idleModeBrightnessMapper, int ambientLightHorizonShort,
+            int ambientLightHorizonLong) {
         this(new Injector(), callbacks, looper, sensorManager, lightSensor,
                 interactiveModeBrightnessMapper,
                 lightSensorWarmUpTime, brightnessMin, brightnessMax, dozeScaleFactor,
                 lightSensorRate, initialLightSensorRate, brighteningLightDebounceConfig,
                 darkeningLightDebounceConfig, resetAmbientLuxAfterWarmUpConfig,
                 ambientBrightnessThresholds, screenBrightnessThresholds, context,
-                hbmController, idleModeBrightnessMapper
+                hbmController, idleModeBrightnessMapper, ambientLightHorizonShort,
+                ambientLightHorizonLong
         );
     }
 
@@ -252,8 +250,10 @@
             boolean resetAmbientLuxAfterWarmUpConfig, HysteresisLevels ambientBrightnessThresholds,
             HysteresisLevels screenBrightnessThresholds, Context context,
             HighBrightnessModeController hbmController,
-            BrightnessMappingStrategy idleModeBrightnessMapper) {
+            BrightnessMappingStrategy idleModeBrightnessMapper, int ambientLightHorizonShort,
+            int ambientLightHorizonLong) {
         mInjector = injector;
+        mClock = injector.createClock();
         mContext = context;
         mCallbacks = callbacks;
         mSensorManager = sensorManager;
@@ -268,15 +268,16 @@
         mBrighteningLightDebounceConfig = brighteningLightDebounceConfig;
         mDarkeningLightDebounceConfig = darkeningLightDebounceConfig;
         mResetAmbientLuxAfterWarmUpConfig = resetAmbientLuxAfterWarmUpConfig;
-        mAmbientLightHorizon = AMBIENT_LIGHT_LONG_HORIZON_MILLIS;
-        mWeightingIntercept = AMBIENT_LIGHT_LONG_HORIZON_MILLIS;
+        mAmbientLightHorizonLong = ambientLightHorizonLong;
+        mAmbientLightHorizonShort = ambientLightHorizonShort;
+        mWeightingIntercept = ambientLightHorizonLong;
         mAmbientBrightnessThresholds = ambientBrightnessThresholds;
         mScreenBrightnessThresholds = screenBrightnessThresholds;
         mShortTermModelValid = true;
         mShortTermModelAnchor = -1;
         mHandler = new AutomaticBrightnessHandler(looper);
         mAmbientLightRingBuffer =
-            new AmbientLightRingBuffer(mNormalLightSensorRate, mAmbientLightHorizon);
+            new AmbientLightRingBuffer(mNormalLightSensorRate, mAmbientLightHorizonLong, mClock);
 
         if (!DEBUG_PRETEND_LIGHT_SENSOR_ABSENT) {
             mLightSensor = lightSensor;
@@ -397,6 +398,11 @@
         mHandler.sendEmptyMessage(MSG_RUN_UPDATE);
     }
 
+    @VisibleForTesting
+    float getAmbientLux() {
+        return mAmbientLux;
+    }
+
     private boolean setDisplayPolicy(int policy) {
         if (mDisplayPolicy == policy) {
             return false;
@@ -476,7 +482,8 @@
         pw.println("  mBrighteningLightDebounceConfig=" + mBrighteningLightDebounceConfig);
         pw.println("  mDarkeningLightDebounceConfig=" + mDarkeningLightDebounceConfig);
         pw.println("  mResetAmbientLuxAfterWarmUpConfig=" + mResetAmbientLuxAfterWarmUpConfig);
-        pw.println("  mAmbientLightHorizon=" + mAmbientLightHorizon);
+        pw.println("  mAmbientLightHorizonLong=" + mAmbientLightHorizonLong);
+        pw.println("  mAmbientLightHorizonShort=" + mAmbientLightHorizonShort);
         pw.println("  mWeightingIntercept=" + mWeightingIntercept);
 
         pw.println();
@@ -545,7 +552,7 @@
         if (enable) {
             if (!mLightSensorEnabled) {
                 mLightSensorEnabled = true;
-                mLightSensorEnableTime = SystemClock.uptimeMillis();
+                mLightSensorEnableTime = mClock.uptimeMillis();
                 mCurrentLightSensorRate = mInitialLightSensorRate;
                 registerForegroundAppUpdater();
                 mSensorManager.registerListener(mLightSensorListener, mLightSensor,
@@ -580,7 +587,7 @@
 
     private void applyLightSensorMeasurement(long time, float lux) {
         mRecentLightSamples++;
-        mAmbientLightRingBuffer.prune(time - mAmbientLightHorizon);
+        mAmbientLightRingBuffer.prune(time - mAmbientLightHorizonLong);
         mAmbientLightRingBuffer.push(time, lux);
 
         // Remember this sample value.
@@ -721,8 +728,8 @@
     }
 
     private void updateAmbientLux() {
-        long time = SystemClock.uptimeMillis();
-        mAmbientLightRingBuffer.prune(time - mAmbientLightHorizon);
+        long time = mClock.uptimeMillis();
+        mAmbientLightRingBuffer.prune(time - mAmbientLightHorizonLong);
         updateAmbientLux(time);
     }
 
@@ -742,7 +749,7 @@
                         timeWhenSensorWarmedUp);
                 return;
             }
-            setAmbientLux(calculateAmbientLux(time, AMBIENT_LIGHT_SHORT_HORIZON_MILLIS));
+            setAmbientLux(calculateAmbientLux(time, mAmbientLightHorizonShort));
             mAmbientLuxValid = true;
             if (mLoggingEnabled) {
                 Slog.d(TAG, "updateAmbientLux: Initializing: " +
@@ -762,8 +769,8 @@
         // proposed ambient light value since the slow value might be sufficiently far enough away
         // from the fast value to cause a recalculation while its actually just converging on
         // the fast value still.
-        float slowAmbientLux = calculateAmbientLux(time, AMBIENT_LIGHT_LONG_HORIZON_MILLIS);
-        float fastAmbientLux = calculateAmbientLux(time, AMBIENT_LIGHT_SHORT_HORIZON_MILLIS);
+        float slowAmbientLux = calculateAmbientLux(time, mAmbientLightHorizonLong);
+        float fastAmbientLux = calculateAmbientLux(time, mAmbientLightHorizonShort);
 
         if ((slowAmbientLux >= mAmbientBrighteningThreshold
                 && fastAmbientLux >= mAmbientBrighteningThreshold
@@ -1044,7 +1051,7 @@
         @Override
         public void onSensorChanged(SensorEvent event) {
             if (mLightSensorEnabled) {
-                final long time = SystemClock.uptimeMillis();
+                final long time = mClock.uptimeMillis();
                 final float lux = event.values[0];
                 handleLightSensorEvent(time, lux);
             }
@@ -1070,6 +1077,15 @@
         void updateBrightness();
     }
 
+    /** Functional interface for providing time. */
+    @VisibleForTesting
+    interface Clock {
+        /**
+         * Returns current time in milliseconds since boot, not counting time spent in deep sleep.
+         */
+        long uptimeMillis();
+    }
+
     /**
      * A ring buffer of ambient light measurements sorted by time.
      *
@@ -1089,14 +1105,16 @@
         private int mStart;
         private int mEnd;
         private int mCount;
+        Clock mClock;
 
-        public AmbientLightRingBuffer(long lightSensorRate, int ambientLightHorizon) {
+        public AmbientLightRingBuffer(long lightSensorRate, int ambientLightHorizon, Clock clock) {
             if (lightSensorRate <= 0) {
                 throw new IllegalArgumentException("lightSensorRate must be above 0");
             }
             mCapacity = (int) Math.ceil(ambientLightHorizon * BUFFER_SLACK / lightSensorRate);
             mRingLux = new float[mCapacity];
             mRingTime = new long[mCapacity];
+            mClock = clock;
         }
 
         public float getLux(int index) {
@@ -1181,7 +1199,7 @@
             StringBuilder buf = new StringBuilder();
             buf.append('[');
             for (int i = 0; i < mCount; i++) {
-                final long next = i + 1 < mCount ? getTime(i + 1) : SystemClock.uptimeMillis();
+                final long next = i + 1 < mCount ? getTime(i + 1) : mClock.uptimeMillis();
                 if (i != 0) {
                     buf.append(", ");
                 }
@@ -1210,5 +1228,9 @@
         public Handler getBackgroundThreadHandler() {
             return BackgroundThread.getHandler();
         }
+
+        Clock createClock() {
+            return SystemClock::uptimeMillis;
+        }
     }
 }
diff --git a/services/core/java/com/android/server/display/DisplayDeviceConfig.java b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
index a9e1647..3df2422 100644
--- a/services/core/java/com/android/server/display/DisplayDeviceConfig.java
+++ b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
@@ -52,6 +52,7 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.math.BigDecimal;
+import java.math.BigInteger;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -86,6 +87,13 @@
 
     private static final float NITS_INVALID = -1;
 
+    // Length of the ambient light horizon used to calculate the long term estimate of ambient
+    // light.
+    private static final int AMBIENT_LIGHT_LONG_HORIZON_MILLIS = 10000;
+
+    // Length of the ambient light horizon used to calculate short-term estimate of ambient light.
+    private static final int AMBIENT_LIGHT_SHORT_HORIZON_MILLIS = 2000;
+
     private final Context mContext;
 
     // The details of the ambient light sensor associated with this display.
@@ -120,6 +128,8 @@
     private float mBrightnessRampFastIncrease = Float.NaN;
     private float mBrightnessRampSlowDecrease = Float.NaN;
     private float mBrightnessRampSlowIncrease = Float.NaN;
+    private int mAmbientHorizonLong = AMBIENT_LIGHT_LONG_HORIZON_MILLIS;
+    private int mAmbientHorizonShort = AMBIENT_LIGHT_SHORT_HORIZON_MILLIS;
     private Spline mBrightnessToBacklightSpline;
     private Spline mBacklightToBrightnessSpline;
     private Spline mBacklightToNitsSpline;
@@ -346,6 +356,14 @@
         return mBrightnessRampSlowIncrease;
     }
 
+    public int getAmbientHorizonLong() {
+        return mAmbientHorizonLong;
+    }
+
+    public int getAmbientHorizonShort() {
+        return mAmbientHorizonShort;
+    }
+
     SensorData getAmbientLightSensor() {
         return mAmbientLightSensor;
     }
@@ -405,6 +423,8 @@
                 + ", mBrightnessRampFastIncrease=" + mBrightnessRampFastIncrease
                 + ", mBrightnessRampSlowDecrease=" + mBrightnessRampSlowDecrease
                 + ", mBrightnessRampSlowIncrease=" + mBrightnessRampSlowIncrease
+                + ", mAmbientHorizonLong=" + mAmbientHorizonLong
+                + ", mAmbientHorizonShort=" + mAmbientHorizonShort
                 + ", mAmbientLightSensor=" + mAmbientLightSensor
                 + ", mProximitySensor=" + mProximitySensor
                 + ", mRefreshRateLimitations= " + Arrays.toString(mRefreshRateLimitations.toArray())
@@ -461,6 +481,7 @@
                 loadBrightnessRamps(config);
                 loadAmbientLightSensorFromDdc(config);
                 loadProxSensorFromDdc(config);
+                loadAmbientHorizonFromDdc(config);
             } else {
                 Slog.w(TAG, "DisplayDeviceConfig file is null");
             }
@@ -869,6 +890,17 @@
         }
     }
 
+    private void loadAmbientHorizonFromDdc(DisplayConfiguration config) {
+        final BigInteger configLongHorizon = config.getAmbientLightHorizonLong();
+        if (configLongHorizon != null) {
+            mAmbientHorizonLong = configLongHorizon.intValue();
+        }
+        final BigInteger configShortHorizon = config.getAmbientLightHorizonShort();
+        if (configShortHorizon != null) {
+            mAmbientHorizonShort = configShortHorizon.intValue();
+        }
+    }
+
     static class SensorData {
         public String type;
         public String name;
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index faf0038..34f915e 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -957,7 +957,9 @@
                     lightSensorRate, initialLightSensorRate, brighteningLightDebounce,
                     darkeningLightDebounce, autoBrightnessResetAmbientLuxAfterWarmUp,
                     ambientBrightnessThresholds, screenBrightnessThresholds, mContext,
-                    mHbmController, mIdleModeBrightnessMapper);
+                    mHbmController, mIdleModeBrightnessMapper,
+                    mDisplayDeviceConfig.getAmbientHorizonShort(),
+                    mDisplayDeviceConfig.getAmbientHorizonLong());
         } else {
             mUseSoftwareAutoBrightnessConfig = false;
         }
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodBindingController.java b/services/core/java/com/android/server/inputmethod/InputMethodBindingController.java
index 3af51f4..db13deb 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodBindingController.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodBindingController.java
@@ -18,8 +18,6 @@
 
 import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
 
-import static com.android.server.inputmethod.InputMethodManagerService.MSG_INITIALIZE_IME;
-
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.PendingIntent;
@@ -311,11 +309,8 @@
                     if (DEBUG) Slog.v(TAG, "Initiating attach with token: " + mCurToken);
                     final InputMethodInfo info = mMethodMap.get(mSelectedMethodId);
                     mSupportsStylusHw = info.supportsStylusHandwriting();
-                    // Dispatch display id for InputMethodService to update context display.
-                    mService.executeOrSendMessage(mCurMethod,
-                            mService.mCaller.obtainMessageIOOO(MSG_INITIALIZE_IME,
-                                    info.getConfigChanges(), mCurMethod, mCurToken,
-                                    mSupportsStylusHw));
+                    mService.executeOrSendInitializeIme(mCurMethod, mCurToken,
+                            info.getConfigChanges(), mSupportsStylusHw);
                     mService.scheduleNotifyImeUidToAudioService(mCurMethodUid);
                     mService.reRequestCurrentClientSessionLocked();
                 }
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index f1e8d0d..6c68011 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -219,38 +219,38 @@
         int FAILURE = -1;
     }
 
-    static final int MSG_SHOW_IM_SUBTYPE_PICKER = 1;
-    static final int MSG_SHOW_IM_SUBTYPE_ENABLER = 2;
-    static final int MSG_SHOW_IM_CONFIG = 3;
+    private static final int MSG_SHOW_IM_SUBTYPE_PICKER = 1;
+    private static final int MSG_SHOW_IM_SUBTYPE_ENABLER = 2;
+    private static final int MSG_SHOW_IM_CONFIG = 3;
 
-    static final int MSG_UNBIND_INPUT = 1000;
-    static final int MSG_BIND_INPUT = 1010;
-    static final int MSG_SHOW_SOFT_INPUT = 1020;
-    static final int MSG_HIDE_SOFT_INPUT = 1030;
-    static final int MSG_HIDE_CURRENT_INPUT_METHOD = 1035;
-    static final int MSG_INITIALIZE_IME = 1040;
-    static final int MSG_CREATE_SESSION = 1050;
-    static final int MSG_REMOVE_IME_SURFACE = 1060;
-    static final int MSG_REMOVE_IME_SURFACE_FROM_WINDOW = 1061;
-    static final int MSG_UPDATE_IME_WINDOW_STATUS = 1070;
-    static final int MSG_START_HANDWRITING = 1100;
+    private static final int MSG_UNBIND_INPUT = 1000;
+    private static final int MSG_BIND_INPUT = 1010;
+    private static final int MSG_SHOW_SOFT_INPUT = 1020;
+    private static final int MSG_HIDE_SOFT_INPUT = 1030;
+    private static final int MSG_HIDE_CURRENT_INPUT_METHOD = 1035;
+    private static final int MSG_INITIALIZE_IME = 1040;
+    private static final int MSG_CREATE_SESSION = 1050;
+    private static final int MSG_REMOVE_IME_SURFACE = 1060;
+    private static final int MSG_REMOVE_IME_SURFACE_FROM_WINDOW = 1061;
+    private static final int MSG_UPDATE_IME_WINDOW_STATUS = 1070;
+    private static final int MSG_START_HANDWRITING = 1100;
 
-    static final int MSG_START_INPUT = 2000;
+    private static final int MSG_START_INPUT = 2000;
 
-    static final int MSG_UNBIND_CLIENT = 3000;
-    static final int MSG_BIND_CLIENT = 3010;
-    static final int MSG_SET_ACTIVE = 3020;
-    static final int MSG_SET_INTERACTIVE = 3030;
-    static final int MSG_REPORT_FULLSCREEN_MODE = 3045;
+    private static final int MSG_UNBIND_CLIENT = 3000;
+    private static final int MSG_BIND_CLIENT = 3010;
+    private static final int MSG_SET_ACTIVE = 3020;
+    private static final int MSG_SET_INTERACTIVE = 3030;
+    private static final int MSG_REPORT_FULLSCREEN_MODE = 3045;
 
-    static final int MSG_HARD_KEYBOARD_SWITCH_CHANGED = 4000;
+    private static final int MSG_HARD_KEYBOARD_SWITCH_CHANGED = 4000;
 
-    static final int MSG_SYSTEM_UNLOCK_USER = 5000;
-    static final int MSG_DISPATCH_ON_INPUT_METHOD_LIST_UPDATED = 5010;
+    private static final int MSG_SYSTEM_UNLOCK_USER = 5000;
+    private static final int MSG_DISPATCH_ON_INPUT_METHOD_LIST_UPDATED = 5010;
 
-    static final int MSG_INLINE_SUGGESTIONS_REQUEST = 6000;
+    private static final int MSG_INLINE_SUGGESTIONS_REQUEST = 6000;
 
-    static final int MSG_NOTIFY_IME_UID_TO_AUDIO_SERVICE = 7000;
+    private static final int MSG_NOTIFY_IME_UID_TO_AUDIO_SERVICE = 7000;
 
     private static final int NOT_A_SUBTYPE_ID = InputMethodUtils.NOT_A_SUBTYPE_ID;
     private static final String TAG_TRY_SUPPRESSING_IME_SWITCHER = "TrySuppressingImeSwitcher";
@@ -278,14 +278,14 @@
 
     final Context mContext;
     final Resources mRes;
-    final Handler mHandler;
+    private final Handler mHandler;
     final InputMethodSettings mSettings;
     final SettingsObserver mSettingsObserver;
     final IWindowManager mIWindowManager;
     final WindowManagerInternal mWindowManagerInternal;
     final PackageManagerInternal mPackageManagerInternal;
     final InputManagerInternal mInputManagerInternal;
-    final HandlerCaller mCaller;
+    private final HandlerCaller mCaller;
     final boolean mHasFeature;
     private final ArrayMap<String, List<InputMethodSubtype>> mAdditionalSubtypeMap =
             new ArrayMap<>();
@@ -1806,10 +1806,10 @@
                 mShowOngoingImeSwitcherForPhones = mRes.getBoolean(
                         com.android.internal.R.bool.show_ongoing_ime_switcher);
                 if (mShowOngoingImeSwitcherForPhones) {
-                    final InputMethodMenuController.HardKeyboardListener hardKeyboardListener =
-                            mMenuController.getHardKeyboardListener();
-                    mWindowManagerInternal.setOnHardKeyboardStatusChangeListener(
-                            hardKeyboardListener);
+                    mWindowManagerInternal.setOnHardKeyboardStatusChangeListener(available -> {
+                        mHandler.obtainMessage(MSG_HARD_KEYBOARD_SWITCH_CHANGED, available ? 1 : 0)
+                                .sendToTarget();
+                    });
                 }
 
                 mMyPackageMonitor.register(mContext, null, UserHandle.ALL, true);
@@ -2241,7 +2241,7 @@
         }
     }
 
-    void executeOrSendMessage(IInterface target, Message msg) {
+    private void executeOrSendMessage(IInterface target, Message msg) {
          if (target.asBinder() instanceof Binder) {
              mCaller.sendMessage(msg);
          } else {
@@ -2527,6 +2527,13 @@
     }
 
     @AnyThread
+    void executeOrSendInitializeIme(@NonNull IInputMethod inputMethod, @NonNull IBinder token,
+            @android.content.pm.ActivityInfo.Config int configChanges, boolean supportStylusHw) {
+        executeOrSendMessage(inputMethod, mCaller.obtainMessageIOOO(MSG_INITIALIZE_IME,
+                configChanges, inputMethod, token, supportStylusHw));
+    }
+
+    @AnyThread
     void scheduleNotifyImeUidToAudioService(int uid) {
         mCaller.removeMessages(MSG_NOTIFY_IME_UID_TO_AUDIO_SERVICE);
         mCaller.obtainMessageI(MSG_NOTIFY_IME_UID_TO_AUDIO_SERVICE, uid).sendToTarget();
@@ -4416,9 +4423,7 @@
 
             // --------------------------------------------------------------
             case MSG_HARD_KEYBOARD_SWITCH_CHANGED:
-                final InputMethodMenuController.HardKeyboardListener hardKeyboardListener =
-                        mMenuController.getHardKeyboardListener();
-                hardKeyboardListener.handleHardKeyboardStatusChange(msg.arg1 == 1);
+                mMenuController.handleHardKeyboardStatusChange(msg.arg1 == 1);
                 return true;
             case MSG_SYSTEM_UNLOCK_USER: {
                 final int userId = msg.arg1;
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodMenuController.java b/services/core/java/com/android/server/inputmethod/InputMethodMenuController.java
index 132be7d..fcb1be0 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodMenuController.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodMenuController.java
@@ -18,7 +18,6 @@
 
 import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
 import static com.android.server.inputmethod.InputMethodManagerService.DEBUG;
-import static com.android.server.inputmethod.InputMethodManagerService.MSG_HARD_KEYBOARD_SWITCH_CHANGED;
 import static com.android.server.inputmethod.InputMethodUtils.NOT_A_SUBTYPE_ID;
 
 import android.app.ActivityThread;
@@ -28,7 +27,6 @@
 import android.content.DialogInterface;
 import android.content.res.TypedArray;
 import android.graphics.drawable.Drawable;
-import android.os.Handler;
 import android.os.IBinder;
 import android.text.TextUtils;
 import android.util.ArrayMap;
@@ -62,10 +60,8 @@
     private final InputMethodManagerService mService;
     private final InputMethodUtils.InputMethodSettings mSettings;
     private final InputMethodSubtypeSwitchingController mSwitchingController;
-    private final Handler mHandler;
     private final ArrayMap<String, InputMethodInfo> mMethodMap;
     private final KeyguardManager mKeyguardManager;
-    private final HardKeyboardListener mHardKeyboardListener;
     private final WindowManagerInternal mWindowManagerInternal;
 
     private Context mSettingsContext;
@@ -83,10 +79,8 @@
         mService = service;
         mSettings = mService.mSettings;
         mSwitchingController = mService.mSwitchingController;
-        mHandler = mService.mHandler;
         mMethodMap = mService.mMethodMap;
         mKeyguardManager = mService.mKeyguardManager;
-        mHardKeyboardListener = new HardKeyboardListener();
         mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
     }
 
@@ -271,10 +265,6 @@
         }
     }
 
-    HardKeyboardListener getHardKeyboardListener() {
-        return mHardKeyboardListener;
-    }
-
     AlertDialog getSwitchingDialogLocked() {
         return mSwitchingDialog;
     }
@@ -290,24 +280,16 @@
         return mSwitchingDialog.isShowing();
     }
 
-    class HardKeyboardListener implements WindowManagerInternal.OnHardKeyboardStatusChangeListener {
-        @Override
-        public void onHardKeyboardStatusChange(boolean available) {
-            mHandler.sendMessage(mHandler.obtainMessage(MSG_HARD_KEYBOARD_SWITCH_CHANGED,
-                    available ? 1 : 0));
+    void handleHardKeyboardStatusChange(boolean available) {
+        if (DEBUG) {
+            Slog.w(TAG, "HardKeyboardStatusChanged: available=" + available);
         }
-
-        public void handleHardKeyboardStatusChange(boolean available) {
-            if (DEBUG) {
-                Slog.w(TAG, "HardKeyboardStatusChanged: available=" + available);
-            }
-            synchronized (ImfLock.class) {
-                if (mSwitchingDialog != null && mSwitchingDialogTitleView != null
-                        && mSwitchingDialog.isShowing()) {
-                    mSwitchingDialogTitleView.findViewById(
-                            com.android.internal.R.id.hard_keyboard_section).setVisibility(
-                            available ? View.VISIBLE : View.GONE);
-                }
+        synchronized (ImfLock.class) {
+            if (mSwitchingDialog != null && mSwitchingDialogTitleView != null
+                    && mSwitchingDialog.isShowing()) {
+                mSwitchingDialogTitleView.findViewById(
+                        com.android.internal.R.id.hard_keyboard_section).setVisibility(
+                        available ? View.VISIBLE : View.GONE);
             }
         }
     }
diff --git a/services/core/java/com/android/server/pm/ApexManager.java b/services/core/java/com/android/server/pm/ApexManager.java
index a1c97a8..c285e27 100644
--- a/services/core/java/com/android/server/pm/ApexManager.java
+++ b/services/core/java/com/android/server/pm/ApexManager.java
@@ -413,11 +413,9 @@
             throws PackageManagerException;
 
     /**
-     * Get a list of apex system services implemented in an apex.
-     *
-     * <p>The list is sorted by initOrder for consistency.
+     * Get a map of system services defined in an apex mapped to the jar files they reside in.
      */
-    public abstract List<ApexSystemServiceInfo> getApexSystemServices();
+    public abstract Map<String, String> getApexSystemServices();
 
     /**
      * Dumps various state information to the provided {@link PrintWriter} object.
@@ -450,7 +448,7 @@
          * Map of all apex system services to the jar files they are contained in.
          */
         @GuardedBy("mLock")
-        private List<ApexSystemServiceInfo> mApexSystemServices = new ArrayList<>();
+        private Map<String, String> mApexSystemServices = new ArrayMap<>();
 
         /**
          * Contains the list of {@code packageName}s of apks-in-apex for given
@@ -606,19 +604,14 @@
                         }
 
                         String name = service.getName();
-                        for (ApexSystemServiceInfo info : mApexSystemServices) {
-                            if (info.getName().equals(name)) {
-                                throw new IllegalStateException(String.format(
-                                        "Duplicate apex-system-service %s from %s, %s",
-                                        name, info.mJarPath, service.getJarPath()));
-                            }
+                        if (mApexSystemServices.containsKey(name)) {
+                            throw new IllegalStateException(String.format(
+                                    "Duplicate apex-system-service %s from %s, %s",
+                                    name, mApexSystemServices.get(name), service.getJarPath()));
                         }
 
-                        ApexSystemServiceInfo info = new ApexSystemServiceInfo(
-                                service.getName(), service.getJarPath(), service.getInitOrder());
-                        mApexSystemServices.add(info);
+                        mApexSystemServices.put(name, service.getJarPath());
                     }
-                    Collections.sort(mApexSystemServices);
                     mPackageNameToApexModuleName.put(packageInfo.packageName, ai.moduleName);
                     if (ai.isActive) {
                         if (activePackagesSet.contains(packageInfo.packageName)) {
@@ -1139,7 +1132,7 @@
         }
 
         @Override
-        public List<ApexSystemServiceInfo> getApexSystemServices() {
+        public Map<String, String> getApexSystemServices() {
             synchronized (mLock) {
                 Preconditions.checkState(mApexSystemServices != null,
                         "APEX packages have not been scanned");
@@ -1425,10 +1418,10 @@
         }
 
         @Override
-        public List<ApexSystemServiceInfo> getApexSystemServices() {
+        public Map<String, String> getApexSystemServices() {
             // TODO(satayev): we can't really support flattened apex use case, and need to migrate
             // the manifest entries into system's manifest asap.
-            return Collections.emptyList();
+            return Collections.emptyMap();
         }
 
         @Override
diff --git a/services/core/java/com/android/server/pm/ApexSystemServiceInfo.java b/services/core/java/com/android/server/pm/ApexSystemServiceInfo.java
deleted file mode 100644
index f75ba6d..0000000
--- a/services/core/java/com/android/server/pm/ApexSystemServiceInfo.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * 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.pm;
-
-import android.annotation.Nullable;
-
-/**
- * A helper class that contains information about apex-system-service to be used within system
- * server process.
- */
-public final class ApexSystemServiceInfo implements Comparable<ApexSystemServiceInfo> {
-
-    final String mName;
-    @Nullable
-    final String mJarPath;
-    final int mInitOrder;
-
-    public ApexSystemServiceInfo(String name, String jarPath, int initOrder) {
-        this.mName = name;
-        this.mJarPath = jarPath;
-        this.mInitOrder = initOrder;
-    }
-
-    public String getName() {
-        return mName;
-    }
-
-    public String getJarPath() {
-        return mJarPath;
-    }
-
-    public int getInitOrder() {
-        return mInitOrder;
-    }
-
-    @Override
-    public int compareTo(ApexSystemServiceInfo other) {
-        if (mInitOrder == other.mInitOrder) {
-            return mName.compareTo(other.mName);
-        }
-        // higher initOrder values take precedence
-        return -Integer.compare(mInitOrder, other.mInitOrder);
-    }
-}
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index 4225f21..44818a8 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -399,10 +399,11 @@
         if (recentsAnimationInputConsumer != null && focus != null) {
             final RecentsAnimationController recentsAnimationController =
                     mService.getRecentsAnimationController();
+            // Apply recents input consumer when the focusing window is in recents animation.
             final boolean shouldApplyRecentsInputConsumer = (recentsAnimationController != null
                     && recentsAnimationController.shouldApplyInputConsumer(focus.mActivityRecord))
                     // Shell transitions doesn't use RecentsAnimationController
-                    || getWeak(mActiveRecentsActivity) != null;
+                    || getWeak(mActiveRecentsActivity) != null && focus.inTransition();
             if (shouldApplyRecentsInputConsumer) {
                 requestFocus(recentsAnimationInputConsumer.mWindowHandle.token,
                         recentsAnimationInputConsumer.mName);
diff --git a/services/core/xsd/display-device-config/display-device-config.xsd b/services/core/xsd/display-device-config/display-device-config.xsd
index 2f4dd57..baf2ede 100644
--- a/services/core/xsd/display-device-config/display-device-config.xsd
+++ b/services/core/xsd/display-device-config/display-device-config.xsd
@@ -58,6 +58,15 @@
                 <xs:element type="sensorDetails" name="proxSensor">
                     <xs:annotation name="final"/>
                 </xs:element>
+
+                <!-- Length of the ambient light horizon used to calculate the long & short term
+                estimates of ambient light in milliseconds.-->
+                <xs:element type="xs:nonNegativeInteger" name="ambientLightHorizonLong">
+                    <xs:annotation name="final"/>
+                </xs:element>
+                <xs:element type="xs:nonNegativeInteger" name="ambientLightHorizonShort">
+                    <xs:annotation name="final"/>
+                </xs:element>
             </xs:sequence>
         </xs:complexType>
     </xs:element>
diff --git a/services/core/xsd/display-device-config/schema/current.txt b/services/core/xsd/display-device-config/schema/current.txt
index 5b2b87c..6f97431 100644
--- a/services/core/xsd/display-device-config/schema/current.txt
+++ b/services/core/xsd/display-device-config/schema/current.txt
@@ -18,6 +18,8 @@
 
   public class DisplayConfiguration {
     ctor public DisplayConfiguration();
+    method public final java.math.BigInteger getAmbientLightHorizonLong();
+    method public final java.math.BigInteger getAmbientLightHorizonShort();
     method @Nullable public final com.android.server.display.config.DensityMap getDensityMap();
     method public com.android.server.display.config.HighBrightnessMode getHighBrightnessMode();
     method public final com.android.server.display.config.SensorDetails getLightSensor();
@@ -29,6 +31,8 @@
     method public final java.math.BigDecimal getScreenBrightnessRampFastIncrease();
     method public final java.math.BigDecimal getScreenBrightnessRampSlowDecrease();
     method public final java.math.BigDecimal getScreenBrightnessRampSlowIncrease();
+    method public final void setAmbientLightHorizonLong(java.math.BigInteger);
+    method public final void setAmbientLightHorizonShort(java.math.BigInteger);
     method public final void setDensityMap(@Nullable com.android.server.display.config.DensityMap);
     method public void setHighBrightnessMode(com.android.server.display.config.HighBrightnessMode);
     method public final void setLightSensor(com.android.server.display.config.SensorDetails);
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java b/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java
index 55ab8c3..ebe9f93 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java
@@ -17,16 +17,20 @@
 
 import android.annotation.NonNull;
 import android.annotation.UserIdInt;
+import android.app.admin.DevicePolicyDrawableResource;
 import android.app.admin.DevicePolicySafetyChecker;
 import android.app.admin.FullyManagedDeviceProvisioningParams;
 import android.app.admin.IDevicePolicyManager;
 import android.app.admin.ManagedProfileProvisioningParams;
+import android.app.admin.ParcelableResource;
 import android.content.ComponentName;
 import android.os.UserHandle;
 import android.util.Slog;
 
 import com.android.server.SystemService;
 
+import java.util.List;
+
 /**
  * Defines the required interface for IDevicePolicyManager implemenation.
  *
@@ -161,4 +165,16 @@
     public boolean isKeyPairGrantedToWifiAuth(String callerPackage, String alias) {
         return false;
     }
+
+    @Override
+    public void setDrawables(@NonNull List<DevicePolicyDrawableResource> drawables){}
+
+    @Override
+    public void resetDrawables(@NonNull int[] drawableIds){}
+
+    @Override
+    public ParcelableResource getDrawable(
+            int drawableId, int drawableStyle, int drawableSource) {
+        return null;
+    }
 }
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DeviceManagementResourcesProvider.java b/services/devicepolicy/java/com/android/server/devicepolicy/DeviceManagementResourcesProvider.java
new file mode 100644
index 0000000..53422940
--- /dev/null
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DeviceManagementResourcesProvider.java
@@ -0,0 +1,417 @@
+/*
+ * 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.devicepolicy;
+
+import static android.app.admin.DevicePolicyResources.Drawable.Source.UPDATABLE_DRAWABLE_SOURCES;
+import static android.app.admin.DevicePolicyResources.Drawable.Style;
+import static android.app.admin.DevicePolicyResources.Drawable.Style.UPDATABLE_DRAWABLE_STYLES;
+import static android.app.admin.DevicePolicyResources.Drawable.UPDATABLE_DRAWABLE_IDS;
+
+import static java.util.Objects.requireNonNull;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.admin.DevicePolicyDrawableResource;
+import android.app.admin.DevicePolicyResources;
+import android.app.admin.ParcelableResource;
+import android.os.Environment;
+import android.util.AtomicFile;
+import android.util.Log;
+import android.util.TypedXmlPullParser;
+import android.util.TypedXmlSerializer;
+import android.util.Xml;
+
+import libcore.io.IoUtils;
+
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * A helper class for {@link DevicePolicyManagerService} to store/retrieve updated device
+ * management resources.
+ */
+class DeviceManagementResourcesProvider {
+    private static final String TAG = "DevicePolicyManagerService";
+
+    private static final String UPDATED_RESOURCES_XML = "updated_resources.xml";
+    private static final String TAG_ROOT = "root";
+    private static final String TAG_DRAWABLE_STYLE_ENTRY = "drawable-style-entry";
+    private static final String TAG_DRAWABLE_SOURCE_ENTRY = "drawable-source-entry";
+    private static final String ATTR_DRAWABLE_STYLE_SIZE = "drawable-style-size";
+    private static final String ATTR_DRAWABLE_SOURCE_SIZE = "drawable-source-size";
+    private static final String ATTR_DRAWABLE_STYLE = "drawable-style";
+    private static final String ATTR_DRAWABLE_SOURCE = "drawable-source";
+    private static final String ATTR_DRAWABLE_ID = "drawable-id";
+
+
+    private final Map<Integer, Map<Integer, ParcelableResource>>
+            mUpdatedDrawablesForStyle = new HashMap<>();
+
+    private final Map<Integer, Map<Integer, ParcelableResource>>
+            mUpdatedDrawablesForSource = new HashMap<>();
+
+    private final Object mLock = new Object();
+    private final Injector mInjector;
+
+    DeviceManagementResourcesProvider() {
+        this(new Injector());
+    }
+
+    DeviceManagementResourcesProvider(Injector injector) {
+        mInjector = requireNonNull(injector);
+    }
+
+    /**
+     * Returns {@code false} if no resources were updated.
+     */
+    boolean updateDrawables(@NonNull List<DevicePolicyDrawableResource> drawables) {
+        boolean updated = false;
+        for (int i = 0; i < drawables.size(); i++) {
+            int drawableId = drawables.get(i).getDrawableId();
+            int drawableStyle = drawables.get(i).getDrawableStyle();
+            int drawableSource = drawables.get(i).getDrawableSource();
+            ParcelableResource resource = drawables.get(i).getResource();
+
+            Objects.requireNonNull(resource, "ParcelableResource must be provided.");
+
+            if (drawableSource == DevicePolicyResources.Drawable.Source.UNDEFINED) {
+                updated |= updateDrawable(drawableId, drawableStyle, resource);
+            } else {
+                updated |= updateDrawableForSource(drawableId, drawableSource, resource);
+            }
+        }
+        if (!updated) {
+            return false;
+        }
+        synchronized (mLock) {
+            write();
+            return true;
+        }
+    }
+
+    private boolean updateDrawable(
+            int drawableId, int drawableStyle, ParcelableResource updatableResource) {
+        if (!UPDATABLE_DRAWABLE_IDS.contains(drawableId)) {
+            throw new IllegalArgumentException(
+                    "Can't update drawable resource, invalid drawable " + "id " + drawableId);
+        }
+        if (!UPDATABLE_DRAWABLE_STYLES.contains(drawableStyle)) {
+            throw new IllegalArgumentException(
+                    "Can't update drawable resource, invalid style id " + drawableStyle);
+        }
+        synchronized (mLock) {
+            if (!mUpdatedDrawablesForStyle.containsKey(drawableId)) {
+                mUpdatedDrawablesForStyle.put(drawableId, new HashMap<>());
+            }
+            ParcelableResource current = mUpdatedDrawablesForStyle.get(drawableId).get(
+                    drawableStyle);
+            if (updatableResource.equals(current)) {
+                return false;
+            }
+            mUpdatedDrawablesForStyle.get(drawableId).put(drawableStyle, updatableResource);
+            return true;
+        }
+    }
+
+    // TODO(b/214576716): change this to respect style
+    private boolean updateDrawableForSource(
+            int drawableId, int drawableSource, ParcelableResource updatableResource) {
+        if (!UPDATABLE_DRAWABLE_IDS.contains(drawableId)) {
+            throw new IllegalArgumentException("Can't update drawable resource, invalid drawable "
+                    + "id " + drawableId);
+        }
+        if (!UPDATABLE_DRAWABLE_SOURCES.contains(drawableSource)) {
+            throw new IllegalArgumentException("Can't update drawable resource, invalid source id "
+                    + drawableSource);
+        }
+        synchronized (mLock) {
+            if (!mUpdatedDrawablesForSource.containsKey(drawableId)) {
+                mUpdatedDrawablesForSource.put(drawableId, new HashMap<>());
+            }
+            ParcelableResource current = mUpdatedDrawablesForSource.get(drawableId).get(
+                    drawableSource);
+            if (updatableResource.equals(current)) {
+                return false;
+            }
+            mUpdatedDrawablesForSource.get(drawableId).put(drawableSource, updatableResource);
+            return true;
+        }
+    }
+
+    /**
+     * Returns {@code false} if no resources were removed.
+     */
+    boolean removeDrawables(@NonNull int[] drawableIds) {
+        synchronized (mLock) {
+            boolean removed = false;
+            for (int i = 0; i < drawableIds.length; i++) {
+                int drawableId = drawableIds[i];
+                removed |= mUpdatedDrawablesForStyle.remove(drawableId) != null
+                        || mUpdatedDrawablesForSource.remove(drawableId) != null;
+            }
+            if (!removed) {
+                return false;
+            }
+            write();
+            return true;
+        }
+    }
+
+    @Nullable
+    ParcelableResource getDrawable(
+            int drawableId, int drawableStyle, int drawableSource) {
+        if (!UPDATABLE_DRAWABLE_IDS.contains(drawableId)) {
+            Log.e(TAG, "Can't get updated drawable resource, invalid drawable id "
+                    + drawableId);
+            return null;
+        }
+        if (!UPDATABLE_DRAWABLE_STYLES.contains(drawableStyle)) {
+            Log.e(TAG, "Can't get updated drawable resource, invalid style id "
+                    + drawableStyle);
+            return null;
+        }
+        if (!UPDATABLE_DRAWABLE_SOURCES.contains(drawableSource)) {
+            Log.e(TAG, "Can't get updated drawable resource, invalid source id "
+                    + drawableSource);
+            return null;
+        }
+        if (mUpdatedDrawablesForSource.containsKey(drawableId)
+                && mUpdatedDrawablesForSource.get(drawableId).containsKey(drawableSource)) {
+            return mUpdatedDrawablesForSource.get(drawableId).get(drawableSource);
+        }
+        if (!mUpdatedDrawablesForStyle.containsKey(drawableId)) {
+            Log.d(TAG, "No updated drawable found for drawable id " + drawableId);
+            return null;
+        }
+        if (mUpdatedDrawablesForStyle.get(drawableId).containsKey(drawableStyle)) {
+            return mUpdatedDrawablesForStyle.get(drawableId).get(drawableStyle);
+        }
+
+        if (mUpdatedDrawablesForStyle.get(drawableId).containsKey(Style.DEFAULT)) {
+            return mUpdatedDrawablesForStyle.get(drawableId).get(Style.DEFAULT);
+        }
+        Log.d(TAG, "No updated drawable found for drawable id " + drawableId);
+        return null;
+    }
+
+    private void write() {
+        Log.d(TAG, "Writing updated resources to file.");
+        new ResourcesReaderWriter().writeToFileLocked();
+    }
+
+    void load() {
+        synchronized (mLock) {
+            new ResourcesReaderWriter().readFromFileLocked();
+        }
+    }
+
+    private File getResourcesFile() {
+        return new File(mInjector.environmentGetDataSystemDirectory(), UPDATED_RESOURCES_XML);
+    }
+
+    private class ResourcesReaderWriter {
+        private final File mFile;
+        private ResourcesReaderWriter() {
+            mFile = getResourcesFile();
+        }
+
+        void writeToFileLocked() {
+            Log.d(TAG, "Writing to " + mFile);
+
+            AtomicFile f = new AtomicFile(mFile);
+            FileOutputStream outputStream = null;
+            try {
+                outputStream = f.startWrite();
+                TypedXmlSerializer out = Xml.resolveSerializer(outputStream);
+
+                // Root tag
+                out.startDocument(null, true);
+                out.startTag(null, TAG_ROOT);
+
+                // Actual content
+                writeInner(out);
+
+                // Close root
+                out.endTag(null, TAG_ROOT);
+                out.endDocument();
+                out.flush();
+
+                // Commit the content.
+                f.finishWrite(outputStream);
+                outputStream = null;
+
+            } catch (IOException e) {
+                Log.e(TAG, "Exception when writing", e);
+                if (outputStream != null) {
+                    f.failWrite(outputStream);
+                }
+            }
+        }
+
+        void readFromFileLocked() {
+            if (!mFile.exists()) {
+                Log.d(TAG, "" + mFile + " doesn't exist");
+                return;
+            }
+
+            Log.d(TAG, "Reading from " + mFile);
+            AtomicFile f = new AtomicFile(mFile);
+            InputStream input = null;
+            try {
+                input = f.openRead();
+                TypedXmlPullParser parser = Xml.resolvePullParser(input);
+
+                int type;
+                int depth = 0;
+                while ((type = parser.next()) != TypedXmlPullParser.END_DOCUMENT) {
+                    switch (type) {
+                        case TypedXmlPullParser.START_TAG:
+                            depth++;
+                            break;
+                        case TypedXmlPullParser.END_TAG:
+                            depth--;
+                            // fallthrough
+                        default:
+                            continue;
+                    }
+                    // Check the root tag
+                    String tag = parser.getName();
+                    if (depth == 1) {
+                        if (!TAG_ROOT.equals(tag)) {
+                            Log.e(TAG, "Invalid root tag: " + tag);
+                            return;
+                        }
+                        continue;
+                    }
+                    // readInner() will only see START_TAG at depth >= 2.
+                    if (!readInner(parser, depth, tag)) {
+                        return; // Error
+                    }
+                }
+            } catch (XmlPullParserException | IOException e) {
+                Log.e(TAG, "Error parsing resources file", e);
+            } finally {
+                IoUtils.closeQuietly(input);
+            }
+        }
+
+        void writeInner(TypedXmlSerializer out) throws IOException {
+            if (mUpdatedDrawablesForStyle != null && !mUpdatedDrawablesForStyle.isEmpty()) {
+                for (Map.Entry<Integer, Map<Integer, ParcelableResource>> drawableEntry
+                        : mUpdatedDrawablesForStyle.entrySet()) {
+                    out.startTag(/* namespace= */ null, TAG_DRAWABLE_STYLE_ENTRY);
+                    out.attributeInt(
+                            /* namespace= */ null, ATTR_DRAWABLE_ID, drawableEntry.getKey());
+                    out.attributeInt(
+                            /* namespace= */ null,
+                            ATTR_DRAWABLE_STYLE_SIZE,
+                            drawableEntry.getValue().size());
+                    int counter = 0;
+                    for (Map.Entry<Integer, ParcelableResource> styleEntry
+                            : drawableEntry.getValue().entrySet()) {
+                        out.attributeInt(
+                                /* namespace= */ null,
+                                ATTR_DRAWABLE_STYLE + (counter++),
+                                styleEntry.getKey());
+                        styleEntry.getValue().writeToXmlFile(out);
+                    }
+                    out.endTag(/* namespace= */ null, TAG_DRAWABLE_STYLE_ENTRY);
+                }
+            }
+            if (mUpdatedDrawablesForSource != null && !mUpdatedDrawablesForSource.isEmpty()) {
+                for (Map.Entry<Integer, Map<Integer, ParcelableResource>> drawableEntry
+                        : mUpdatedDrawablesForSource.entrySet()) {
+                    out.startTag(/* namespace= */ null, TAG_DRAWABLE_SOURCE_ENTRY);
+                    out.attributeInt(
+                            /* namespace= */ null, ATTR_DRAWABLE_ID, drawableEntry.getKey());
+                    out.attributeInt(
+                            /* namespace= */ null,
+                            ATTR_DRAWABLE_SOURCE_SIZE,
+                            drawableEntry.getValue().size());
+                    int counter = 0;
+                    for (Map.Entry<Integer, ParcelableResource> sourceEntry
+                            : drawableEntry.getValue().entrySet()) {
+                        out.attributeInt(
+                                /* namespace= */ null,
+                                ATTR_DRAWABLE_SOURCE + (counter++),
+                                sourceEntry.getKey());
+                        sourceEntry.getValue().writeToXmlFile(out);
+                    }
+                    out.endTag(/* namespace= */ null, TAG_DRAWABLE_SOURCE_ENTRY);
+                }
+            }
+        }
+
+        private boolean readInner(
+                TypedXmlPullParser parser, int depth, String tag)
+                throws XmlPullParserException, IOException {
+            if (depth > 2) {
+                return true; // Ignore
+            }
+            switch (tag) {
+                case TAG_DRAWABLE_STYLE_ENTRY:
+                    int drawableId = parser.getAttributeInt(
+                            /* namespace= */ null, ATTR_DRAWABLE_ID);
+                    mUpdatedDrawablesForStyle.put(
+                            drawableId,
+                            new HashMap<>());
+                    int size = parser.getAttributeInt(
+                            /* namespace= */ null, ATTR_DRAWABLE_STYLE_SIZE);
+                    for (int i = 0; i < size; i++) {
+                        int style = parser.getAttributeInt(
+                                /* namespace= */ null, ATTR_DRAWABLE_STYLE + i);
+                        mUpdatedDrawablesForStyle.get(drawableId).put(
+                                style,
+                                ParcelableResource.createFromXml(parser));
+                    }
+                    break;
+                case TAG_DRAWABLE_SOURCE_ENTRY:
+                    drawableId = parser.getAttributeInt(
+                            /* namespace= */ null, ATTR_DRAWABLE_ID);
+                    mUpdatedDrawablesForSource.put(drawableId, new HashMap<>());
+                    size = parser.getAttributeInt(
+                            /* namespace= */ null, ATTR_DRAWABLE_SOURCE_SIZE);
+                    for (int i = 0; i < size; i++) {
+                        int source = parser.getAttributeInt(
+                                /* namespace= */ null, ATTR_DRAWABLE_SOURCE + i);
+                        mUpdatedDrawablesForSource.get(drawableId).put(
+                                source,
+                                ParcelableResource.createFromXml(parser));
+                    }
+                    break;
+                default:
+                    Log.e(TAG, "Unexpected tag: " + tag);
+                    return false;
+            }
+            return true;
+        }
+    }
+
+    public static class Injector {
+        File environmentGetDataSystemDirectory() {
+            return Environment.getDataSystemDirectory();
+        }
+    }
+}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 6caf731..0595b73 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -26,6 +26,7 @@
 import static android.app.admin.DeviceAdminReceiver.ACTION_COMPLIANCE_ACKNOWLEDGEMENT_REQUIRED;
 import static android.app.admin.DeviceAdminReceiver.EXTRA_TRANSFER_OWNERSHIP_ADMIN_EXTRAS_BUNDLE;
 import static android.app.admin.DevicePolicyManager.ACTION_CHECK_POLICY_COMPLIANCE;
+import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_RESOURCE_UPDATED;
 import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE;
 import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE;
 import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_USER;
@@ -56,6 +57,8 @@
 import static android.app.admin.DevicePolicyManager.DELEGATION_PERMISSION_GRANT;
 import static android.app.admin.DevicePolicyManager.DELEGATION_SECURITY_LOGGING;
 import static android.app.admin.DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE_PER_USER;
+import static android.app.admin.DevicePolicyManager.EXTRA_RESOURCE_ID;
+import static android.app.admin.DevicePolicyManager.EXTRA_RESOURCE_TYPE_DRAWABLE;
 import static android.app.admin.DevicePolicyManager.ID_TYPE_BASE_INFO;
 import static android.app.admin.DevicePolicyManager.ID_TYPE_IMEI;
 import static android.app.admin.DevicePolicyManager.ID_TYPE_INDIVIDUAL_ATTESTATION;
@@ -161,6 +164,7 @@
 import android.app.admin.DeviceAdminInfo;
 import android.app.admin.DeviceAdminReceiver;
 import android.app.admin.DevicePolicyCache;
+import android.app.admin.DevicePolicyDrawableResource;
 import android.app.admin.DevicePolicyEventLogger;
 import android.app.admin.DevicePolicyManager;
 import android.app.admin.DevicePolicyManager.DeviceOwnerType;
@@ -177,6 +181,7 @@
 import android.app.admin.ManagedProfileProvisioningParams;
 import android.app.admin.NetworkEvent;
 import android.app.admin.ParcelableGranteeMap;
+import android.app.admin.ParcelableResource;
 import android.app.admin.PasswordMetrics;
 import android.app.admin.PasswordPolicy;
 import android.app.admin.SecurityLog;
@@ -716,6 +721,8 @@
     // Guarded by mHandler
     private @UserIdInt int mNetworkLoggingNotificationUserId = UserHandle.USER_NULL;
 
+    private final DeviceManagementResourcesProvider mDeviceManagementResourcesProvider;
+
     private static final boolean ENABLE_LOCK_GUARD = true;
 
     /**
@@ -1740,6 +1747,10 @@
         void setDevicePolicySafetyChecker(DevicePolicySafetyChecker safetyChecker) {
             mSafetyChecker = safetyChecker;
         }
+
+        DeviceManagementResourcesProvider getDeviceManagementResourcesProvider() {
+            return new DeviceManagementResourcesProvider();
+        }
     }
 
     /**
@@ -1792,6 +1803,8 @@
         mTransferOwnershipMetadataManager = mInjector.newTransferOwnershipMetadataManager();
         mBugreportCollectionManager = new RemoteBugreportManager(this, mInjector);
 
+        mDeviceManagementResourcesProvider = mInjector.getDeviceManagementResourcesProvider();
+
         // "Lite" interface is available even when the device doesn't have the feature
         LocalServices.addService(DevicePolicyManagerLiteInternal.class, mLocalService);
         if (!mHasFeature) {
@@ -1838,6 +1851,8 @@
         loadOwners();
 
         performPolicyVersionUpgrade();
+
+        mDeviceManagementResourcesProvider.load();
     }
 
     /**
@@ -17956,4 +17971,54 @@
                         && mInjector.getUsbManager().getUsbHalVersion() >= UsbManager.USB_HAL_V1_3
         );
     }
+
+    @Override
+    public void setDrawables(@NonNull List<DevicePolicyDrawableResource> drawables) {
+        Preconditions.checkCallAuthorization(hasCallingOrSelfPermission(
+                android.Manifest.permission.UPDATE_DEVICE_MANAGEMENT_RESOURCES));
+
+        Objects.requireNonNull(drawables, "drawables must be provided.");
+
+        mInjector.binderWithCleanCallingIdentity(() -> {
+            if (mDeviceManagementResourcesProvider.updateDrawables(drawables)) {
+                sendDrawableUpdatedBroadcast(
+                        drawables.stream().mapToInt(d -> d.getDrawableId()).toArray());
+            }
+        });
+    }
+
+    @Override
+    public void resetDrawables(@NonNull int[] drawableIds) {
+        Preconditions.checkCallAuthorization(hasCallingOrSelfPermission(
+                android.Manifest.permission.UPDATE_DEVICE_MANAGEMENT_RESOURCES));
+
+        Objects.requireNonNull(drawableIds, "drawableIds must be provided.");
+
+        mInjector.binderWithCleanCallingIdentity(() -> {
+            if (mDeviceManagementResourcesProvider.removeDrawables(drawableIds)) {
+                sendDrawableUpdatedBroadcast(drawableIds);
+            }
+        });
+    }
+
+    @Override
+    public ParcelableResource getDrawable(int drawableId, int drawableStyle, int drawableSource) {
+        return mInjector.binderWithCleanCallingIdentity(() ->
+                mDeviceManagementResourcesProvider.getDrawable(
+                        drawableId, drawableStyle, drawableSource));
+    }
+
+    private void sendDrawableUpdatedBroadcast(int[] drawableIds) {
+        final Intent intent = new Intent(ACTION_DEVICE_POLICY_RESOURCE_UPDATED);
+        intent.putExtra(EXTRA_RESOURCE_ID, drawableIds);
+        intent.putExtra(EXTRA_RESOURCE_TYPE_DRAWABLE, /* value= */ true);
+        intent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+        intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+
+        List<UserInfo> users = mUserManager.getAliveUsers();
+        for (int i = 0; i < users.size(); i++) {
+            UserHandle user = users.get(i).getUserHandle();
+            mContext.sendBroadcastAsUser(intent, user);
+        }
+    }
 }
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index ee8288e..c767f4d 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -152,7 +152,6 @@
 import com.android.server.os.SchedulingPolicyService;
 import com.android.server.people.PeopleService;
 import com.android.server.pm.ApexManager;
-import com.android.server.pm.ApexSystemServiceInfo;
 import com.android.server.pm.CrossProfileAppsService;
 import com.android.server.pm.DataLoaderManagerService;
 import com.android.server.pm.DynamicCodeLoggingService;
@@ -221,8 +220,8 @@
 import java.util.Arrays;
 import java.util.Date;
 import java.util.LinkedList;
-import java.util.List;
 import java.util.Locale;
+import java.util.Map;
 import java.util.Timer;
 import java.util.TreeSet;
 import java.util.concurrent.CountDownLatch;
@@ -261,10 +260,6 @@
             "com.android.server.companion.virtual.VirtualDeviceManagerService";
     private static final String STATS_COMPANION_APEX_PATH =
             "/apex/com.android.os.statsd/javalib/service-statsd.jar";
-    private static final String SCHEDULING_APEX_PATH =
-            "/apex/com.android.scheduling/javalib/service-scheduling.jar";
-    private static final String REBOOT_READINESS_LIFECYCLE_CLASS =
-            "com.android.server.scheduling.RebootReadinessManagerService$Lifecycle";
     private static final String CONNECTIVITY_SERVICE_APEX_PATH =
             "/apex/com.android.tethering/javalib/service-connectivity.jar";
     private static final String STATS_COMPANION_LIFECYCLE_CLASS =
@@ -1460,7 +1455,7 @@
             // TelecomLoader hooks into classes with defined HFP logic,
             // so check for either telephony or microphone.
             if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_MICROPHONE) ||
-                    mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+                mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
                 t.traceBegin("StartTelecomLoaderService");
                 mSystemServiceManager.startService(TelecomLoaderService.class);
                 t.traceEnd();
@@ -1468,7 +1463,7 @@
 
             t.traceBegin("StartTelephonyRegistry");
             telephonyRegistry = new TelephonyRegistry(
-                    context, new TelephonyRegistry.ConfigurationProvider());
+                context, new TelephonyRegistry.ConfigurationProvider());
             ServiceManager.addService("telephony.registry", telephonyRegistry);
             t.traceEnd();
 
@@ -2547,12 +2542,6 @@
                 STATS_COMPANION_LIFECYCLE_CLASS, STATS_COMPANION_APEX_PATH);
         t.traceEnd();
 
-        // Reboot Readiness
-        t.traceBegin("StartRebootReadinessManagerService");
-        mSystemServiceManager.startServiceFromJar(
-                REBOOT_READINESS_LIFECYCLE_CLASS, SCHEDULING_APEX_PATH);
-        t.traceEnd();
-
         // Statsd pulled atoms
         t.traceBegin("StartStatsPullAtomService");
         mSystemServiceManager.startService(STATS_PULL_ATOM_SERVICE_CLASS);
@@ -2999,9 +2988,7 @@
             t.traceEnd();
             t.traceBegin("MakeTelephonyRegistryReady");
             try {
-                if (telephonyRegistryF != null) {
-                    telephonyRegistryF.systemRunning();
-                }
+                if (telephonyRegistryF != null) telephonyRegistryF.systemRunning();
             } catch (Throwable e) {
                 reportWtf("Notifying TelephonyRegistry running", e);
             }
@@ -3066,12 +3053,10 @@
      */
     private void startApexServices(@NonNull TimingsTraceAndSlog t) {
         t.traceBegin("startApexServices");
-        // TODO(b/192880996): get the list from "android" package, once the manifest entries
-        // are migrated to system manifest.
-        List<ApexSystemServiceInfo> services = ApexManager.getInstance().getApexSystemServices();
-        for (ApexSystemServiceInfo info : services) {
-            String name = info.getName();
-            String jarPath = info.getJarPath();
+        Map<String, String> services = ApexManager.getInstance().getApexSystemServices();
+        // TODO(satayev): introduce android:order for services coming the same apexes
+        for (String name : new TreeSet<>(services.keySet())) {
+            String jarPath = services.get(name);
             t.traceBegin("starting " + name);
             if (TextUtils.isEmpty(jarPath)) {
                 mSystemServiceManager.startService(name);
diff --git a/services/tests/apexsystemservices/Android.bp b/services/tests/apexsystemservices/Android.bp
index 01e90a8..a6ed1ae 100644
--- a/services/tests/apexsystemservices/Android.bp
+++ b/services/tests/apexsystemservices/Android.bp
@@ -37,5 +37,8 @@
         "truth-prebuilt",
         "modules-utils-build-testing",
     ],
-    test_suites: ["device-tests"],
+    test_suites: [
+        "device-tests",
+        "mts-core",
+    ],
 }
diff --git a/services/tests/apexsystemservices/apexes/test_com.android.server/Android.bp b/services/tests/apexsystemservices/apexes/test_com.android.server/Android.bp
index 0a9b7b1..16d6241 100644
--- a/services/tests/apexsystemservices/apexes/test_com.android.server/Android.bp
+++ b/services/tests/apexsystemservices/apexes/test_com.android.server/Android.bp
@@ -32,7 +32,7 @@
     name: "test_com.android.server",
     manifest: "manifest.json",
     androidManifest: "AndroidManifest.xml",
-    java_libs: ["FakeApexSystemServices"],
+    java_libs: ["FakeApexSystemService"],
     file_contexts: ":apex.test-file_contexts",
     key: "test_com.android.server.key",
     updatable: false,
diff --git a/services/tests/apexsystemservices/apexes/test_com.android.server/AndroidManifest.xml b/services/tests/apexsystemservices/apexes/test_com.android.server/AndroidManifest.xml
index 6bec284..eb741ca 100644
--- a/services/tests/apexsystemservices/apexes/test_com.android.server/AndroidManifest.xml
+++ b/services/tests/apexsystemservices/apexes/test_com.android.server/AndroidManifest.xml
@@ -21,29 +21,21 @@
     <application android:hasCode="false" android:testOnly="true">
         <apex-system-service
             android:name="com.android.server.testing.FakeApexSystemService"
-            android:path="/apex/test_com.android.server/javalib/FakeApexSystemServices.jar"
-            android:minSdkVersion="30"
-        />
-
-        <apex-system-service
-            android:name="com.android.server.testing.FakeApexSystemService2"
-            android:path="/apex/test_com.android.server/javalib/FakeApexSystemServices.jar"
-            android:minSdkVersion="30"
-            android:initOrder="1"
-        />
+            android:path="/apex/test_com.android.server/javalib/FakeApexSystemService.jar"
+            android:minSdkVersion="30"/>
 
         <!-- Always inactive system service, since maxSdkVersion is low -->
         <apex-system-service
-            android:name="com.android.server.testing.OldApexSystemService"
-            android:path="/apex/test_com.android.server/javalib/fake.jar"
+            android:name="com.android.apex.test.OldApexSystemService"
+            android:path="/apex/com.android.apex.test/javalib/fake.jar"
             android:minSdkVersion="1"
             android:maxSdkVersion="1"
         />
 
         <!-- Always inactive system service, since minSdkVersion is high -->
         <apex-system-service
-            android:name="com.android.server.testing.NewApexSystemService"
-            android:path="/apex/test_com.android.server/javalib/fake.jar"
+            android:name="com.android.apex.test.NewApexSystemService"
+            android:path="/apex/com.android.apex.test/javalib/fake.jar"
             android:minSdkVersion="999999"
         />
     </application>
diff --git a/services/tests/apexsystemservices/services/Android.bp b/services/tests/apexsystemservices/service/Android.bp
similarity index 94%
rename from services/tests/apexsystemservices/services/Android.bp
rename to services/tests/apexsystemservices/service/Android.bp
index 477ea4c..9d04f39 100644
--- a/services/tests/apexsystemservices/services/Android.bp
+++ b/services/tests/apexsystemservices/service/Android.bp
@@ -8,7 +8,7 @@
 }
 
 java_library {
-    name: "FakeApexSystemServices",
+    name: "FakeApexSystemService",
     srcs: ["**/*.java"],
     sdk_version: "system_server_current",
     libs: [
diff --git a/services/tests/apexsystemservices/services/src/com/android/server/testing/FakeApexSystemService.java b/services/tests/apexsystemservices/service/src/com/android/server/testing/FakeApexSystemService.java
similarity index 100%
rename from services/tests/apexsystemservices/services/src/com/android/server/testing/FakeApexSystemService.java
rename to services/tests/apexsystemservices/service/src/com/android/server/testing/FakeApexSystemService.java
diff --git a/services/tests/apexsystemservices/services/src/com/android/server/testing/FakeApexSystemService2.java b/services/tests/apexsystemservices/services/src/com/android/server/testing/FakeApexSystemService2.java
deleted file mode 100644
index e83343b..0000000
--- a/services/tests/apexsystemservices/services/src/com/android/server/testing/FakeApexSystemService2.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 com.android.server.testing;
-
-import android.content.Context;
-import android.util.Log;
-
-import androidx.annotation.NonNull;
-
-import com.android.server.SystemService;
-
-/**
- * A fake system service that just logs when it is started.
- */
-public class FakeApexSystemService2 extends SystemService {
-
-    private static final String TAG = "FakeApexSystemService";
-
-    public FakeApexSystemService2(@NonNull Context context) {
-        super(context);
-    }
-
-    @Override
-    public void onStart() {
-        Log.d(TAG, "FakeApexSystemService2 onStart");
-    }
-}
diff --git a/services/tests/apexsystemservices/src/com/android/server/ApexSystemServicesTestCases.java b/services/tests/apexsystemservices/src/com/android/server/ApexSystemServicesTestCases.java
index 7ab7b6ed..2b453a9 100644
--- a/services/tests/apexsystemservices/src/com/android/server/ApexSystemServicesTestCases.java
+++ b/services/tests/apexsystemservices/src/com/android/server/ApexSystemServicesTestCases.java
@@ -37,10 +37,6 @@
 import org.junit.rules.TemporaryFolder;
 import org.junit.runner.RunWith;
 
-import java.util.Objects;
-import java.util.regex.Pattern;
-import java.util.stream.Collectors;
-
 @RunWith(DeviceJUnit4ClassRunner.class)
 public class ApexSystemServicesTestCases extends BaseHostJUnit4Test {
 
@@ -71,7 +67,7 @@
     }
 
     @Test
-    public void testNoApexSystemServiceStartsWithoutApex() throws Exception {
+    public void noApexSystemServerStartsWithoutApex() throws Exception {
         mPreparer.reboot();
 
         assertThat(getFakeApexSystemServiceLogcat())
@@ -79,7 +75,7 @@
     }
 
     @Test
-    public void testApexSystemServiceStarts() throws Exception {
+    public void apexSystemServerStarts() throws Exception {
         // Pre-install the apex
         String apex = "test_com.android.server.apex";
         mPreparer.pushResourceFile(apex, "/system/apex/" + apex);
@@ -90,40 +86,9 @@
                 .contains("FakeApexSystemService onStart");
     }
 
-    @Test
-    public void testInitOrder() throws Exception {
-        // Pre-install the apex
-        String apex = "test_com.android.server.apex";
-        mPreparer.pushResourceFile(apex, "/system/apex/" + apex);
-        // Reboot activates the apex
-        mPreparer.reboot();
-
-        assertThat(getFakeApexSystemServiceLogcat().lines()
-                .map(ApexSystemServicesTestCases::getDebugMessage)
-                .filter(Objects::nonNull)
-                .collect(Collectors.toList()))
-                .containsExactly(
-                        // Second service has a higher initOrder and must be started first
-                        "FakeApexSystemService2 onStart",
-                        "FakeApexSystemService onStart"
-                )
-                .inOrder();
-    }
-
     private String getFakeApexSystemServiceLogcat() throws DeviceNotAvailableException {
         return mDevice.executeAdbCommand("logcat", "-v", "brief", "-d", "FakeApexSystemService:D",
                 "*:S");
     }
 
-    private static final Pattern DEBUG_MESSAGE =
-            Pattern.compile("(FakeApexSystemService[0-9]* onStart)");
-
-    private static String getDebugMessage(String logcatLine) {
-        return DEBUG_MESSAGE.matcher(logcatLine)
-                .results()
-                .map(m -> m.group(1))
-                .findFirst()
-                .orElse(null);
-    }
-
 }
diff --git a/services/tests/servicestests/Android.bp b/services/tests/servicestests/Android.bp
index c3a364e..171af77 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/display/AutomaticBrightnessControllerTest.java b/services/tests/servicestests/src/com/android/server/display/AutomaticBrightnessControllerTest.java
index 176e5a9..54945e4 100644
--- a/services/tests/servicestests/src/com/android/server/display/AutomaticBrightnessControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/AutomaticBrightnessControllerTest.java
@@ -19,6 +19,7 @@
 import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.anyFloat;
@@ -34,18 +35,22 @@
 import android.hardware.SensorManager;
 import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
 import android.os.Handler;
+import android.os.test.TestLooper;
 import android.platform.test.annotations.Presubmit;
 
 import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.server.testutils.OffsettableClock;
+
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
+import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 
 @SmallTest
@@ -61,7 +66,11 @@
     private static final float DOZE_SCALE_FACTOR = 0.0f;
     private static final boolean RESET_AMBIENT_LUX_AFTER_WARMUP_CONFIG = false;
     private static final int LIGHT_SENSOR_WARMUP_TIME = 0;
-
+    private static final int AMBIENT_LIGHT_HORIZON_SHORT = 1000;
+    private static final int AMBIENT_LIGHT_HORIZON_LONG = 2000;
+    private static final float EPSILON = 0.001f;
+    private OffsettableClock mClock = new OffsettableClock();
+    private TestLooper mTestLooper;
     private Context mContext;
     private AutomaticBrightnessController mController;
 
@@ -91,21 +100,36 @@
         }
     }
 
+    private void advanceTime(long timeMs) {
+        mClock.fastForward(timeMs);
+        mTestLooper.dispatchAll();
+    }
+
     private AutomaticBrightnessController setupController(Sensor lightSensor) {
+        mClock = new OffsettableClock.Stopped();
+        mTestLooper = new TestLooper(mClock::now);
+
         AutomaticBrightnessController controller = new AutomaticBrightnessController(
                 new AutomaticBrightnessController.Injector() {
                     @Override
                     public Handler getBackgroundThreadHandler() {
                         return mNoOpHandler;
                     }
-                },
-                () -> { }, mContext.getMainLooper(), mSensorManager, lightSensor,
+
+                    @Override
+                    AutomaticBrightnessController.Clock createClock() {
+                        return mClock::now;
+                    }
+
+                }, // pass in test looper instead, pass in offsetable clock
+                () -> { }, mTestLooper.getLooper(), mSensorManager, lightSensor,
                 mBrightnessMappingStrategy, LIGHT_SENSOR_WARMUP_TIME, BRIGHTNESS_MIN_FLOAT,
                 BRIGHTNESS_MAX_FLOAT, DOZE_SCALE_FACTOR, LIGHT_SENSOR_RATE,
                 INITIAL_LIGHT_SENSOR_RATE, BRIGHTENING_LIGHT_DEBOUNCE_CONFIG,
                 DARKENING_LIGHT_DEBOUNCE_CONFIG, RESET_AMBIENT_LUX_AFTER_WARMUP_CONFIG,
                 mAmbientBrightnessThresholds, mScreenBrightnessThresholds,
-                mContext, mHbmController, mIdleBrightnessMappingStrategy
+                mContext, mHbmController, mIdleBrightnessMappingStrategy,
+                AMBIENT_LIGHT_HORIZON_SHORT, AMBIENT_LIGHT_HORIZON_LONG
         );
 
         when(mHbmController.getCurrentBrightnessMax()).thenReturn(BRIGHTNESS_MAX_FLOAT);
@@ -276,4 +300,95 @@
         // Ensure we use the correct mapping strategy
         verify(mIdleBrightnessMappingStrategy, times(1)).addUserDataPoint(1000f, 0.5f);
     }
+
+    @Test
+    public void testAmbientLightHorizon() throws Exception {
+        // create abc
+        Sensor lightSensor = TestUtils.createSensor(Sensor.TYPE_LIGHT, "Light Sensor");
+        mController = setupController(lightSensor);
+        ArgumentCaptor<SensorEventListener> listenerCaptor =
+                ArgumentCaptor.forClass(SensorEventListener.class);
+        verify(mSensorManager).registerListener(listenerCaptor.capture(), eq(lightSensor),
+                eq(INITIAL_LIGHT_SENSOR_RATE * 1000), any(Handler.class));
+        SensorEventListener listener = listenerCaptor.getValue();
+
+        long increment = 500;
+        // set autobrightness to low
+        // t = 0
+        listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, 0));
+
+        // t = 500
+        mClock.fastForward(increment);
+        listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, 0));
+
+        // t = 1000
+        mClock.fastForward(increment);
+        listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, 0));
+        assertEquals(0.0f, mController.getAmbientLux(), EPSILON);
+
+        // t = 1500
+        mClock.fastForward(increment);
+        listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, 0));
+        assertEquals(0.0f, mController.getAmbientLux(), EPSILON);
+
+        // t = 2000
+        // ensure that our reading is at 0.
+        mClock.fastForward(increment);
+        listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, 0));
+        assertEquals(0.0f, mController.getAmbientLux(), EPSILON);
+
+        // t = 2500
+        // first 10000 lux sensor event reading
+        mClock.fastForward(increment);
+        listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, 10000));
+        assertTrue(mController.getAmbientLux() > 0.0f);
+        assertTrue(mController.getAmbientLux() < 10000.0f);
+
+        // t = 3000
+        // lux reading should still not yet be 10000.
+        mClock.fastForward(increment);
+        listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, 10000));
+        assertTrue(mController.getAmbientLux() > 0.0f);
+        assertTrue(mController.getAmbientLux() < 10000.0f);
+
+        // t = 3500
+        mClock.fastForward(increment);
+        // lux has been high (10000) for 1000ms.
+        // lux reading should be 10000
+        // short horizon (ambient lux) is high, long horizon is still not high
+        listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, 10000));
+        assertEquals(10000.0f, mController.getAmbientLux(), EPSILON);
+
+        // t = 4000
+        // stay high
+        mClock.fastForward(increment);
+        listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, 10000));
+        assertEquals(10000.0f, mController.getAmbientLux(), EPSILON);
+
+        // t = 4500
+        Mockito.clearInvocations(mBrightnessMappingStrategy);
+        mClock.fastForward(increment);
+        // short horizon is high, long horizon is high too
+        listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, 10000));
+        verify(mBrightnessMappingStrategy, times(1)).getBrightness(10000, null, -1);
+        assertEquals(10000.0f, mController.getAmbientLux(), EPSILON);
+
+        // t = 5000
+        mClock.fastForward(increment);
+        listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, 0));
+        assertTrue(mController.getAmbientLux() > 0.0f);
+        assertTrue(mController.getAmbientLux() < 10000.0f);
+
+        // t = 5500
+        mClock.fastForward(increment);
+        listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, 0));
+        assertTrue(mController.getAmbientLux() > 0.0f);
+        assertTrue(mController.getAmbientLux() < 10000.0f);
+
+        // t = 6000
+        mClock.fastForward(increment);
+        // ambient lux goes to 0
+        listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, 0));
+        assertEquals(0.0f, mController.getAmbientLux(), EPSILON);
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/pm/ApexManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/ApexManagerTest.java
index 2f5993d1..7f7c716 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ApexManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ApexManagerTest.java
@@ -61,7 +61,7 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
-import java.util.List;
+import java.util.Map;
 
 @SmallTest
 @Presubmit
@@ -136,10 +136,9 @@
         mApexManager.scanApexPackagesTraced(mPackageParser2,
                 ParallelPackageParser.makeExecutorService());
 
-        List<ApexSystemServiceInfo> services = mApexManager.getApexSystemServices();
+        Map<String, String> services = mApexManager.getApexSystemServices();
         assertThat(services).hasSize(1);
-        assertThat(services.stream().map(ApexSystemServiceInfo::getName).findFirst().orElse(null))
-                .matches("com.android.apex.test.ApexSystemService");
+        assertThat(services).containsKey("com.android.apex.test.ApexSystemService");
     }
 
     @Test
diff --git a/telephony/java/android/telephony/ims/ImsService.java b/telephony/java/android/telephony/ims/ImsService.java
index 53dff54..be233b8 100644
--- a/telephony/java/android/telephony/ims/ImsService.java
+++ b/telephony/java/android/telephony/ims/ImsService.java
@@ -42,6 +42,7 @@
 import android.telephony.ims.stub.SipTransportImplBase;
 import android.util.Log;
 import android.util.SparseArray;
+import android.util.SparseBooleanArray;
 
 import com.android.ims.internal.IImsFeatureStatusCallback;
 import com.android.internal.annotations.VisibleForTesting;
@@ -180,6 +181,12 @@
     // call ImsFeature#onFeatureRemoved.
     private final SparseArray<SparseArray<ImsFeature>> mFeaturesBySlot = new SparseArray<>();
 
+    // A map of slot id -> boolean array, where each entry in the boolean array corresponds to an
+    // ImsFeature that was created for a slot id and not a sub id for backwards compatibility
+    // purposes.
+    private final SparseArray<SparseBooleanArray> mCreateImsFeatureWithSlotIdFlagMap =
+            new SparseArray<>();
+
     private IImsServiceControllerListener mListener;
     private Executor mExecutor;
 
@@ -222,15 +229,36 @@
         }
 
         @Override
-        public IImsMmTelFeature createMmTelFeature(int slotId) {
-            return executeMethodAsyncForResult(() -> createMmTelFeatureInternal(slotId),
-                "createMmTelFeature");
+        public IImsMmTelFeature createMmTelFeature(int slotId, int subId) {
+            MmTelFeature f  = (MmTelFeature) getImsFeature(slotId, ImsFeature.FEATURE_MMTEL);
+            if (f == null) {
+                return executeMethodAsyncForResult(() -> createMmTelFeatureInternal(slotId, subId),
+                        "createMmTelFeature");
+            } else {
+                return f.getBinder();
+            }
         }
 
         @Override
-        public IImsRcsFeature createRcsFeature(int slotId) {
-            return executeMethodAsyncForResult(() -> createRcsFeatureInternal(slotId),
-                "createRcsFeature");
+        public IImsMmTelFeature createEmergencyOnlyMmTelFeature(int slotId) {
+            MmTelFeature f  = (MmTelFeature) getImsFeature(slotId, ImsFeature.FEATURE_MMTEL);
+            if (f == null) {
+                return executeMethodAsyncForResult(() -> createEmergencyOnlyMmTelFeatureInternal(
+                        slotId), "createEmergencyOnlyMmTelFeature");
+            } else {
+                return f.getBinder();
+            }
+        }
+
+        @Override
+        public IImsRcsFeature createRcsFeature(int slotId, int subId) {
+            RcsFeature f  = (RcsFeature) getImsFeature(slotId, ImsFeature.FEATURE_RCS);
+            if (f == null) {
+                return executeMethodAsyncForResult(() ->
+                        createRcsFeatureInternal(slotId, subId), "createRcsFeature");
+            } else {
+                return f.getBinder();
+            }
         }
 
         @Override
@@ -248,9 +276,14 @@
         }
 
         @Override
-        public void removeImsFeature(int slotId, int featureType) {
+        public void removeImsFeature(int slotId, int featureType, boolean changeSubId) {
+            if (changeSubId && isImsFeatureCreatedForSlot(slotId, featureType)) {
+                Log.w(LOG_TAG, "Do not remove Ims feature for compatibility");
+                return;
+            }
             executeMethodAsync(() -> ImsService.this.removeImsFeature(slotId, featureType),
                     "removeImsFeature");
+            setImsFeatureCreatedForSlot(slotId, featureType, false);
         }
 
         @Override
@@ -279,9 +312,10 @@
         }
 
         @Override
-        public IImsConfig getConfig(int slotId) {
+        public IImsConfig getConfig(int slotId, int subId) {
             return executeMethodAsyncForResult(() -> {
-                ImsConfigImplBase c = ImsService.this.getConfig(slotId);
+                ImsConfigImplBase c =
+                        ImsService.this.getConfigForSubscription(slotId, subId);
                 if (c != null) {
                     c.setDefaultExecutor(mExecutor);
                     return c.getIImsConfig();
@@ -292,9 +326,10 @@
         }
 
         @Override
-        public IImsRegistration getRegistration(int slotId) {
+        public IImsRegistration getRegistration(int slotId, int subId) {
             return executeMethodAsyncForResult(() -> {
-                ImsRegistrationImplBase r =  ImsService.this.getRegistration(slotId);
+                ImsRegistrationImplBase r =
+                        ImsService.this.getRegistrationForSubscription(slotId, subId);
                 if (r != null) {
                     r.setDefaultExecutor(mExecutor);
                     return r.getBinder();
@@ -318,13 +353,15 @@
         }
 
         @Override
-        public void enableIms(int slotId) {
-            executeMethodAsync(() -> ImsService.this.enableIms(slotId), "enableIms");
+        public void enableIms(int slotId, int subId) {
+            executeMethodAsync(() ->
+                    ImsService.this.enableImsForSubscription(slotId, subId), "enableIms");
         }
 
         @Override
-        public void disableIms(int slotId) {
-            executeMethodAsync(() -> ImsService.this.disableIms(slotId), "disableIms");
+        public void disableIms(int slotId, int subId) {
+            executeMethodAsync(() ->
+                    ImsService.this.disableImsForSubscription(slotId, subId), "disableIms");
         }
 
         // Call the methods with a clean calling identity on the executor and wait indefinitely for
@@ -364,16 +401,8 @@
         return null;
     }
 
-    /**
-     * @hide
-     */
-    @VisibleForTesting
-    public SparseArray<ImsFeature> getFeatures(int slotId) {
-        return mFeaturesBySlot.get(slotId);
-    }
-
-    private IImsMmTelFeature createMmTelFeatureInternal(int slotId) {
-        MmTelFeature f = createMmTelFeature(slotId);
+    private IImsMmTelFeature createMmTelFeatureInternal(int slotId, int subscriptionId) {
+        MmTelFeature f = createMmTelFeatureForSubscription(slotId, subscriptionId);
         if (f != null) {
             setupFeature(f, slotId, ImsFeature.FEATURE_MMTEL);
             f.setDefaultExecutor(mExecutor);
@@ -384,8 +413,20 @@
         }
     }
 
-    private IImsRcsFeature createRcsFeatureInternal(int slotId) {
-        RcsFeature f = createRcsFeature(slotId);
+    private IImsMmTelFeature createEmergencyOnlyMmTelFeatureInternal(int slotId) {
+        MmTelFeature f = createEmergencyOnlyMmTelFeature(slotId);
+        if (f != null) {
+            setupFeature(f, slotId, ImsFeature.FEATURE_MMTEL);
+            f.setDefaultExecutor(mExecutor);
+            return f.getBinder();
+        } else {
+            Log.e(LOG_TAG, "createEmergencyOnlyMmTelFeatureInternal: null feature returned.");
+            return null;
+        }
+    }
+
+    private IImsRcsFeature createRcsFeatureInternal(int slotId, int subI) {
+        RcsFeature f = createRcsFeatureForSubscription(slotId, subI);
         if (f != null) {
             f.setDefaultExecutor(mExecutor);
             setupFeature(f, slotId, ImsFeature.FEATURE_RCS);
@@ -466,6 +507,49 @@
             f.onFeatureRemoved();
             features.remove(featureType);
         }
+
+    }
+
+    /**
+     * @hide
+     */
+    @VisibleForTesting
+    public ImsFeature getImsFeature(int slotId, int featureType) {
+        synchronized (mFeaturesBySlot) {
+            // Get SparseArray for Features, by querying slot Id
+            SparseArray<ImsFeature> features = mFeaturesBySlot.get(slotId);
+            if (features == null) {
+                return null;
+            }
+            return features.get(featureType);
+        }
+    }
+
+    private void setImsFeatureCreatedForSlot(int slotId,
+            @ImsFeature.FeatureType int featureType, boolean createdForSlot) {
+        synchronized (mCreateImsFeatureWithSlotIdFlagMap) {
+            getImsFeatureCreatedForSlot(slotId).put(featureType, createdForSlot);
+        }
+    }
+
+    /**
+     * @hide
+     */
+    @VisibleForTesting
+    public boolean isImsFeatureCreatedForSlot(int slotId,
+            @ImsFeature.FeatureType int featureType) {
+        synchronized (mCreateImsFeatureWithSlotIdFlagMap) {
+            return getImsFeatureCreatedForSlot(slotId).get(featureType);
+        }
+    }
+
+    private SparseBooleanArray getImsFeatureCreatedForSlot(int slotId) {
+        SparseBooleanArray createFlag = mCreateImsFeatureWithSlotIdFlagMap.get(slotId);
+        if (createFlag == null) {
+            createFlag = new SparseBooleanArray();
+            mCreateImsFeatureWithSlotIdFlagMap.put(slotId, createFlag);
+        }
+        return createFlag;
     }
 
     /**
@@ -524,27 +608,95 @@
     }
 
     /**
+     * The framework has enabled IMS for the subscription specified, the ImsService should register
+     * for IMS and perform all appropriate initialization to bring up all ImsFeatures.
+     *
+     * @param slotId The slot ID that IMS will be enabled for.
+     * @param subscriptionId The subscription ID that IMS will be enabled for.
+     */
+    public void enableImsForSubscription(int slotId, int subscriptionId) {
+        enableIms(slotId);
+    }
+
+    /**
+     * The framework has disabled IMS for the subscription specified. The ImsService must deregister
+     * for IMS and set capability status to false for all ImsFeatures.
+     * @param slotId The slot ID that IMS will be disabled for.
+     * @param subscriptionId The subscription ID that IMS will be disabled for.
+     */
+    public void disableImsForSubscription(int slotId, int subscriptionId) {
+        disableIms(slotId);
+    }
+
+    /**
      * The framework has enabled IMS for the slot specified, the ImsService should register for IMS
      * and perform all appropriate initialization to bring up all ImsFeatures.
+     * @deprecated Use {@link #enableImsForSubscription} instead.
      */
+    @Deprecated
     public void enableIms(int slotId) {
     }
 
     /**
      * The framework has disabled IMS for the slot specified. The ImsService must deregister for IMS
      * and set capability status to false for all ImsFeatures.
+     * @deprecated Use {@link #disableImsForSubscription} instead.
      */
+    @Deprecated
     public void disableIms(int slotId) {
     }
 
     /**
      * When called, the framework is requesting that a new {@link MmTelFeature} is created for the
+     * specified subscription.
+     *
+     * @param subscriptionId The subscription ID that the MMTEL Feature is being created for.
+     * @return The newly created {@link MmTelFeature} associated with the subscription or null if
+     * the feature is not supported.
+     */
+    public @Nullable MmTelFeature createMmTelFeatureForSubscription(int slotId,
+            int subscriptionId) {
+        setImsFeatureCreatedForSlot(slotId, ImsFeature.FEATURE_MMTEL, true);
+        return createMmTelFeature(slotId);
+    }
+
+    /**
+     * When called, the framework is requesting that a new {@link RcsFeature} is created for the
+     * specified subscription.
+     *
+     * @param subscriptionId The subscription ID that the RCS Feature is being created for.
+     * @return The newly created {@link RcsFeature} associated with the subscription or null if the
+     * feature is not supported.
+     */
+    public @Nullable RcsFeature createRcsFeatureForSubscription(int slotId, int subscriptionId) {
+        setImsFeatureCreatedForSlot(slotId, ImsFeature.FEATURE_RCS, true);
+        return createRcsFeature(slotId);
+    }
+
+    /**
+     * When called, the framework is requesting that a new emergency-only {@link MmTelFeature} is
+     * created for the specified slot. For emergency calls, there is no known Subscription Id.
+     *
+     * @param slotId The slot ID that the MMTEL Feature is being created for.
+     * @return An MmTelFeature instance to be used for the slot ID when there is not
+     * subscription inserted. Only requested when there is no subscription active on
+     * the specified slot.
+     */
+    public @Nullable MmTelFeature createEmergencyOnlyMmTelFeature(int slotId) {
+        setImsFeatureCreatedForSlot(slotId, ImsFeature.FEATURE_MMTEL, true);
+        return createMmTelFeature(slotId);
+    }
+
+    /**
+     * When called, the framework is requesting that a new {@link MmTelFeature} is created for the
      * specified slot.
+     * @deprecated Use {@link #createMmTelFeatureForSubscription} instead
      *
      * @param slotId The slot ID that the MMTEL Feature is being created for.
      * @return The newly created {@link MmTelFeature} associated with the slot or null if the
      * feature is not supported.
      */
+    @Deprecated
     public MmTelFeature createMmTelFeature(int slotId) {
         return null;
     }
@@ -552,32 +704,62 @@
     /**
      * When called, the framework is requesting that a new {@link RcsFeature} is created for the
      * specified slot.
+     * @deprecated Use {@link #createRcsFeatureForSubscription} instead
      *
      * @param slotId The slot ID that the RCS Feature is being created for.
      * @return The newly created {@link RcsFeature} associated with the slot or null if the feature
      * is not supported.
      */
+    @Deprecated
     public RcsFeature createRcsFeature(int slotId) {
         return null;
     }
 
     /**
+     * Return the {@link ImsConfigImplBase} implementation associated with the provided
+     * subscription. This will be used by the platform to get/set specific IMS related
+     * configurations.
+     *
+     * @param subscriptionId The subscription ID that the IMS configuration is associated with.
+     * @return ImsConfig implementation that is associated with the specified subscription.
+     */
+    public @NonNull ImsConfigImplBase getConfigForSubscription(int slotId, int subscriptionId) {
+        return getConfig(slotId);
+    }
+
+    /**
+     * Return the {@link ImsRegistrationImplBase} implementation associated with the provided
+     * subscription.
+     *
+     * @param subscriptionId The subscription ID that is associated with the IMS Registration.
+     * @return the ImsRegistration implementation associated with the subscription.
+     */
+    public @NonNull ImsRegistrationImplBase getRegistrationForSubscription(int slotId,
+            int subscriptionId) {
+        return getRegistration(slotId);
+    }
+
+    /**
      * Return the {@link ImsConfigImplBase} implementation associated with the provided slot. This
      * will be used by the platform to get/set specific IMS related configurations.
+     * @deprecated use {@link #getConfigForSubscription} instead.
      *
      * @param slotId The slot that the IMS configuration is associated with.
      * @return ImsConfig implementation that is associated with the specified slot.
      */
+    @Deprecated
     public ImsConfigImplBase getConfig(int slotId) {
         return new ImsConfigImplBase();
     }
 
     /**
      * Return the {@link ImsRegistrationImplBase} implementation associated with the provided slot.
+     * @deprecated use  {@link #getRegistrationForSubscription} instead.
      *
      * @param slotId The slot that is associated with the IMS Registration.
      * @return the ImsRegistration implementation associated with the slot.
      */
+    @Deprecated
     public ImsRegistrationImplBase getRegistration(int slotId) {
         return new ImsRegistrationImplBase();
     }
diff --git a/telephony/java/android/telephony/ims/aidl/IImsServiceController.aidl b/telephony/java/android/telephony/ims/aidl/IImsServiceController.aidl
index c6966b3..ae6166f 100644
--- a/telephony/java/android/telephony/ims/aidl/IImsServiceController.aidl
+++ b/telephony/java/android/telephony/ims/aidl/IImsServiceController.aidl
@@ -32,18 +32,19 @@
  */
 interface IImsServiceController {
     void setListener(IImsServiceControllerListener l);
-    IImsMmTelFeature createMmTelFeature(int slotId);
-    IImsRcsFeature createRcsFeature(int slotId);
+    IImsMmTelFeature createMmTelFeature(int slotId, int subId);
+    IImsMmTelFeature createEmergencyOnlyMmTelFeature(int slotId);
+    IImsRcsFeature createRcsFeature(int slotId, int subId);
     ImsFeatureConfiguration querySupportedImsFeatures();
     long getImsServiceCapabilities();
     void addFeatureStatusCallback(int slotId, int featureType, in IImsFeatureStatusCallback c);
     void removeFeatureStatusCallback(int slotId, int featureType, in IImsFeatureStatusCallback c);
     // Synchronous call to ensure the ImsService is ready before continuing with feature creation.
     void notifyImsServiceReadyForFeatureCreation();
-    void removeImsFeature(int slotId, int featureType);
-    IImsConfig getConfig(int slotId);
-    IImsRegistration getRegistration(int slotId);
+    void removeImsFeature(int slotId, int featureType, boolean changeSubId);
+    IImsConfig getConfig(int slotId, int subId);
+    IImsRegistration getRegistration(int slotId, int subId);
     ISipTransport getSipTransport(int slotId);
-    oneway void enableIms(int slotId);
-    oneway void disableIms(int slotId);
+    oneway void enableIms(int slotId, int subId);
+    oneway void disableIms(int slotId, int subId);
 }
diff --git a/telephony/java/com/android/ims/internal/IImsServiceFeatureCallback.aidl b/telephony/java/com/android/ims/internal/IImsServiceFeatureCallback.aidl
index f5f67bd..416096b 100644
--- a/telephony/java/com/android/ims/internal/IImsServiceFeatureCallback.aidl
+++ b/telephony/java/com/android/ims/internal/IImsServiceFeatureCallback.aidl
@@ -23,11 +23,11 @@
  * {@hide}
  */
 oneway interface IImsServiceFeatureCallback {
-    void imsFeatureCreated(in ImsFeatureContainer feature);
+    void imsFeatureCreated(in ImsFeatureContainer feature, int subId);
     // Reason defined in FeatureConnector.UnavailableReason
     void imsFeatureRemoved(int reason);
     // Status defined in ImsFeature.ImsState.
-    void imsStatusChanged(int status);
+    void imsStatusChanged(int status, int subId);
     //Capabilities defined in ImsService.ImsServiceCapability
     void updateCapabilities(long capabilities);
 }
\ No newline at end of file
diff --git a/tests/DozeTest/src/com/android/dreams/dozetest/DozeTestDream.java b/tests/DozeTest/src/com/android/dreams/dozetest/DozeTestDream.java
index 6985702..9a88abd 100644
--- a/tests/DozeTest/src/com/android/dreams/dozetest/DozeTestDream.java
+++ b/tests/DozeTest/src/com/android/dreams/dozetest/DozeTestDream.java
@@ -81,7 +81,8 @@
         intent.setPackage(getPackageName());
         IntentFilter filter = new IntentFilter();
         filter.addAction(intent.getAction());
-        registerReceiver(mAlarmReceiver, filter);
+        registerReceiver(mAlarmReceiver, filter,
+                Context.RECEIVER_EXPORTED_UNAUDITED);
         mAlarmIntent = PendingIntent.getBroadcast(this, 0, intent,
                 PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_MUTABLE_UNAUDITED);