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

Commit bc55c9d8 authored by François Gaffie's avatar François Gaffie Committed by Mikhail Naganov
Browse files

[AOSP_IMPR] AudioPolicy: engine: add matching score API



Bug: 260298113
Bug: 284010885
Bug: 284020937
Test: build

Merged-In: I72ff69abc09d8017564bf8f811b5586aab9ebdec
Change-Id: I72ff69abc09d8017564bf8f811b5586aab9ebdec
Signed-off-by: default avatarFrançois Gaffie <francois.gaffie@renault.com>
(cherry picked from commit 8d7fd5a3)
parent 809ae91b
Loading
Loading
Loading
Loading
+39 −14
Original line number Original line Diff line number Diff line
@@ -60,25 +60,50 @@ aidl2legacy_AudioProductStrategy(const media::AudioProductStrategy& aidl) {
}
}


// Keep in sync with android/media/audiopolicy/AudioProductStrategy#attributeMatches
// Keep in sync with android/media/audiopolicy/AudioProductStrategy#attributeMatches
bool AudioProductStrategy::attributesMatches(const audio_attributes_t refAttributes,
int AudioProductStrategy::attributesMatchesScore(const audio_attributes_t refAttributes,
                                                 const audio_attributes_t clientAttritubes)
                                                 const audio_attributes_t clientAttritubes)
{
{
    if (refAttributes == clientAttritubes) {
        return MATCH_EQUALS;
    }
    if (refAttributes == AUDIO_ATTRIBUTES_INITIALIZER) {
    if (refAttributes == AUDIO_ATTRIBUTES_INITIALIZER) {
        // The default product strategy is the strategy that holds default attributes by convention.
        // The default product strategy is the strategy that holds default attributes by convention.
        // All attributes that fail to match will follow the default strategy for routing.
        // All attributes that fail to match will follow the default strategy for routing.
        // Choosing the default must be done as a fallback, the attributes match shall not
        // Choosing the default must be done as a fallback,so return a default (zero) score to
        // select the default.
        // allow identify the fallback.
        return false;
        return MATCH_ON_DEFAULT_SCORE;
    }
    int score = MATCH_ON_DEFAULT_SCORE;
    if (refAttributes.usage == AUDIO_USAGE_UNKNOWN) {
        score |= MATCH_ON_DEFAULT_SCORE;
    } else if (clientAttritubes.usage == refAttributes.usage) {
        score |= MATCH_ON_USAGE_SCORE;
    } else {
        return NO_MATCH;
    }
    if (refAttributes.content_type == AUDIO_CONTENT_TYPE_UNKNOWN) {
        score |= MATCH_ON_DEFAULT_SCORE;
    } else if (clientAttritubes.content_type == refAttributes.content_type) {
        score |= MATCH_ON_CONTENT_TYPE_SCORE;
    } else {
        return NO_MATCH;
    }
    if (strlen(refAttributes.tags) == 0) {
        score |= MATCH_ON_DEFAULT_SCORE;
    } else if (std::strcmp(clientAttritubes.tags, refAttributes.tags) == 0) {
        score |= MATCH_ON_TAGS_SCORE;
    } else {
        return NO_MATCH;
    }
    if (refAttributes.flags == AUDIO_FLAG_NONE) {
        score |= MATCH_ON_DEFAULT_SCORE;
    } else if ((clientAttritubes.flags != AUDIO_FLAG_NONE)
            && ((clientAttritubes.flags & refAttributes.flags) == refAttributes.flags)) {
        score |= MATCH_ON_FLAGS_SCORE;
    } else {
        return NO_MATCH;
    }
    }
    return ((refAttributes.usage == AUDIO_USAGE_UNKNOWN) ||
    return score;
            (clientAttritubes.usage == refAttributes.usage)) &&
            ((refAttributes.content_type == AUDIO_CONTENT_TYPE_UNKNOWN) ||
             (clientAttritubes.content_type == refAttributes.content_type)) &&
            ((refAttributes.flags == AUDIO_FLAG_NONE) ||
             (clientAttritubes.flags != AUDIO_FLAG_NONE &&
            (clientAttritubes.flags & refAttributes.flags) == refAttributes.flags)) &&
            ((strlen(refAttributes.tags) == 0) ||
             (std::strcmp(clientAttritubes.tags, refAttributes.tags) == 0));
}
}


} // namespace android
} // namespace android
+1 −2
Original line number Original line Diff line number Diff line
@@ -2132,8 +2132,7 @@ audio_stream_type_t AudioSystem::attributesToStreamType(const audio_attributes_t
        if (strategy.getId() == psId) {
        if (strategy.getId() == psId) {
            auto attrVect = strategy.getVolumeGroupAttributes();
            auto attrVect = strategy.getVolumeGroupAttributes();
            auto iter = std::find_if(begin(attrVect), end(attrVect), [&attr](const auto& refAttr) {
            auto iter = std::find_if(begin(attrVect), end(attrVect), [&attr](const auto& refAttr) {
                return AudioProductStrategy::attributesMatches(
                return refAttr.matchesScore(attr) > 0;
                        refAttr.getAttributes(), attr);
            });
            });
            if (iter != end(attrVect)) {
            if (iter != end(attrVect)) {
                return iter->getStreamType();
                return iter->getStreamType();
+5 −0
Original line number Original line Diff line number Diff line
@@ -21,11 +21,16 @@
#include <binder/Parcel.h>
#include <binder/Parcel.h>


#include <media/AidlConversion.h>
#include <media/AidlConversion.h>
#include <media/AudioProductStrategy.h>
#include <media/VolumeGroupAttributes.h>
#include <media/VolumeGroupAttributes.h>
#include <media/PolicyAidlConversion.h>
#include <media/PolicyAidlConversion.h>


namespace android {
namespace android {


int VolumeGroupAttributes::matchesScore(const audio_attributes_t &attributes) const {
    return AudioProductStrategy::attributesMatchesScore(mAttributes, attributes);
}

status_t VolumeGroupAttributes::readFromParcel(const Parcel* parcel) {
status_t VolumeGroupAttributes::readFromParcel(const Parcel* parcel) {
    media::AudioAttributesEx aidl;
    media::AudioAttributesEx aidl;
    RETURN_STATUS_IF_ERROR(aidl.readFromParcel(parcel));
    RETURN_STATUS_IF_ERROR(aidl.readFromParcel(parcel));
+22 −6
Original line number Original line Diff line number Diff line
@@ -46,19 +46,35 @@ public:
    status_t writeToParcel(Parcel *parcel) const override;
    status_t writeToParcel(Parcel *parcel) const override;


    /**
    /**
     * @brief attributesMatches: checks if client attributes matches with a reference attributes
     * @brief attributesMatchesScore: checks if client attributes matches with a reference
     * "matching" means the usage shall match if reference attributes has a defined usage, AND
     * attributes "matching" means the usage shall match if reference attributes has a defined
     * content type shall match if reference attributes has a defined content type AND
     * usage, AND content type shall match if reference attributes has a defined content type AND
     * flags shall match if reference attributes has defined flags AND
     * flags shall match if reference attributes has defined flags AND
     * tags shall match if reference attributes has defined tags.
     * tags shall match if reference attributes has defined tags.
     * Reference attributes "default" shall not be considered as a "true" case. This convention
     * Reference attributes "default" shall be considered as a weak match case. This convention
     * is used to identify the default strategy.
     * is used to identify the default strategy.
     * @param refAttributes to be considered
     * @param refAttributes to be considered
     * @param clientAttritubes to be considered
     * @param clientAttritubes to be considered
     * @return true if matching, false otherwise
     * @return {@code INVALID_SCORE} if not matching, {@code MATCH_ON_DEFAULT_SCORE} if matching
     * to default strategy, non zero positive score if matching a strategy.
     */
     */
    static bool attributesMatches(const audio_attributes_t refAttributes,
    static int attributesMatchesScore(const audio_attributes_t refAttributes,
                                      const audio_attributes_t clientAttritubes);
                                      const audio_attributes_t clientAttritubes);

    static bool attributesMatches(const audio_attributes_t refAttributes,
                                      const audio_attributes_t clientAttritubes) {
        return attributesMatchesScore(refAttributes, clientAttritubes) > 0;
    }

    static const int MATCH_ON_TAGS_SCORE = 1 << 3;
    static const int MATCH_ON_FLAGS_SCORE = 1 << 2;
    static const int MATCH_ON_USAGE_SCORE = 1 << 1;
    static const int MATCH_ON_CONTENT_TYPE_SCORE = 1 << 0;
    static const int MATCH_ON_DEFAULT_SCORE = 0;
    static const int MATCH_EQUALS = MATCH_ON_TAGS_SCORE | MATCH_ON_FLAGS_SCORE
            | MATCH_ON_USAGE_SCORE | MATCH_ON_CONTENT_TYPE_SCORE;
    static const int NO_MATCH = -1;

private:
private:
    std::string mName;
    std::string mName;
    std::vector<VolumeGroupAttributes> mVolumeGroupAttributes;
    std::vector<VolumeGroupAttributes> mVolumeGroupAttributes;
+2 −0
Original line number Original line Diff line number Diff line
@@ -41,6 +41,8 @@ public:
        mAttributes.source = AUDIO_SOURCE_INVALID;
        mAttributes.source = AUDIO_SOURCE_INVALID;
    }
    }


    int matchesScore(const audio_attributes_t &attributes) const;

    audio_attributes_t getAttributes() const { return mAttributes; }
    audio_attributes_t getAttributes() const { return mAttributes; }


    status_t readFromParcel(const Parcel *parcel) override;
    status_t readFromParcel(const Parcel *parcel) override;
Loading