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

Commit a807ef99 authored by François Gaffie's avatar François Gaffie Committed by Eric Laurent
Browse files

audiopolicy: apm: Fix default bus device issue



When a bus device is used as default, when calling setForceUse,
a given SwOutputDescriptor might be asked to switch to another
bus device (the default), violating the Policy Mix rule.

Test: see below
 -start an automotive device with PolicyMix registered and
  bus device as the default.
 -Consider having a system bus for system sound and media for music.
 -Play touch sound (check played in system bus).
 -launch music player.

Result:
 -Music shall be played on media bus device
 -Touch sound still played on system bus device

Change-Id: I6668cffa525af51af6ed0838745658f72ae00a62
Signed-off-by: default avatarFrançois Gaffie <francois.gaffie@renault.com>
parent 9eb18550
Loading
Loading
Loading
Loading
+15 −2
Original line number Diff line number Diff line
@@ -23,9 +23,10 @@
#include <system/audio.h>
#include <utils/String8.h>

namespace android {
#include <DeviceDescriptor.h>
#include <AudioOutputDescriptor.h>

class SwAudioOutputDescriptor;
namespace android {

/**
 * custom mix entry in mPolicyMixes
@@ -79,6 +80,18 @@ public:
                                                       const DeviceVector &availableDeviceTypes,
                                                       AudioMix **policyMix);

    /**
     * @brief try to find a matching mix for a given output descriptor and returns the associated
     * output device.
     * @param output to be considered
     * @param availableOutputDevices list of output devices currently reachable
     * @param policyMix to be returned if any mix matching ouput descriptor
     * @return device selected from the mix attached to the output, null pointer otherwise
     */
    sp<DeviceDescriptor> getDeviceAndMixForOutput(const sp<SwAudioOutputDescriptor> &output,
                                                  const DeviceVector &availableOutputDevices,
                                                  AudioMix **policyMix = nullptr);

    status_t getInputMixForAttr(audio_attributes_t attr, AudioMix **policyMix);

    status_t setUidDeviceAffinities(uid_t uid, const Vector<AudioDeviceTypeAddr>& devices);
+21 −0
Original line number Diff line number Diff line
@@ -280,6 +280,27 @@ status_t AudioPolicyMixCollection::getOutputForAttr(audio_attributes_t attribute
    return BAD_VALUE;
}

sp<DeviceDescriptor> AudioPolicyMixCollection::getDeviceAndMixForOutput(
        const sp<SwAudioOutputDescriptor> &output,
        const DeviceVector &availableOutputDevices,
        AudioMix **policyMix)
{
    for (size_t i = 0; i < size(); i++) {
        if (valueAt(i)->getOutput() == output) {
            AudioMix *mix = valueAt(i)->getMix();
            if (policyMix != nullptr)
                *policyMix = mix;
            // This Desc is involved in a Mix, which has the highest prio
            audio_devices_t deviceType = mix->mDeviceType;
            String8 address = mix->mDeviceAddress;
            ALOGV("%s: device (0x%x, addr=%s) forced by mix",
                  __FUNCTION__, deviceType, address.c_str());
            return availableOutputDevices.getDevice(deviceType, address, AUDIO_FORMAT_DEFAULT);
        }
    }
    return nullptr;
}

sp<DeviceDescriptor> AudioPolicyMixCollection::getDeviceAndMixForInputSource(
        audio_source_t inputSource, const DeviceVector &availDevices, AudioMix **policyMix)
{
+10 −0
Original line number Diff line number Diff line
@@ -790,6 +790,9 @@ void AudioPolicyManager::setForceUse(audio_policy_force_use_t usage,
        sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueAt(i);
        DeviceVector newDevices = getNewOutputDevices(outputDesc, true /*fromCache*/);
        if ((mEngine->getPhoneState() != AUDIO_MODE_IN_CALL) || (outputDesc != mPrimaryOutput)) {
            // As done in setDeviceConnectionState, we could also fix default device issue by
            // preventing the force re-routing in case of default dev that distinguishes on address.
            // Let's give back to engine full device choice decision however.
            waitMs = setOutputDevices(outputDesc, newDevices, !newDevices.isEmpty(), delayMs);
        }
        if (forceVolumeReeval && !newDevices.isEmpty()) {
@@ -4969,6 +4972,13 @@ DeviceVector AudioPolicyManager::getNewOutputDevices(const sp<SwAudioOutputDescr
        return DeviceVector(device);
    }

    // Legacy Engine cannot take care of bus devices and mix, so we need to handle the conflict
    // of setForceUse / Default Bus device here
    device = mPolicyMixes.getDeviceAndMixForOutput(outputDesc, mAvailableOutputDevices);
    if (device != nullptr) {
        return DeviceVector(device);
    }

    // check the following by order of priority to request a routing change if necessary:
    // 1: the strategy enforced audible is active and enforced on the output:
    //      use device for strategy enforced audible