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

Commit 2802b869 authored by Eric Laurent's avatar Eric Laurent
Browse files

audio policy: fix STRATEGY_PHONE routing when not in call

commit 2517af3e unintentionaly mapped STRATEGY_PHONE to
STRATEGY_MEDIA when not in call. This mapping is only for
STRATEGY_DTMF.

Also group filtering of available output devices according to
strategy in a helper method and apply the filter also before
checking for preferred devices for a given strategy.

Bug: 179642678
Test: atest AudioCommunicationDeviceTest
Change-Id: Ia47b81ee6aff9a49a83f40870eb811b493141f5b
parent 4c8abb48
Loading
Loading
Loading
Loading
+71 −47
Original line number Diff line number Diff line
@@ -142,6 +142,68 @@ status_t Engine::setForceUse(audio_policy_force_use_t usage, audio_policy_forced
    return EngineBase::setForceUse(usage, config);
}

void Engine::filterOutputDevicesForStrategy(legacy_strategy strategy,
                                            DeviceVector& availableOutputDevices,
                                            const DeviceVector availableInputDevices,
                                            const SwAudioOutputCollection &outputs) const
{
    switch (strategy) {
    case STRATEGY_SONIFICATION_RESPECTFUL: {
        if (!(isInCall() || outputs.isActiveLocally(toVolumeSource(AUDIO_STREAM_VOICE_CALL)))) {
            // routing is same as media without the "remote" device
            availableOutputDevices.remove(availableOutputDevices.getDevicesFromType(
                    AUDIO_DEVICE_OUT_REMOTE_SUBMIX));
        }
        } break;
    case STRATEGY_DTMF:
    case STRATEGY_PHONE: {
        // Force use of only devices on primary output if:
        // - in call AND
        //   - cannot route from voice call RX OR
        //   - audio HAL version is < 3.0 and TX device is on the primary HW module
        if (getPhoneState() == AUDIO_MODE_IN_CALL) {
            audio_devices_t txDevice = getDeviceForInputSource(
                    AUDIO_SOURCE_VOICE_COMMUNICATION)->type();
            sp<AudioOutputDescriptor> primaryOutput = outputs.getPrimaryOutput();
            LOG_ALWAYS_FATAL_IF(primaryOutput == nullptr, "Primary output not found");
            DeviceVector availPrimaryInputDevices =
                    availableInputDevices.getDevicesFromHwModule(primaryOutput->getModuleHandle());

            // TODO: getPrimaryOutput return only devices from first module in
            // audio_policy_configuration.xml, hearing aid is not there, but it's
            // a primary device
            // FIXME: this is not the right way of solving this problem
            DeviceVector availPrimaryOutputDevices = availableOutputDevices.getDevicesFromTypes(
                    primaryOutput->supportedDevices().types());
            availPrimaryOutputDevices.add(
                    availableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_HEARING_AID));

            if ((availableInputDevices.getDevice(AUDIO_DEVICE_IN_TELEPHONY_RX,
                                                 String8(""), AUDIO_FORMAT_DEFAULT) == nullptr) ||
                ((availPrimaryInputDevices.getDevice(
                        txDevice, String8(""), AUDIO_FORMAT_DEFAULT) != nullptr) &&
                 (primaryOutput->getPolicyAudioPort()->getModuleVersionMajor() < 3))) {
                availableOutputDevices = availPrimaryOutputDevices;
            }
        }
        } break;
    case STRATEGY_ACCESSIBILITY: {
        // do not route accessibility prompts to a digital output currently configured with a
        // compressed format as they would likely not be mixed and dropped.
        for (size_t i = 0; i < outputs.size(); i++) {
            sp<AudioOutputDescriptor> desc = outputs.valueAt(i);
            if (desc->isActive() && !audio_is_linear_pcm(desc->getFormat())) {
                availableOutputDevices.remove(desc->devices().getDevicesFromTypes({
                        AUDIO_DEVICE_OUT_HDMI, AUDIO_DEVICE_OUT_SPDIF,
                        AUDIO_DEVICE_OUT_HDMI_ARC}));
            }
        }
        } break;
    default:
        break;
    }
}

