Loading media/libaudioclient/AudioProductStrategy.cpp +39 −14 Original line number Diff line number Diff line Loading @@ -60,25 +60,50 @@ aidl2legacy_AudioProductStrategy(const media::AudioProductStrategy& aidl) { } // 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) { if (refAttributes == clientAttritubes) { return MATCH_EQUALS; } if (refAttributes == AUDIO_ATTRIBUTES_INITIALIZER) { // 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. // Choosing the default must be done as a fallback, the attributes match shall not // select the default. return false; // Choosing the default must be done as a fallback,so return a default (zero) score to // allow identify the fallback. 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) || (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)); return score; } } // namespace android media/libaudioclient/AudioSystem.cpp +1 −2 Original line number Diff line number Diff line Loading @@ -2136,8 +2136,7 @@ audio_stream_type_t AudioSystem::attributesToStreamType(const audio_attributes_t if (strategy.getId() == psId) { auto attrVect = strategy.getVolumeGroupAttributes(); auto iter = std::find_if(begin(attrVect), end(attrVect), [&attr](const auto& refAttr) { return AudioProductStrategy::attributesMatches( refAttr.getAttributes(), attr); return refAttr.matchesScore(attr) > 0; }); if (iter != end(attrVect)) { return iter->getStreamType(); Loading media/libaudioclient/VolumeGroupAttributes.cpp +5 −0 Original line number Diff line number Diff line Loading @@ -21,11 +21,16 @@ #include <binder/Parcel.h> #include <media/AidlConversion.h> #include <media/AudioProductStrategy.h> #include <media/VolumeGroupAttributes.h> #include <media/PolicyAidlConversion.h> namespace android { int VolumeGroupAttributes::matchesScore(const audio_attributes_t &attributes) const { return AudioProductStrategy::attributesMatchesScore(mAttributes, attributes); } status_t VolumeGroupAttributes::readFromParcel(const Parcel* parcel) { media::AudioAttributesEx aidl; RETURN_STATUS_IF_ERROR(aidl.readFromParcel(parcel)); Loading media/libaudioclient/include/media/AudioProductStrategy.h +22 −6 Original line number Diff line number Diff line Loading @@ -46,19 +46,35 @@ public: status_t writeToParcel(Parcel *parcel) const override; /** * @brief attributesMatches: checks if client attributes matches with a reference attributes * "matching" means the usage shall match if reference attributes has a defined usage, AND * content type shall match if reference attributes has a defined content type AND * @brief attributesMatchesScore: checks if client attributes matches with a reference * attributes "matching" means the usage shall match if reference attributes has a defined * 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 * 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. * @param refAttributes 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); 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: std::string mName; std::vector<VolumeGroupAttributes> mVolumeGroupAttributes; Loading media/libaudioclient/include/media/VolumeGroupAttributes.h +2 −0 Original line number Diff line number Diff line Loading @@ -41,6 +41,8 @@ public: mAttributes.source = AUDIO_SOURCE_INVALID; } int matchesScore(const audio_attributes_t &attributes) const; audio_attributes_t getAttributes() const { return mAttributes; } status_t readFromParcel(const Parcel *parcel) override; Loading Loading
media/libaudioclient/AudioProductStrategy.cpp +39 −14 Original line number Diff line number Diff line Loading @@ -60,25 +60,50 @@ aidl2legacy_AudioProductStrategy(const media::AudioProductStrategy& aidl) { } // 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) { if (refAttributes == clientAttritubes) { return MATCH_EQUALS; } if (refAttributes == AUDIO_ATTRIBUTES_INITIALIZER) { // 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. // Choosing the default must be done as a fallback, the attributes match shall not // select the default. return false; // Choosing the default must be done as a fallback,so return a default (zero) score to // allow identify the fallback. 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) || (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)); return score; } } // namespace android
media/libaudioclient/AudioSystem.cpp +1 −2 Original line number Diff line number Diff line Loading @@ -2136,8 +2136,7 @@ audio_stream_type_t AudioSystem::attributesToStreamType(const audio_attributes_t if (strategy.getId() == psId) { auto attrVect = strategy.getVolumeGroupAttributes(); auto iter = std::find_if(begin(attrVect), end(attrVect), [&attr](const auto& refAttr) { return AudioProductStrategy::attributesMatches( refAttr.getAttributes(), attr); return refAttr.matchesScore(attr) > 0; }); if (iter != end(attrVect)) { return iter->getStreamType(); Loading
media/libaudioclient/VolumeGroupAttributes.cpp +5 −0 Original line number Diff line number Diff line Loading @@ -21,11 +21,16 @@ #include <binder/Parcel.h> #include <media/AidlConversion.h> #include <media/AudioProductStrategy.h> #include <media/VolumeGroupAttributes.h> #include <media/PolicyAidlConversion.h> namespace android { int VolumeGroupAttributes::matchesScore(const audio_attributes_t &attributes) const { return AudioProductStrategy::attributesMatchesScore(mAttributes, attributes); } status_t VolumeGroupAttributes::readFromParcel(const Parcel* parcel) { media::AudioAttributesEx aidl; RETURN_STATUS_IF_ERROR(aidl.readFromParcel(parcel)); Loading
media/libaudioclient/include/media/AudioProductStrategy.h +22 −6 Original line number Diff line number Diff line Loading @@ -46,19 +46,35 @@ public: status_t writeToParcel(Parcel *parcel) const override; /** * @brief attributesMatches: checks if client attributes matches with a reference attributes * "matching" means the usage shall match if reference attributes has a defined usage, AND * content type shall match if reference attributes has a defined content type AND * @brief attributesMatchesScore: checks if client attributes matches with a reference * attributes "matching" means the usage shall match if reference attributes has a defined * 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 * 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. * @param refAttributes 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); 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: std::string mName; std::vector<VolumeGroupAttributes> mVolumeGroupAttributes; Loading
media/libaudioclient/include/media/VolumeGroupAttributes.h +2 −0 Original line number Diff line number Diff line Loading @@ -41,6 +41,8 @@ public: mAttributes.source = AUDIO_SOURCE_INVALID; } int matchesScore(const audio_attributes_t &attributes) const; audio_attributes_t getAttributes() const { return mAttributes; } status_t readFromParcel(const Parcel *parcel) override; Loading