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

Commit 069787e7 authored by Jan Sebechlebsky's avatar Jan Sebechlebsky
Browse files

Refactor mixCriteria in AudioPolicyMix.

- use std::vector instead of android::Vector
- remove const qualifiers on setters (incorrect by definition)
- remove mutable specifier on mCriteria
- fix assignment to const pointer when actually changing the AudioMix

Bug: 233910083
Test: atest AudioServiceHostTest AudioHostTest AudioPolicyHostTest
Test: Refactoring cl, existing tests pass.
Change-Id: I140c41acbea0f5b88d71587d7633db4e7ceee847
parent d01cbef7
Loading
Loading
Loading
Loading
+10 −9
Original line number Diff line number Diff line
@@ -91,10 +91,11 @@ status_t AudioMix::readFromParcel(Parcel *parcel)
    if (size > MAX_CRITERIA_PER_MIX) {
        size = MAX_CRITERIA_PER_MIX;
    }
    mCriteria.reserve(size);
    for (size_t i = 0; i < size; i++) {
        AudioMixMatchCriterion criterion;
        if (criterion.readFromParcel(parcel) == NO_ERROR) {
            mCriteria.add(criterion);
            mCriteria.push_back(criterion);
        }
    }
    return NO_ERROR;
@@ -135,18 +136,18 @@ status_t AudioMix::writeToParcel(Parcel *parcel) const
    return NO_ERROR;
}

