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

Commit dacc06f5 authored by Jean-Michel Trivi's avatar Jean-Michel Trivi
Browse files

Fix AudioPolicyManager dynamic policy initialization

AudioPolicyManager::getInputForAttr() is initializing the AudioMix
 for the new AudioInputDescriptor.
The audio policy manager refactoring introduced a regression where
 the association of an existing AudioMix (registered when the
 associated AudioPolicy was registered) with the input descriptor
 copied a value of local scope, instead of referencing the
 AudioMix in the list of mixes.

Bug 20081375

Change-Id: Iddd57fed8525880afd1d4a5493f97130aabe4816
parent e41b5f31
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -39,7 +39,7 @@ public:

    void clearOutput();

    android::AudioMix &getMix();
    android::AudioMix *getMix();

    void setMix(AudioMix &mix);

@@ -75,7 +75,7 @@ public:
                                                  audio_devices_t availableDeviceTypes,
                                                  AudioMix **policyMix);

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

}; // namespace android
+26 −26
Original line number Diff line number Diff line
@@ -46,9 +46,9 @@ void AudioPolicyMix::setMix(AudioMix &mix)
    mMix = mix;
}

android::AudioMix &AudioPolicyMix::getMix()
android::AudioMix *AudioPolicyMix::getMix()
{
    return mMix;
    return &mMix;
}

