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

Commit d77befba authored by Eric Laurent's avatar Eric Laurent Committed by Jakub Pawlowski
Browse files

audio policy: default routing rules for BLE audio devices

Add default audio routing rules for BLE audio devices in audio
policy manager engine.

Also remove isA2dpSupported() helper: checking if a2dp is supported
before selecting an A2DP device is redundant as the device connection
would have been rejected in the first place if A2DP was not supported.

The implementation for communication use cases is not final until a new API is
added to control routing to BLE audio similarly to what exists for
Bluetooth SCO or speakerphone.

Bug: 161358428
Test: regression on audio playback and capture routing, especially with
hearing aid, Bluetooth A2DP and Bluetooth SCO.

Change-Id: If07150dc4495aeee5e796d891fd3ce98965bf5f9
Merged-In: If07150dc4495aeee5e796d891fd3ce98965bf5f9
parent 80cd5274
Loading
Loading
Loading
Loading
+0 −5
Original line number Diff line number Diff line
@@ -498,11 +498,6 @@ public:
     */
    bool isA2dpOffloadedOnPrimary() const;

    /**
     * returns true if A2DP is supported (either via hardware offload or software encoding)
     */
    bool isA2dpSupported() const;

    sp<SwAudioOutputDescriptor> getOutputFromId(audio_port_handle_t id) const;

    sp<SwAudioOutputDescriptor> getPrimaryOutput() const;
+0 −5
Original line number Diff line number Diff line
@@ -764,11 +764,6 @@ bool SwAudioOutputCollection::isA2dpOffloadedOnPrimary() const
    return false;
}

bool SwAudioOutputCollection::isA2dpSupported() const
{
    return (isA2dpOffloadedOnPrimary() || (getA2dpOutput() != 0));
}

