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

Commit 85e8a653 authored by Eric Laurent's avatar Eric Laurent
Browse files

Audio Policy: fix media over SCO logic

Fix the A2DP device override in Engine::getDevicesForStrategyInt()
which was ineffective as implemented.
Simplify Engine::isBtScoActive() to only retain the only condition
that matters: SCO is preferred for PHONE strategy.

Bug: 358120583
Bug: 292037886
Test: regression for phone calls over BT
Flag: com.android.media.audioserver.use_bt_sco_for_media
Change-Id: I6dabc2c2c9257ac2ef84593a0bd22b2b1c3b7a8f
parent 3570b809
Loading
Loading
Loading
Loading
+22 −38
Original line number Diff line number Diff line
@@ -156,41 +156,22 @@ status_t Engine::setForceUse(audio_policy_force_use_t usage, audio_policy_forced
    return EngineBase::setForceUse(usage, config);
}

bool Engine::isBtScoActive(DeviceVector& availableOutputDevices,
                           const SwAudioOutputCollection &outputs) const {
bool Engine::isBtScoActive(DeviceVector& availableOutputDevices) const {
    // SCO is considered active if:
    // 1) a SCO device is connected
    // 2) the preferred device for PHONE strategy is BT SCO: this is controlled only by java
    // AudioService and is only true if the SCO audio link as been confirmed active by BT.
    if (availableOutputDevices.getDevicesFromTypes(getAudioDeviceOutAllScoSet()).isEmpty()) {
        return false;
    }
    // SCO is active if:
    // 1) we are in a call and SCO is the preferred device for PHONE strategy
    if (isInCall() && audio_is_bluetooth_out_sco_device(

    if (!audio_is_bluetooth_out_sco_device(
            getPreferredDeviceTypeForLegacyStrategy(availableOutputDevices, STRATEGY_PHONE))) {
        return true;
        return false;
    }

    // 2) A strategy for which the preferred device is SCO is active
    for (const auto &ps : getOrderedProductStrategies()) {
        if (outputs.isStrategyActive(ps) &&
            !getPreferredAvailableDevicesForProductStrategy(availableOutputDevices, ps)
                .getDevicesFromTypes(getAudioDeviceOutAllScoSet()).isEmpty()) {
    return true;
}
    }
    // 3) a ringtone is active and SCO is used for ringing
    if (outputs.isActiveLocally(toVolumeSource(AUDIO_STREAM_RING))
          && (getForceUse(AUDIO_POLICY_FORCE_FOR_VIBRATE_RINGING)
                    == AUDIO_POLICY_FORCE_BT_SCO)) {
        return true;
    }
    // 4) an active input is routed from SCO
    DeviceVector availableInputDevices = getApmObserver()->getAvailableInputDevices();
    const auto &inputs = getApmObserver()->getInputs();
    if (inputs.activeInputsCountOnDevices(availableInputDevices.getDevicesFromType(
            AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET)) > 0) {
        return true;
    }
    return false;
}

void Engine::filterOutputDevicesForStrategy(legacy_strategy strategy,
                                            DeviceVector& availableOutputDevices,
@@ -200,7 +181,7 @@ void Engine::filterOutputDevicesForStrategy(legacy_strategy strategy,

    if (com::android::media::audioserver::use_bt_sco_for_media()) {
        // remove A2DP and LE Audio devices whenever BT SCO is in use
        if (isBtScoActive(availableOutputDevices, outputs)) {
        if (isBtScoActive(availableOutputDevices)) {
            availableOutputDevices.remove(
                availableOutputDevices.getDevicesFromTypes(getAudioDeviceOutAllA2dpSet()));
            availableOutputDevices.remove(
@@ -486,21 +467,24 @@ DeviceVector Engine::getDevicesForStrategyInt(legacy_strategy strategy,
                // Get the last connected device of wired and bluetooth a2dp
                devices2 = availableOutputDevices.getFirstDevicesFromTypes(
                        getLastRemovableMediaDevices(GROUP_NONE, excludedDevices));
            } else {
                // Get the last connected device of wired except bluetooth a2dp
                devices2 = availableOutputDevices.getFirstDevicesFromTypes(
                        getLastRemovableMediaDevices(GROUP_WIRED, excludedDevices));
            }
        }

                if (com::android::media::audioserver::use_bt_sco_for_media()) {
            if (devices2.isEmpty() && isBtScoActive(availableOutputDevices, outputs)) {
                    if (isBtScoActive(availableOutputDevices)
                         && !(devices2.getDevicesFromTypes(
                                 getAudioDeviceOutAllA2dpSet()).isEmpty()
                             && devices2.getDevicesFromTypes(
                                     getAudioDeviceOutAllBleSet()).isEmpty())) {
                        devices2 = availableOutputDevices.getFirstDevicesFromTypes(
                                { AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT,
                                  AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET,
                                  AUDIO_DEVICE_OUT_BLUETOOTH_SCO});
                    }
                }
            } else {
                // Get the last connected device of wired except bluetooth a2dp
                devices2 = availableOutputDevices.getFirstDevicesFromTypes(
                        getLastRemovableMediaDevices(GROUP_WIRED, excludedDevices));
            }
        }

        if ((devices2.isEmpty()) &&
                (getForceUse(AUDIO_POLICY_FORCE_FOR_DOCK) == AUDIO_POLICY_FORCE_ANALOG_DOCK)) {
+1 −2
Original line number Diff line number Diff line
@@ -95,8 +95,7 @@ private:
    DeviceVector getDisabledDevicesForInputSource(
            const DeviceVector& availableInputDevices, audio_source_t inputSource) const;

    bool isBtScoActive(DeviceVector& availableOutputDevices,
                       const SwAudioOutputCollection &outputs) const;
    bool isBtScoActive(DeviceVector& availableOutputDevices) const;

    std::map<product_strategy_t, legacy_strategy> mLegacyStrategyMap;
};