void AudioMix::setExcludeUid(uid_t uid) const {
void AudioMix::setExcludeUid(uid_t uid) {
    AudioMixMatchCriterion crit;
    crit.mRule = RULE_EXCLUDE_UID;
    crit.mValue.mUid = uid;
    mCriteria.add(crit);
    mCriteria.push_back(crit);
}

void AudioMix::setMatchUid(uid_t uid) const {
void AudioMix::setMatchUid(uid_t uid) {
    AudioMixMatchCriterion crit;
    crit.mRule = RULE_MATCH_UID;
    crit.mValue.mUid = uid;
    mCriteria.add(crit);
    mCriteria.push_back(crit);
}

bool AudioMix::hasUidRule(bool match, uid_t uid) const {
@@ -169,18 +170,18 @@ bool AudioMix::hasMatchUidRule() const {
    return false;
}

void AudioMix::setExcludeUserId(int userId) const {
void AudioMix::setExcludeUserId(int userId) {
    AudioMixMatchCriterion crit;
    crit.mRule = RULE_EXCLUDE_USERID;
    crit.mValue.mUserId = userId;
    mCriteria.add(crit);
    mCriteria.push_back(crit);
}

void AudioMix::setMatchUserId(int userId) const {
void AudioMix::setMatchUserId(int userId) {
    AudioMixMatchCriterion crit;
    crit.mRule = RULE_MATCH_USERID;
    crit.mValue.mUserId = userId;
    mCriteria.add(crit);
    mCriteria.push_back(crit);
}

bool AudioMix::hasUserIdRule(bool match, int userId) const {
+8 −7
Original line number Diff line number Diff line
@@ -88,23 +88,24 @@ public:
    static const uint32_t kCbFlagNotifyActivity = 0x1;

    AudioMix() {}
    AudioMix(Vector<AudioMixMatchCriterion> criteria, uint32_t mixType, audio_config_t format,
             uint32_t routeFlags, String8 registrationId, uint32_t flags) :
    AudioMix(const std::vector<AudioMixMatchCriterion> &criteria, uint32_t mixType,
             audio_config_t format, uint32_t routeFlags,const String8 &registrationId,
             uint32_t flags) :
        mCriteria(criteria), mMixType(mixType), mFormat(format),
        mRouteFlags(routeFlags), mDeviceAddress(registrationId), mCbFlags(flags){}

    status_t readFromParcel(Parcel *parcel);
    status_t writeToParcel(Parcel *parcel) const;

    void setExcludeUid(uid_t uid) const;
    void setMatchUid(uid_t uid) const;
    void setExcludeUid(uid_t uid);
    void setMatchUid(uid_t uid);
    /** returns true if this mix has a rule to match or exclude the given uid */
    bool hasUidRule(bool match, uid_t uid) const;
    /** returns true if this mix has a rule for uid match (any uid) */
    bool hasMatchUidRule() const;

    void setExcludeUserId(int userId) const;
    void setMatchUserId(int userId) const;
    void setExcludeUserId(int userId);
    void setMatchUserId(int userId);
    /** returns true if this mix has a rule to match or exclude the given userId */
    bool hasUserIdRule(bool match, int userId) const;
    /** returns true if this mix has a rule for userId match (any userId) */
@@ -112,7 +113,7 @@ public:
    /** returns true if this mix can be used for uid-device affinity routing */
    bool isDeviceAffinityCompatible() const;

    mutable Vector<AudioMixMatchCriterion> mCriteria;
    std::vector<AudioMixMatchCriterion> mCriteria;
    uint32_t        mMixType;
    audio_config_t  mFormat;
    uint32_t        mRouteFlags;
+3 −2
Original line number Diff line number Diff line
@@ -189,12 +189,13 @@ TEST_F(SerializationTest, AudioVolumeGroupBinderization) {
TEST_F(SerializationTest, AudioMixBinderization) {
    for (int j = 0; j < 512; j++) {
        const std::string msg{"Test AMBinderization for seed::" + std::to_string(mSeed)};
        Vector<AudioMixMatchCriterion> criteria;
        std::vector<AudioMixMatchCriterion> criteria;
        criteria.reserve(16);
        for (int i = 0; i < 16; i++) {
            AudioMixMatchCriterion ammc{kUsages[rand() % kUsages.size()],
                                        kInputSources[rand() % kInputSources.size()],
                                        kMixMatchRules[rand() % kMixMatchRules.size()]};
            criteria.add(ammc);
            criteria.push_back(ammc);
        }
        audio_config_t config{};
        config.sample_rate = 48000;
+1 −1
Original line number Diff line number Diff line
@@ -55,7 +55,7 @@ public:
    status_t getAudioPolicyMix(audio_devices_t deviceType,
            const String8& address, sp<AudioPolicyMix> &policyMix) const;

    status_t registerMix(AudioMix mix, sp<SwAudioOutputDescriptor> desc);
    status_t registerMix(const AudioMix& mix, const sp<SwAudioOutputDescriptor>& desc);

    status_t unregisterMix(const AudioMix& mix);

+31 −42
Original line number Diff line number Diff line
@@ -26,6 +26,16 @@

namespace android {

namespace {

template <typename Predicate>
void EraseCriteriaIf(std::vector<AudioMixMatchCriterion>& v,
                     const Predicate& predicate) {
    v.erase(std::remove_if(v.begin(), v.end(), predicate), v.end());
}

} // namespace

void AudioPolicyMix::dump(String8 *dst, int spaces, int index) const
{
    dst->appendFormat("%*sAudio Policy Mix %d (%p):\n", spaces, "", index + 1, this);
@@ -78,7 +88,8 @@ void AudioPolicyMix::dump(String8 *dst, int spaces, int index) const
    }
}

status_t AudioPolicyMixCollection::registerMix(AudioMix mix, sp<SwAudioOutputDescriptor> desc)
status_t AudioPolicyMixCollection::registerMix(const AudioMix& mix,
                                               const sp<SwAudioOutputDescriptor>& desc)
{
    for (size_t i = 0; i < size(); i++) {
        const sp<AudioPolicyMix>& registeredMix = itemAt(i);
@@ -89,12 +100,12 @@ status_t AudioPolicyMixCollection::registerMix(AudioMix mix, sp<SwAudioOutputDes
            return BAD_VALUE;
        }
    }
    sp<AudioPolicyMix> policyMix = new AudioPolicyMix(mix);
    sp<AudioPolicyMix> policyMix = sp<AudioPolicyMix>::make(mix);
    add(policyMix);
    ALOGD("registerMix(): adding mix for dev=0x%x addr=%s",
            policyMix->mDeviceType, policyMix->mDeviceAddress.string());

    if (desc != 0) {
    if (desc != nullptr) {
        desc->mPolicyMix = policyMix;
        policyMix->setOutput(desc);
    }
@@ -500,7 +511,7 @@ status_t AudioPolicyMixCollection::setUidDeviceAffinities(uid_t uid,
    //     AND it doesn't have a "match uid" rule
    //   THEN add a rule to exclude the uid
    for (size_t i = 0; i < size(); i++) {
        const AudioPolicyMix *mix = itemAt(i).get();
        AudioPolicyMix *mix = itemAt(i).get();
        if (!mix->isDeviceAffinityCompatible()) {
            continue;
        }
@@ -530,27 +541,16 @@ status_t AudioPolicyMixCollection::setUidDeviceAffinities(uid_t uid,
status_t AudioPolicyMixCollection::removeUidDeviceAffinities(uid_t uid) {
    // for each player mix: remove existing rules that match or exclude this uid
    for (size_t i = 0; i < size(); i++) {
        bool foundUidRule = false;
        const AudioPolicyMix *mix = itemAt(i).get();
        AudioPolicyMix *mix = itemAt(i).get();
        if (!mix->isDeviceAffinityCompatible()) {
            continue;
        }
        std::vector<size_t> criteriaToRemove;
        for (size_t j = 0; j < mix->mCriteria.size(); j++) {
            const uint32_t rule = mix->mCriteria[j].mRule;

        // is this rule excluding the uid? (not considering uid match rules
        // as those are not used for uid-device affinity)
            if (rule == RULE_EXCLUDE_UID
                    && uid == mix->mCriteria[j].mValue.mUid) {
                foundUidRule = true;
                criteriaToRemove.insert(criteriaToRemove.begin(), j);
            }
        }
        if (foundUidRule) {
            for (size_t j = 0; j < criteriaToRemove.size(); j++) {
                mix->mCriteria.removeAt(criteriaToRemove[j]);
            }
        }
        EraseCriteriaIf(mix->mCriteria, [uid](const AudioMixMatchCriterion& c) {
            return c.mRule == RULE_EXCLUDE_UID && c.mValue.mUid == uid;
        });
    }
    return NO_ERROR;
}
@@ -585,7 +585,7 @@ status_t AudioPolicyMixCollection::setUserIdDeviceAffinities(int userId,
    //    "match userId" rule for this userId, return an error
    //    (adding a userId-device affinity would result in contradictory rules)
    for (size_t i = 0; i < size(); i++) {
        const AudioPolicyMix* mix = itemAt(i).get();
        AudioPolicyMix* mix = itemAt(i).get();
        if (!mix->isDeviceAffinityCompatible()) {
            continue;
        }
@@ -602,7 +602,7 @@ status_t AudioPolicyMixCollection::setUserIdDeviceAffinities(int userId,
    //     AND it doesn't have a "match userId" rule
    //   THEN add a rule to exclude the userId
    for (size_t i = 0; i < size(); i++) {
        const AudioPolicyMix *mix = itemAt(i).get();
        AudioPolicyMix *mix = itemAt(i).get();
        if (!mix->isDeviceAffinityCompatible()) {
            continue;
        }
@@ -632,27 +632,16 @@ status_t AudioPolicyMixCollection::setUserIdDeviceAffinities(int userId,
status_t AudioPolicyMixCollection::removeUserIdDeviceAffinities(int userId) {
    // for each player mix: remove existing rules that match or exclude this userId
    for (size_t i = 0; i < size(); i++) {
        bool foundUserIdRule = false;
        const AudioPolicyMix *mix = itemAt(i).get();
        AudioPolicyMix *mix = itemAt(i).get();
        if (!mix->isDeviceAffinityCompatible()) {
            continue;
        }
        std::vector<size_t> criteriaToRemove;
        for (size_t j = 0; j < mix->mCriteria.size(); j++) {
            const uint32_t rule = mix->mCriteria[j].mRule;

        // is this rule excluding the userId? (not considering userId match rules
        // as those are not used for userId-device affinity)
            if (rule == RULE_EXCLUDE_USERID
                    && userId == mix->mCriteria[j].mValue.mUserId) {
                foundUserIdRule = true;
                criteriaToRemove.insert(criteriaToRemove.begin(), j);
            }
        }
        if (foundUserIdRule) {
            for (size_t j = 0; j < criteriaToRemove.size(); j++) {
                mix->mCriteria.removeAt(criteriaToRemove[j]);
            }
        }
        EraseCriteriaIf(mix->mCriteria, [userId](const AudioMixMatchCriterion& c) {
            return c.mRule == RULE_EXCLUDE_USERID && c.mValue.mUserId == userId;
        });
    }
    return NO_ERROR;
}
Loading