status_t AudioPolicyMixCollection::registerMix(String8 address, AudioMix mix)
@@ -103,36 +103,36 @@ status_t AudioPolicyMixCollection::getOutputForAttr(audio_attributes_t attribute
{
    for (size_t i = 0; i < size(); i++) {
        sp<AudioPolicyMix> policyMix = valueAt(i);
        AudioMix mix = policyMix->getMix();

        if (mix.mMixType == MIX_TYPE_PLAYERS) {
            for (size_t j = 0; j < mix.mCriteria.size(); j++) {
                if ((RULE_MATCH_ATTRIBUTE_USAGE == mix.mCriteria[j].mRule &&
                     mix.mCriteria[j].mAttr.mUsage == attributes.usage) ||
                        (RULE_EXCLUDE_ATTRIBUTE_USAGE == mix.mCriteria[j].mRule &&
                         mix.mCriteria[j].mAttr.mUsage != attributes.usage)) {
        AudioMix *mix = policyMix->getMix();

        if (mix->mMixType == MIX_TYPE_PLAYERS) {
            for (size_t j = 0; j < mix->mCriteria.size(); j++) {
                if ((RULE_MATCH_ATTRIBUTE_USAGE == mix->mCriteria[j].mRule &&
                     mix->mCriteria[j].mAttr.mUsage == attributes.usage) ||
                        (RULE_EXCLUDE_ATTRIBUTE_USAGE == mix->mCriteria[j].mRule &&
                         mix->mCriteria[j].mAttr.mUsage != attributes.usage)) {
                    desc = policyMix->getOutput();
                    break;
                }
                if (strncmp(attributes.tags, "addr=", strlen("addr=")) == 0 &&
                        strncmp(attributes.tags + strlen("addr="),
                                mix.mRegistrationId.string(),
                                mix->mRegistrationId.string(),
                                AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - strlen("addr=") - 1) == 0) {
                    desc = policyMix->getOutput();
                    break;
                }
            }
        } else if (mix.mMixType == MIX_TYPE_RECORDERS) {
        } else if (mix->mMixType == MIX_TYPE_RECORDERS) {
            if (attributes.usage == AUDIO_USAGE_VIRTUAL_SOURCE &&
                    strncmp(attributes.tags, "addr=", strlen("addr=")) == 0 &&
                    strncmp(attributes.tags + strlen("addr="),
                            mix.mRegistrationId.string(),
                            mix->mRegistrationId.string(),
                            AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - strlen("addr=") - 1) == 0) {
                desc = policyMix->getOutput();
            }
        }
        if (desc != 0) {
            desc->mPolicyMix = &mix;
            desc->mPolicyMix = mix;
            return NO_ERROR;
        }
    }
@@ -144,19 +144,19 @@ audio_devices_t AudioPolicyMixCollection::getDeviceAndMixForInputSource(audio_so
                                                                        AudioMix **policyMix)
{
    for (size_t i = 0; i < size(); i++) {
        AudioMix mix = valueAt(i)->getMix();
        AudioMix *mix = valueAt(i)->getMix();

        if (mix.mMixType != MIX_TYPE_RECORDERS) {
        if (mix->mMixType != MIX_TYPE_RECORDERS) {
            continue;
        }
        for (size_t j = 0; j < mix.mCriteria.size(); j++) {
            if ((RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET == mix.mCriteria[j].mRule &&
                    mix.mCriteria[j].mAttr.mSource == inputSource) ||
               (RULE_EXCLUDE_ATTRIBUTE_CAPTURE_PRESET == mix.mCriteria[j].mRule &&
                    mix.mCriteria[j].mAttr.mSource != inputSource)) {
        for (size_t j = 0; j < mix->mCriteria.size(); j++) {
            if ((RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET == mix->mCriteria[j].mRule &&
                    mix->mCriteria[j].mAttr.mSource == inputSource) ||
               (RULE_EXCLUDE_ATTRIBUTE_CAPTURE_PRESET == mix->mCriteria[j].mRule &&
                    mix->mCriteria[j].mAttr.mSource != inputSource)) {
                if (availDevices & AUDIO_DEVICE_IN_REMOTE_SUBMIX) {
                    if (policyMix != NULL) {
                        *policyMix = &mix;
                        *policyMix = mix;
                    }
                    return AUDIO_DEVICE_IN_REMOTE_SUBMIX;
                }
@@ -167,7 +167,7 @@ audio_devices_t AudioPolicyMixCollection::getDeviceAndMixForInputSource(audio_so
    return AUDIO_DEVICE_NONE;
}

status_t AudioPolicyMixCollection::getInputMixForAttr(audio_attributes_t attr, AudioMix *&policyMix)
status_t AudioPolicyMixCollection::getInputMixForAttr(audio_attributes_t attr, AudioMix **policyMix)
{
    if (strncmp(attr.tags, "addr=", strlen("addr=")) != 0) {
        return BAD_VALUE;
@@ -180,13 +180,13 @@ status_t AudioPolicyMixCollection::getInputMixForAttr(audio_attributes_t attr, A
        return BAD_VALUE;
    }
    sp<AudioPolicyMix> audioPolicyMix = valueAt(index);
    AudioMix mix = audioPolicyMix->getMix();
    AudioMix *mix = audioPolicyMix->getMix();

    if (mix.mMixType != MIX_TYPE_PLAYERS) {
    if (mix->mMixType != MIX_TYPE_PLAYERS) {
        ALOGW("getInputForAttr() bad policy mix type for address %s", address.string());
        return BAD_VALUE;
    }
    policyMix = &mix;
    *policyMix = mix;
    return NO_ERROR;
}

+3 −3
Original line number Diff line number Diff line
@@ -1189,7 +1189,7 @@ status_t AudioPolicyManager::getInputForAttr(const audio_attributes_t *attr,

    if (inputSource == AUDIO_SOURCE_REMOTE_SUBMIX &&
            strncmp(attr->tags, "addr=", strlen("addr=")) == 0) {
        status_t ret = mPolicyMixes.getInputMixForAttr(*attr, policyMix);
        status_t ret = mPolicyMixes.getInputMixForAttr(*attr, &policyMix);
        if (ret != NO_ERROR) {
            return ret;
        }
@@ -1308,7 +1308,7 @@ status_t AudioPolicyManager::getInputForAttr(const audio_attributes_t *attr,
    inputDesc->mIsSoundTrigger = isSoundTrigger;
    inputDesc->mPolicyMix = policyMix;

    ALOGV("getInputForAttr() returns input type = %d", inputType);
    ALOGV("getInputForAttr() returns input type = %d", *inputType);

    addInput(*input, inputDesc);
    mpClientInterface->onAudioPortListUpdate();
@@ -3032,7 +3032,7 @@ status_t AudioPolicyManager::checkOutputsForDevice(const sp<DeviceDescriptor> de
                                  address.string());
                        }
                        policyMix->setOutput(desc);
                        desc->mPolicyMix = &(policyMix->getMix());
                        desc->mPolicyMix = policyMix->getMix();

                    } else if ((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) == 0) {
                        // no duplicated output for direct outputs and