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

Commit 26c305ad authored by Jean-Michel Trivi's avatar Jean-Michel Trivi Committed by Atneya Nair
Browse files

RESTRICT AUTOMERGE AudioService: handle BT profile disconnections

The BT A2DP, LE and HearingAid proxies to the BT service were
 initialized on profile connection, but were never reset on
 profile disconnection in BtHelper.
Wrapped the calls to the BT proxies with try/catch as the
 notification that a profile disconnected can happen while
 the proxy is used.

Bug: 269238085
Bug: 265815315
Test: BT crash case in bug
Change-Id: I77443a8b3afe8fd386401111e73f388e03510adb
(cherry picked from commit af9b9670)
parent d5c1876b
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1567,6 +1567,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
                case MSG_I_BT_SERVICE_DISCONNECTED_PROFILE:
                    if (msg.arg1 != BluetoothProfile.HEADSET) {
                        synchronized (mDeviceStateLock) {
                            mBtHelper.onBtProfileDisconnected(msg.arg1);
                            mDeviceInventory.onBtProfileDisconnected(msg.arg1);
                        }
                    } else {
+62 −8
Original line number Diff line number Diff line
@@ -278,7 +278,11 @@ public class BtHelper {
        }
        AudioService.sVolumeLogger.enqueue(new AudioServiceEvents.VolumeEvent(
                AudioServiceEvents.VolumeEvent.VOL_SET_AVRCP_VOL, index));
        try {
            mA2dp.setAvrcpAbsoluteVolume(index);
        } catch (Exception e) {
            Log.e(TAG, "Exception while changing abs volume", e);
        }
    }

    /*package*/ synchronized @AudioSystem.AudioFormatNativeEnumForBtCodec int getA2dpCodec(
@@ -286,7 +290,12 @@ public class BtHelper {
        if (mA2dp == null) {
            return AudioSystem.AUDIO_FORMAT_DEFAULT;
        }
        final BluetoothCodecStatus btCodecStatus = mA2dp.getCodecStatus(device);
        BluetoothCodecStatus btCodecStatus = null;
        try {
            btCodecStatus = mA2dp.getCodecStatus(device);
        } catch (Exception e) {
            Log.e(TAG, "Exception while getting status of " + device, e);
        }
        if (btCodecStatus == null) {
            return AudioSystem.AUDIO_FORMAT_DEFAULT;
        }
@@ -420,7 +429,11 @@ public class BtHelper {
        }
        AudioService.sVolumeLogger.enqueue(new AudioServiceEvents.VolumeEvent(
                AudioServiceEvents.VolumeEvent.VOL_SET_LE_AUDIO_VOL, index, maxIndex));
        try {
            mLeAudio.setVolume(volume);
        } catch (Exception e) {
            Log.e(TAG, "Exception while setting LE volume", e);
        }
    }

    /*package*/ synchronized void setHearingAidVolume(int index, int streamType,
@@ -446,7 +459,11 @@ public class BtHelper {
            AudioService.sVolumeLogger.enqueue(new AudioServiceEvents.VolumeEvent(
                    AudioServiceEvents.VolumeEvent.VOL_SET_HEARING_AID_VOL, index, gainDB));
        }
        try {
            mHearingAid.setVolume(gainDB);
        } catch (Exception e) {
            Log.i(TAG, "Exception while setting hearing aid volume", e);
        }
    }

    /*package*/ synchronized void onBroadcastScoConnectionState(int state) {
@@ -471,7 +488,7 @@ public class BtHelper {
    }

    // @GuardedBy("AudioDeviceBroker.mSetModeLock")
    @GuardedBy("AudioDeviceBroker.mDeviceStateLock")
    //@GuardedBy("AudioDeviceBroker.mDeviceStateLock")
    /*package*/ synchronized void resetBluetoothSco() {
        mScoAudioState = SCO_STATE_INACTIVE;
        broadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_DISCONNECTED);
@@ -486,6 +503,35 @@ public class BtHelper {
        mBluetoothHeadset = null;
    }

    //@GuardedBy("AudioDeviceBroker.mDeviceStateLock")
    /*package*/ synchronized void onBtProfileDisconnected(int profile) {
        switch (profile) {
            case BluetoothProfile.A2DP:
                mA2dp = null;
                break;
            case BluetoothProfile.HEARING_AID:
                mHearingAid = null;
                break;
            case BluetoothProfile.LE_AUDIO:
                mLeAudio = null;
                break;

            case BluetoothProfile.A2DP_SINK:
            case BluetoothProfile.LE_AUDIO_BROADCAST:
                // shouldn't be received here as profile doesn't involve BtHelper
                Log.e(TAG, "onBtProfileDisconnected: Not a profile handled by BtHelper "
                        + BluetoothProfile.getProfileName(profile));
                break;

            default:
                // Not a valid profile to disconnect
                Log.e(TAG, "onBtProfileDisconnected: Not a valid profile to disconnect "
                        + BluetoothProfile.getProfileName(profile));
                break;
        }
    }

    @GuardedBy("AudioDeviceBroker.mDeviceStateLock")
    /*package*/ synchronized void onBtProfileConnected(int profile, BluetoothProfile proxy) {
        if (profile == BluetoothProfile.HEADSET) {
            onHeadsetProfileConnected((BluetoothHeadset) proxy);
@@ -671,7 +717,6 @@ public class BtHelper {
                public void onServiceConnected(int profile, BluetoothProfile proxy) {
                    switch(profile) {
                        case BluetoothProfile.A2DP:
                        case BluetoothProfile.A2DP_SINK:
                        case BluetoothProfile.HEADSET:
                        case BluetoothProfile.HEARING_AID:
                        case BluetoothProfile.LE_AUDIO:
@@ -681,6 +726,10 @@ public class BtHelper {
                            mDeviceBroker.postBtProfileConnected(profile, proxy);
                            break;

                        case BluetoothProfile.A2DP_SINK:
                            // no A2DP sink functionality handled by BtHelper
                        case BluetoothProfile.LE_AUDIO_BROADCAST:
                            // no broadcast functionality handled by BtHelper
                        default:
                            break;
                    }
@@ -689,14 +738,19 @@ public class BtHelper {

                    switch (profile) {
                        case BluetoothProfile.A2DP:
                        case BluetoothProfile.A2DP_SINK:
                        case BluetoothProfile.HEADSET:
                        case BluetoothProfile.HEARING_AID:
                        case BluetoothProfile.LE_AUDIO:
                        case BluetoothProfile.LE_AUDIO_BROADCAST:
                            AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent(
                                    "BT profile service: disconnecting "
                                        + BluetoothProfile.getProfileName(profile) + " profile"));
                            mDeviceBroker.postBtProfileDisconnected(profile);
                            break;

                        case BluetoothProfile.A2DP_SINK:
                            // no A2DP sink functionality handled by BtHelper
                        case BluetoothProfile.LE_AUDIO_BROADCAST:
                            // no broadcast functionality handled by BtHelper
                        default:
                            break;
                    }