Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 891d48ae authored by Sungsoo Lim's avatar Sungsoo Lim
Browse files

Reduce the use of locks to avoid deadlock

ActiveDeviceManager and HeadsetService hold locks. When they call each
other's method with the lock, deadlock could happen.
This CL reduce the usage of such methods calls with the lock.

Bug: 298530017
Test: atest BluetoothInstrumentationTests
Change-Id: Ic7d454b10be22b4d4e4a235dc32c50b90d652a21
parent 4e3cc3ba
Loading
Loading
Loading
Loading
+49 −42
Original line number Diff line number Diff line
@@ -373,6 +373,7 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac
                return;
            }
            mHearingAidConnectedDevices.add(device);
        }
        // New connected device: select it as active
        if (setHearingAidActiveDevice(device)) {
            setA2dpActiveDevice(null, true);
@@ -380,7 +381,6 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac
            setLeAudioActiveDevice(null, true);
        }
    }
    }

    private void handleLeAudioConnected(BluetoothDevice device) {
        synchronized (mLock) {
@@ -669,8 +669,12 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac
    private void handleHearingAidActiveDeviceChanged(BluetoothDevice device) {
        synchronized (mLock) {
            if (DBG) {
                Log.d(TAG, "handleHearingAidActiveDeviceChanged: " + device
                        + ", mHearingAidActiveDevices=" + mHearingAidActiveDevices);
                Log.d(
                        TAG,
                        "handleHearingAidActiveDeviceChanged: "
                                + device
                                + ", mHearingAidActiveDevices="
                                + mHearingAidActiveDevices);
            }
            // Just assign locally the new value
            final HearingAidService hearingAidService = mFactory.getHearingAidService();
@@ -684,13 +688,13 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac
                            hearingAidService.getConnectedPeerDevices(hiSyncId));
                }
            }
        }
        if (device != null) {
            setA2dpActiveDevice(null, true);
            setHfpActiveDevice(null);
            setLeAudioActiveDevice(null, true);
        }
    }
    }

    private void handleLeAudioActiveDeviceChanged(BluetoothDevice device) {
        synchronized (mLock) {
@@ -849,26 +853,29 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac

    @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
    private boolean setHfpActiveDevice(BluetoothDevice device) {
        synchronized (mLock) {
        if (DBG) {
            Log.d(TAG, "setHfpActiveDevice(" + device + ")");
        }
        synchronized (mLock) {
            if (mPendingActiveDevice != null) {
                mHandler.removeCallbacksAndMessages(mPendingActiveDevice);
                mPendingActiveDevice = null;
            }
        }
        final HeadsetService headsetService = mFactory.getHeadsetService();
        if (headsetService == null) {
            return false;
        }
        BluetoothSinkAudioPolicy audioPolicy = headsetService.getHfpCallAudioPolicy(device);
            if (audioPolicy != null && audioPolicy.getActiveDevicePolicyAfterConnection()
        if (audioPolicy != null
                && audioPolicy.getActiveDevicePolicyAfterConnection()
                        == BluetoothSinkAudioPolicy.POLICY_NOT_ALLOWED) {
            return false;
        }
        if (!headsetService.setActiveDevice(device)) {
            return false;
        }
        synchronized (mLock) {
            mHfpActiveDevice = device;
        }
        return true;
@@ -923,7 +930,6 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac
            Log.d(TAG, "setLeAudioActiveDevice(" + device + ")"
                    + (device == null ? " hasFallbackDevice=" + hasFallbackDevice : ""));
        }
        synchronized (mLock) {
        final LeAudioService leAudioService = mFactory.getLeAudioService();
        if (leAudioService == null) {
            return false;
@@ -939,6 +945,7 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac
            return false;
        }

        synchronized (mLock) {
            mLeAudioActiveDevice = device;
            if (device == null) {
                mLeHearingAidActiveDevice = null;
+1 −1
Original line number Diff line number Diff line
@@ -1339,12 +1339,12 @@ public class HeadsetService extends ProfileService {
     * Remove the active device
     */
    private void removeActiveDevice() {
        BluetoothDevice fallbackDevice = mActiveDeviceManager.getHfpFallbackDevice();
        synchronized (mStateMachines) {
            // As per b/202602952, if we remove the active device due to a disconnection,
            // we need to check if another device is connected and set it active instead.
            // Calling this before any other active related calls has the same effect as
            // a classic active device switch.
            BluetoothDevice fallbackDevice = mActiveDeviceManager.getHfpFallbackDevice();
            if (fallbackDevice != null && mActiveDevice != null
                    && getConnectionState(mActiveDevice) != BluetoothProfile.STATE_CONNECTED) {
                setActiveDevice(fallbackDevice);