sp<SwAudioOutputDescriptor> SwAudioOutputCollection::getPrimaryOutput() const
{
    for (size_t i = 0; i < size(); i++) {
+5 −0
Original line number Diff line number Diff line
@@ -69,6 +69,11 @@ device_out_group_t LastRemovableMediaDevices::getDeviceOutGroup(audio_devices_t
    case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP:
    case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES:
    case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER:
    // TODO (b/122931261): remove when preferred device for strategy media will be used instead of
    //  AUDIO_POLICY_FORCE_NO_BT_A2DP.
    case AUDIO_DEVICE_OUT_HEARING_AID:
    case AUDIO_DEVICE_OUT_BLE_HEADSET:
    case AUDIO_DEVICE_OUT_BLE_SPEAKER:
        return GROUP_BT_A2DP;
    default:
        return GROUP_NONE;
+29 −19
Original line number Diff line number Diff line
@@ -241,10 +241,15 @@ DeviceVector Engine::getDevicesForStrategyInt(legacy_strategy strategy,
        default:    // FORCE_NONE
            devices = availableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_HEARING_AID);
            if (!devices.isEmpty()) break;

            // TODO (b/161358428): remove when preferred device
            //  for strategy phone will be used instead of AUDIO_POLICY_FORCE_FOR_COMMUNICATION
            devices = availableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_BLE_HEADSET);
            if (!devices.isEmpty()) break;

            // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP
            if (!isInCall() &&
                    (getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
                     outputs.isA2dpSupported()) {
                    (getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) != AUDIO_POLICY_FORCE_NO_BT_A2DP)) {
                devices = availableOutputDevices.getFirstDevicesFromTypes({
                        AUDIO_DEVICE_OUT_BLUETOOTH_A2DP,
                        AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES});
@@ -267,13 +272,17 @@ DeviceVector Engine::getDevicesForStrategyInt(legacy_strategy strategy,
        case AUDIO_POLICY_FORCE_SPEAKER:
            // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to
            // A2DP speaker when forcing to speaker output
            if (!isInCall() &&
                    (getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
                     outputs.isA2dpSupported()) {
            if (!isInCall()) {
                devices = availableOutputDevices.getDevicesFromType(
                        AUDIO_DEVICE_OUT_BLE_SPEAKER);
                if (!devices.isEmpty()) break;

                if ((getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) != AUDIO_POLICY_FORCE_NO_BT_A2DP)) {
                    devices = availableOutputDevices.getDevicesFromType(
                            AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER);
                    if (!devices.isEmpty()) break;
                }
            }
            if (!isInCall()) {
                devices = availableOutputDevices.getFirstDevicesFromTypes({
                        AUDIO_DEVICE_OUT_USB_ACCESSORY, AUDIO_DEVICE_OUT_USB_DEVICE,
@@ -386,18 +395,13 @@ DeviceVector Engine::getDevicesForStrategyInt(legacy_strategy strategy,
                    STRATEGY_PHONE, availableOutputDevices, availableInputDevices, outputs);
            break;
        }
        // FIXME: Find a better solution to prevent routing to BT hearing aid(b/122931261).
        if ((devices2.isEmpty()) &&
                (getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) != AUDIO_POLICY_FORCE_NO_BT_A2DP)) {
            devices2 = availableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_HEARING_AID);
        }

        if ((devices2.isEmpty()) &&
            (getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) == AUDIO_POLICY_FORCE_SPEAKER)) {
            devices2 = availableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_SPEAKER);
        }
        if (devices2.isEmpty() && (getLastRemovableMediaDevices().size() > 0)) {
            if ((getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
                    outputs.isA2dpSupported()) {
            if ((getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) != AUDIO_POLICY_FORCE_NO_BT_A2DP)) {
                // Get the last connected device of wired and bluetooth a2dp
                devices2 = availableOutputDevices.getFirstDevicesFromTypes(
                        getLastRemovableMediaDevices());
@@ -514,8 +518,9 @@ sp<DeviceDescriptor> Engine::getDeviceForInputSource(audio_source_t inputSource)
            if (device != nullptr) break;
        }
        device = availableDevices.getFirstExistingDevice({
                AUDIO_DEVICE_IN_WIRED_HEADSET, AUDIO_DEVICE_IN_USB_HEADSET,
                AUDIO_DEVICE_IN_USB_DEVICE, AUDIO_DEVICE_IN_BUILTIN_MIC});
                AUDIO_DEVICE_IN_BLE_HEADSET, AUDIO_DEVICE_IN_WIRED_HEADSET,
                AUDIO_DEVICE_IN_USB_HEADSET, AUDIO_DEVICE_IN_USB_DEVICE,
                AUDIO_DEVICE_IN_BUILTIN_MIC});
        break;

    case AUDIO_SOURCE_VOICE_COMMUNICATION:
@@ -539,9 +544,13 @@ sp<DeviceDescriptor> Engine::getDeviceForInputSource(audio_source_t inputSource)
            FALLTHROUGH_INTENDED;

        default:    // FORCE_NONE
            // TODO (b/161358428): remove AUDIO_DEVICE_IN_BLE_HEADSET from the list
            //  when preferred device for strategy phone will be used instead of
            //  AUDIO_POLICY_FORCE_FOR_COMMUNICATION.
            device = availableDevices.getFirstExistingDevice({
                    AUDIO_DEVICE_IN_WIRED_HEADSET, AUDIO_DEVICE_IN_USB_HEADSET,
                    AUDIO_DEVICE_IN_USB_DEVICE, AUDIO_DEVICE_IN_BUILTIN_MIC});
                    AUDIO_DEVICE_IN_BLE_HEADSET, AUDIO_DEVICE_IN_WIRED_HEADSET,
                    AUDIO_DEVICE_IN_USB_HEADSET, AUDIO_DEVICE_IN_USB_DEVICE,
                    AUDIO_DEVICE_IN_BUILTIN_MIC});
            break;

        case AUDIO_POLICY_FORCE_SPEAKER:
@@ -566,8 +575,9 @@ sp<DeviceDescriptor> Engine::getDeviceForInputSource(audio_source_t inputSource)
            if (device != nullptr) break;
        }
        device = availableDevices.getFirstExistingDevice({
                AUDIO_DEVICE_IN_WIRED_HEADSET, AUDIO_DEVICE_IN_USB_HEADSET,
                AUDIO_DEVICE_IN_USB_DEVICE, AUDIO_DEVICE_IN_BUILTIN_MIC});
                AUDIO_DEVICE_IN_BLE_HEADSET, AUDIO_DEVICE_IN_WIRED_HEADSET,
                AUDIO_DEVICE_IN_USB_HEADSET, AUDIO_DEVICE_IN_USB_DEVICE,
                AUDIO_DEVICE_IN_BUILTIN_MIC});
        break;
    case AUDIO_SOURCE_CAMCORDER:
        // For a device without built-in mic, adding usb device