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

Commit 3ec6bc84 authored by Ján Sebechlebský's avatar Ján Sebechlebský Committed by Android (Google) Code Review
Browse files

Merge "Fix matching device address using audio attributes."

parents 6ff3553e bc56bcdc
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -134,4 +134,6 @@ private:
                            audio_session_t session);
};

std::optional<std::string> extractAddressFromAudioAttributes(const audio_attributes_t& attr);

} // namespace android
+29 −21
Original line number Diff line number Diff line
@@ -18,6 +18,9 @@
//#define LOG_NDEBUG 0

#include <algorithm>
#include <iterator>
#include <optional>
#include <regex>
#include "AudioPolicyMix.h"
#include "TypeConverter.h"
#include "HwModule.h"
@@ -28,6 +31,11 @@
namespace android {
namespace {

bool matchAddressToTags(const audio_attributes_t& attr, const String8& addr) {
    std::optional<std::string> tagAddress = extractAddressFromAudioAttributes(attr);
    return tagAddress.has_value() && tagAddress->compare(addr.c_str()) == 0;
}

// Returns true if the criterion matches.
// The exclude criteria are handled in the same way as positive
// ones - only condition is matched (the function will return
@@ -332,24 +340,14 @@ bool AudioPolicyMixCollection::mixMatch(const AudioMix* mix, size_t mixIndex,
        }

        // if there is an address match, prioritize that match
        if (strncmp(attributes.tags, "addr=", strlen("addr=")) == 0 &&
                strncmp(attributes.tags + strlen("addr="),
                        mix->mDeviceAddress.string(),
                        AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - strlen("addr=") - 1) == 0) {
            ALOGV("\tgetOutputForAttr will use mix %zu", mixIndex);
            return true;
        }

        if (areMixCriteriaMatched(mix->mCriteria, attributes, uid, session)) {
        if (matchAddressToTags(attributes, mix->mDeviceAddress)
            || areMixCriteriaMatched(mix->mCriteria, attributes, uid, session)) {
                ALOGV("\tgetOutputForAttr will use mix %zu", mixIndex);
                return true;
        }
    } 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->mDeviceAddress.string(),
                        AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - strlen("addr=") - 1) == 0) {
            matchAddressToTags(attributes, mix->mDeviceAddress)) {
            return true;
        }
    }
@@ -404,14 +402,14 @@ sp<DeviceDescriptor> AudioPolicyMixCollection::getDeviceAndMixForInputSource(
status_t AudioPolicyMixCollection::getInputMixForAttr(
        audio_attributes_t attr, sp<AudioPolicyMix> *policyMix)
{
    if (strncmp(attr.tags, "addr=", strlen("addr=")) != 0) {
    std::optional<std::string> address = extractAddressFromAudioAttributes(attr);
    if (!address.has_value()) {
        return BAD_VALUE;
    }
    String8 address(attr.tags + strlen("addr="));

#ifdef LOG_NDEBUG
    ALOGV("getInputMixForAttr looking for address %s for source %d\n  mixes available:",
            address.string(), attr.source);
            address->c_str(), attr.source);
    for (size_t i = 0; i < size(); i++) {
        const sp<AudioPolicyMix> audioPolicyMix = itemAt(i);
        ALOGV("\tmix %zu address=%s", i, audioPolicyMix->mDeviceAddress.string());
@@ -421,20 +419,20 @@ status_t AudioPolicyMixCollection::getInputMixForAttr(
    size_t index;
    for (index = 0; index < size(); index++) {
        const sp<AudioPolicyMix>& registeredMix = itemAt(index);
        if (registeredMix->mDeviceAddress.compare(address) == 0) {
        if (address->compare(registeredMix->mDeviceAddress.c_str()) == 0) {
            ALOGD("getInputMixForAttr found addr=%s dev=0x%x",
                    registeredMix->mDeviceAddress.string(), registeredMix->mDeviceType);
            break;
        }
    }
    if (index == size()) {
        ALOGW("getInputMixForAttr() no policy for address %s", address.string());
        ALOGW("getInputMixForAttr() no policy for address %s", address->c_str());
        return BAD_VALUE;
    }
    const sp<AudioPolicyMix> audioPolicyMix = itemAt(index);

    if (audioPolicyMix->mMixType != MIX_TYPE_PLAYERS) {
        ALOGW("getInputMixForAttr() bad policy mix type for address %s", address.string());
        ALOGW("getInputMixForAttr() bad policy mix type for address %s", address->c_str());
        return BAD_VALUE;
    }
    if (policyMix != nullptr) {
@@ -634,4 +632,14 @@ void AudioPolicyMixCollection::dump(String8 *dst) const
    }
}

std::optional<std::string> extractAddressFromAudioAttributes(const audio_attributes_t& attr) {
    static const std::regex addrTagRegex("addr=([^;]+)");

    std::cmatch match;
    if (std::regex_search(attr.tags, match, addrTagRegex)) {
        return match[1].str();
    }
    return std::nullopt;
}

}; //namespace android
+1 −1
Original line number Diff line number Diff line
@@ -2504,7 +2504,7 @@ status_t AudioPolicyManager::getInputForAttr(const audio_attributes_t *attr,
    *inputType = API_INPUT_INVALID;

    if (attributes.source == AUDIO_SOURCE_REMOTE_SUBMIX &&
            strncmp(attributes.tags, "addr=", strlen("addr=")) == 0) {
            extractAddressFromAudioAttributes(attributes).has_value()) {
        status = mPolicyMixes.getInputMixForAttr(attributes, &policyMix);
        if (status != NO_ERROR) {
            ALOGW("%s could not find input mix for attr %s",
+10 −1
Original line number Diff line number Diff line
@@ -1554,7 +1554,16 @@ INSTANTIATE_TEST_SUITE_P(
            .withTags("addr=remote_submix_media"),
        DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
            .withUsage(AUDIO_USAGE_ASSISTANT)
            .withTags("addr=remote_submix_media")));
            .withTags("addr=remote_submix_media"),
        DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
            .withUsage(AUDIO_USAGE_ASSISTANT)
            .withTags("sometag;addr=remote_submix_media;othertag=somevalue"),
        DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
            .withUsage(AUDIO_USAGE_ASSISTANT)
            .withTags("addr=remote_submix_media;othertag"),
        DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
            .withUsage(AUDIO_USAGE_ASSISTANT)
            .withTags("sometag;othertag;addr=remote_submix_media")));

static constexpr audio_session_t TEST_SESSION_ID = static_cast<audio_session_t>(42);
static constexpr audio_session_t OTHER_SESSION_ID = static_cast<audio_session_t>(77);