DeviceVector Engine::getDevicesForStrategyInt(legacy_strategy strategy,
                                              DeviceVector availableOutputDevices,
                                              DeviceVector availableInputDevices,
@@ -166,9 +228,6 @@ DeviceVector Engine::getDevicesForStrategyInt(legacy_strategy strategy,
                    || outputs.isActiveLocally(
                        toVolumeSource(AUDIO_STREAM_ACCESSIBILITY),
                        SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY);
            // routing is same as media without the "remote" device
            availableOutputDevices.remove(availableOutputDevices.getDevicesFromType(
                    AUDIO_DEVICE_OUT_REMOTE_SUBMIX));
            devices = getDevicesForStrategyInt(STRATEGY_MEDIA,
                    availableOutputDevices,
                    availableInputDevices, outputs);
@@ -185,35 +244,6 @@ DeviceVector Engine::getDevicesForStrategyInt(legacy_strategy strategy,

    case STRATEGY_DTMF:
    case STRATEGY_PHONE: {
        // Force use of only devices on primary output if:
        // - in call AND
        //   - cannot route from voice call RX OR
        //   - audio HAL version is < 3.0 and TX device is on the primary HW module
        if (getPhoneState() == AUDIO_MODE_IN_CALL) {
            audio_devices_t txDevice = getDeviceForInputSource(
                    AUDIO_SOURCE_VOICE_COMMUNICATION)->type();
            sp<AudioOutputDescriptor> primaryOutput = outputs.getPrimaryOutput();
            LOG_ALWAYS_FATAL_IF(primaryOutput == nullptr, "Primary output not found");
            DeviceVector availPrimaryInputDevices =
                    availableInputDevices.getDevicesFromHwModule(primaryOutput->getModuleHandle());

            // TODO: getPrimaryOutput return only devices from first module in
            // audio_policy_configuration.xml, hearing aid is not there, but it's
            // a primary device
            // FIXME: this is not the right way of solving this problem
            DeviceVector availPrimaryOutputDevices = availableOutputDevices.getDevicesFromTypes(
                    primaryOutput->supportedDevices().types());
            availPrimaryOutputDevices.add(
                    availableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_HEARING_AID));

            if ((availableInputDevices.getDevice(AUDIO_DEVICE_IN_TELEPHONY_RX,
                                                 String8(""), AUDIO_FORMAT_DEFAULT) == nullptr) ||
                ((availPrimaryInputDevices.getDevice(
                        txDevice, String8(""), AUDIO_FORMAT_DEFAULT) != nullptr) &&
                 (primaryOutput->getPolicyAudioPort()->getModuleVersionMajor() < 3))) {
                availableOutputDevices = availPrimaryOutputDevices;
            }
        }
        devices = availableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_HEARING_AID);
        if (!devices.isEmpty()) break;
        devices = availableOutputDevices.getFirstDevicesFromTypes({
@@ -286,16 +316,6 @@ DeviceVector Engine::getDevicesForStrategyInt(legacy_strategy strategy,

    case STRATEGY_ACCESSIBILITY:
        if (strategy == STRATEGY_ACCESSIBILITY) {
            // do not route accessibility prompts to a digital output currently configured with a
            // compressed format as they would likely not be mixed and dropped.
            for (size_t i = 0; i < outputs.size(); i++) {
                sp<AudioOutputDescriptor> desc = outputs.valueAt(i);
                if (desc->isActive() && !audio_is_linear_pcm(desc->getFormat())) {
                    availableOutputDevices.remove(desc->devices().getDevicesFromTypes({
                            AUDIO_DEVICE_OUT_HDMI, AUDIO_DEVICE_OUT_SPDIF,
                            AUDIO_DEVICE_OUT_HDMI_ARC}));
                }
            }
            if (outputs.isActive(toVolumeSource(AUDIO_STREAM_RING)) ||
                    outputs.isActive(toVolumeSource(AUDIO_STREAM_ALARM))) {
                return getDevicesForStrategyInt(
@@ -634,11 +654,18 @@ DeviceVector Engine::getDevicesForProductStrategy(product_strategy_t strategy) c
    auto legacyStrategy = mLegacyStrategyMap.find(strategy) != end(mLegacyStrategyMap) ?
                          mLegacyStrategyMap.at(strategy) : STRATEGY_NONE;

    // When not in call, STRATEGY_PHONE and STRATEGY_DTMF follow STRATEGY_MEDIA
    if (!isInCall() && (legacyStrategy == STRATEGY_PHONE || legacyStrategy == STRATEGY_DTMF)) {
    // When not in call, STRATEGY_DTMF follows STRATEGY_MEDIA
    if (!isInCall() && legacyStrategy == STRATEGY_DTMF) {
        legacyStrategy = STRATEGY_MEDIA;
        strategy = getProductStrategyFromLegacy(STRATEGY_MEDIA);
    }

    DeviceVector availableInputDevices = getApmObserver()->getAvailableInputDevices();
    const SwAudioOutputCollection& outputs = getApmObserver()->getOutputs();

    filterOutputDevicesForStrategy(legacyStrategy, availableOutputDevices,
                                   availableInputDevices, outputs);

    // check if this strategy has a preferred device that is available,
    // if yes, give priority to it.
    DeviceVector preferredAvailableDevVec =
@@ -647,9 +674,6 @@ DeviceVector Engine::getDevicesForProductStrategy(product_strategy_t strategy) c
        return preferredAvailableDevVec;
    }

    DeviceVector availableInputDevices = getApmObserver()->getAvailableInputDevices();
    const SwAudioOutputCollection& outputs = getApmObserver()->getOutputs();

    return getDevicesForStrategyInt(legacyStrategy,
                                    availableOutputDevices,
                                    availableInputDevices, outputs);
+5 −0
Original line number Diff line number Diff line
@@ -74,6 +74,11 @@ private:

    status_t setDefaultDevice(audio_devices_t device);

    void filterOutputDevicesForStrategy(legacy_strategy strategy,
                                            DeviceVector& availableOutputDevices,
                                            const DeviceVector availableInputDevices,
                                            const SwAudioOutputCollection &outputs) const;

    DeviceVector getDevicesForStrategyInt(legacy_strategy strategy,
                                          DeviceVector availableOutputDevices,
                                          DeviceVector availableInputDevices,