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

Commit fa3e4e43 authored by Eric Laurent's avatar Eric Laurent
Browse files

AudioDeviceBroker: mute call when switching LE Audio device

When a Bluetooth LE Audio device is disconnected as part of a device switch,
mute call until LE Audio is selected for call or a 2 second timeout happens.

Bug: 414444196
Test: repro steps in bug
Flag: com.android.media.audio.optimize_bt_device_switch
Change-Id: I6c257e1b451358b68ce1a6228dedc8d1a0974fb9
parent 8bfe8a87
Loading
Loading
Loading
Loading
+22 −3
Original line number Diff line number Diff line
@@ -124,8 +124,8 @@ public class AudioDeviceBroker {
    // Delay before checking it music should be unmuted after processing an A2DP message
    private static final int BTA2DP_MUTE_CHECK_DELAY_MS = 200;

    // Delay before unmuting call after HFP device switch
    private static final int HFP_SWITCH_CALL_UNMUTE_DELAY_MS = 2000;
    // Delay before unmuting call after HFP or LE Audio device switch
    private static final int HS_SWITCH_CALL_UNMUTE_DELAY_MS = 2000;

    private final @NonNull AudioService mAudioService;
    private final @NonNull Context mContext;
@@ -319,7 +319,7 @@ public class AudioDeviceBroker {
        if (deviceSwitch && isBluetoothScoActive()) {
            mAudioService.setCallMute(true);
            sendIMsg(MSG_I_MUTE_CALL, SENDMSG_REPLACE,
                    0 /*unmute*/, HFP_SWITCH_CALL_UNMUTE_DELAY_MS);
                    0 /*unmute*/, HS_SWITCH_CALL_UNMUTE_DELAY_MS);
        } else if (btDevice == null) {
            sendIMsg(MSG_I_MUTE_CALL, SENDMSG_REPLACE,
                    0 /*unmute*/, 0 /*delay */);
@@ -1553,6 +1553,15 @@ public class AudioDeviceBroker {
    }

    /*package*/ void postBluetoothActiveDevice(BtDeviceInfo info, int delay) {
        if (info.mProfile == BluetoothProfile.LE_AUDIO
                && info.mState == BluetoothProfile.STATE_DISCONNECTED
                && info.mIsDeviceSwitch
                && isBluetoothLeAudioRequested()) {
            sendIMsg(MSG_I_MUTE_CALL, SENDMSG_REPLACE,
                    1 /*mute*/, delay);
            sendIMsg(MSG_I_MUTE_CALL, SENDMSG_QUEUE,
                    0 /*unmute*/, delay + HS_SWITCH_CALL_UNMUTE_DELAY_MS);
        }
        sendLMsg(MSG_L_SET_BT_ACTIVE_DEVICE, SENDMSG_QUEUE, info, delay);
    }

@@ -2610,6 +2619,7 @@ public class AudioDeviceBroker {
                    + ((mCommunicationStrategyId == -1)
                            ? "failure" : "success"))).printLog(ALOGW, TAG));
        }
        AudioDeviceAttributes appliedCommunicationDevice = null;
        if (preferredCommunicationDevice == null) {
            AudioDeviceAttributes defaultDevice = getDefaultCommunicationDevice();
            if (defaultDevice != null) {
@@ -2623,13 +2633,22 @@ public class AudioDeviceBroker {
            }
            mDeviceInventory.applyConnectedDevicesRoles();
            mDeviceInventory.reapplyExternalDevicesRoles();
            appliedCommunicationDevice = defaultDevice;
        } else {
            mDeviceInventory.setPreferredDevicesForStrategyInt(
                    mCommunicationStrategyId, Arrays.asList(preferredCommunicationDevice));
            mDeviceInventory.setPreferredDevicesForStrategyInt(
                    mAccessibilityStrategyId, Arrays.asList(preferredCommunicationDevice));
            appliedCommunicationDevice = preferredCommunicationDevice;
        }
        onUpdatePhoneStrategyDevice(preferredCommunicationDevice);


        if (appliedCommunicationDevice != null && AudioSystem.isBluetoothLeOutDevice(
                appliedCommunicationDevice.getInternalType())) {
            sendIMsg(MSG_I_MUTE_CALL, SENDMSG_REPLACE,
                    0 /*unmute*/, 0 /*delay */);
        }
    }

    // Pairs of input and output devices for duplex communication devices (headsets)
+7 −4
Original line number Diff line number Diff line
@@ -993,6 +993,7 @@ public class AudioDeviceInventory {

        int deviceType = BtHelper.getTypeFromProfile(btInfo.mProfile, btInfo.mIsLeOutput);

        boolean disconnectDevice = false;
        synchronized (mDevicesLock) {
            if (mDeviceBroker.hasScheduledA2dpConnection(btDevice, btInfo.mProfile)) {
                AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent(
@@ -1034,8 +1035,7 @@ public class AudioDeviceInventory {

                            // force A2DP device disconnection in case of error so that AudioService
                            // state is consistent with audio policy manager state
                            setBluetoothActiveDevice(new AudioDeviceBroker.BtDeviceInfo(btInfo,
                                    BluetoothProfile.STATE_DISCONNECTED));
                            disconnectDevice = true;
                        } else {
                            AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent(
                                    "APM handleDeviceConfigChange success for device addr="
@@ -1051,6 +1051,10 @@ public class AudioDeviceInventory {
                }
            }
        }
        if (disconnectDevice) {
            setBluetoothActiveDevice(new AudioDeviceBroker.BtDeviceInfo(btInfo,
                    BluetoothProfile.STATE_DISCONNECTED));
        }
        mmi.record();
        return delayMs;
    }
@@ -2086,12 +2090,11 @@ public class AudioDeviceInventory {
            } else {
                delay = 0;
            }

            if (AudioService.DEBUG_DEVICES) {
                Log.i(TAG, "setBluetoothActiveDevice " + info.toString() + " delay(ms): " + delay);
            }
            mDeviceBroker.postBluetoothActiveDevice(info, delay);
        }
        mDeviceBroker.postBluetoothActiveDevice(info, delay);
        return delay;
    }