Migrating frameworks/base BT files

Bug: 206121418
Test: Compile
Change-Id: Idb55371e9d678296fe46e5f4231ec2d12ec8b978
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/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/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());
-    }
-}