Loading media/libaudioclient/AudioPolicy.cpp +25 −0 Original line number Diff line number Diff line Loading @@ -159,4 +159,29 @@ void AudioMix::setMatchUid(uid_t uid) const { mCriteria.add(crit); } bool AudioMix::hasUidRule(bool match, uid_t uid) const { const uint32_t rule = match ? RULE_MATCH_UID : RULE_EXCLUDE_UID; for (size_t i = 0; i < mCriteria.size(); i++) { if (mCriteria[i].mRule == rule && mCriteria[i].mValue.mUid == uid) { return true; } } return false; } bool AudioMix::hasMatchUidRule() const { for (size_t i = 0; i < mCriteria.size(); i++) { if (mCriteria[i].mRule == RULE_MATCH_UID) { return true; } } return false; } bool AudioMix::isDeviceAffinityCompatible() const { return ((mMixType == MIX_TYPE_PLAYERS) && (mRouteFlags == MIX_ROUTE_FLAG_RENDER)); } } // namespace android media/libaudioclient/include/media/AudioPolicy.h +6 −0 Original line number Diff line number Diff line Loading @@ -106,6 +106,12 @@ public: void setExcludeUid(uid_t uid) const; void setMatchUid(uid_t uid) const; /** 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; /** returns true if this mix can be used for uid-device affinity routing */ bool isDeviceAffinityCompatible() const; mutable Vector<AudioMixMatchCriterion> mCriteria; uint32_t mMixType; Loading services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h +10 −0 Original line number Diff line number Diff line Loading @@ -89,6 +89,16 @@ public: status_t getInputMixForAttr(audio_attributes_t attr, sp<AudioPolicyMix> *policyMix); /** * Updates the mix rules in order to make streams associated with the given uid * be routed to the given audio devices. * @param uid the uid for which the device affinity is set * @param devices the vector of devices that this uid may be routed to. A typical * use is to pass the devices associated with a given zone in a multi-zone setup. * @return NO_ERROR if the update was successful, INVALID_OPERATION otherwise. * An example of failure is when there are already rules in place to restrict * a mix to the given uid (i.e. when a MATCH_UID rule was set for it). */ status_t setUidDeviceAffinities(uid_t uid, const Vector<AudioDeviceTypeAddr>& devices); status_t removeUidDeviceAffinities(uid_t uid); status_t getDevicesForUid(uid_t uid, Vector<AudioDeviceTypeAddr>& devices) const; Loading services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp +28 −9 Original line number Diff line number Diff line Loading @@ -400,13 +400,29 @@ status_t AudioPolicyMixCollection::getInputMixForAttr( status_t AudioPolicyMixCollection::setUidDeviceAffinities(uid_t uid, const Vector<AudioDeviceTypeAddr>& devices) { // verify feasibility: for each player mix: if it already contains a // "match uid" rule for this uid, return an error // (adding a uid-device affinity would result in contradictory rules) for (size_t i = 0; i < size(); i++) { const AudioPolicyMix* mix = valueAt(i).get(); if (!mix->isDeviceAffinityCompatible()) { continue; } if (mix->hasUidRule(true /*match*/, uid)) { return INVALID_OPERATION; } } // remove existing rules for this uid removeUidDeviceAffinities(uid); // for each player mix: add a rule to match or exclude the uid based on the device // for each player mix: // IF device is not a target for the mix, // 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 = valueAt(i).get(); if (mix->mMixType != MIX_TYPE_PLAYERS) { if (!mix->isDeviceAffinityCompatible()) { continue; } // check if this mix goes to a device in the list of devices Loading @@ -418,14 +434,16 @@ status_t AudioPolicyMixCollection::setUidDeviceAffinities(uid_t uid, break; } } if (deviceMatch) { mix->setMatchUid(uid); } else { if (!deviceMatch && !mix->hasMatchUidRule()) { // this mix doesn't go to one of the listed devices for the given uid, // and it's not already restricting the mix on a uid, // modify its rules to exclude the uid if (!mix->hasUidRule(false /*match*/, uid)) { // no need to do it again if uid is already excluded mix->setExcludeUid(uid); } } } return NO_ERROR; } Loading @@ -435,14 +453,15 @@ status_t AudioPolicyMixCollection::removeUidDeviceAffinities(uid_t uid) { for (size_t i = 0; i < size(); i++) { bool foundUidRule = false; const AudioPolicyMix *mix = valueAt(i).get(); if (mix->mMixType != MIX_TYPE_PLAYERS) { 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 affecting the uid? if ((rule == RULE_EXCLUDE_UID || rule == RULE_MATCH_UID) // 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); Loading Loading
media/libaudioclient/AudioPolicy.cpp +25 −0 Original line number Diff line number Diff line Loading @@ -159,4 +159,29 @@ void AudioMix::setMatchUid(uid_t uid) const { mCriteria.add(crit); } bool AudioMix::hasUidRule(bool match, uid_t uid) const { const uint32_t rule = match ? RULE_MATCH_UID : RULE_EXCLUDE_UID; for (size_t i = 0; i < mCriteria.size(); i++) { if (mCriteria[i].mRule == rule && mCriteria[i].mValue.mUid == uid) { return true; } } return false; } bool AudioMix::hasMatchUidRule() const { for (size_t i = 0; i < mCriteria.size(); i++) { if (mCriteria[i].mRule == RULE_MATCH_UID) { return true; } } return false; } bool AudioMix::isDeviceAffinityCompatible() const { return ((mMixType == MIX_TYPE_PLAYERS) && (mRouteFlags == MIX_ROUTE_FLAG_RENDER)); } } // namespace android
media/libaudioclient/include/media/AudioPolicy.h +6 −0 Original line number Diff line number Diff line Loading @@ -106,6 +106,12 @@ public: void setExcludeUid(uid_t uid) const; void setMatchUid(uid_t uid) const; /** 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; /** returns true if this mix can be used for uid-device affinity routing */ bool isDeviceAffinityCompatible() const; mutable Vector<AudioMixMatchCriterion> mCriteria; uint32_t mMixType; Loading
services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h +10 −0 Original line number Diff line number Diff line Loading @@ -89,6 +89,16 @@ public: status_t getInputMixForAttr(audio_attributes_t attr, sp<AudioPolicyMix> *policyMix); /** * Updates the mix rules in order to make streams associated with the given uid * be routed to the given audio devices. * @param uid the uid for which the device affinity is set * @param devices the vector of devices that this uid may be routed to. A typical * use is to pass the devices associated with a given zone in a multi-zone setup. * @return NO_ERROR if the update was successful, INVALID_OPERATION otherwise. * An example of failure is when there are already rules in place to restrict * a mix to the given uid (i.e. when a MATCH_UID rule was set for it). */ status_t setUidDeviceAffinities(uid_t uid, const Vector<AudioDeviceTypeAddr>& devices); status_t removeUidDeviceAffinities(uid_t uid); status_t getDevicesForUid(uid_t uid, Vector<AudioDeviceTypeAddr>& devices) const; Loading
services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp +28 −9 Original line number Diff line number Diff line Loading @@ -400,13 +400,29 @@ status_t AudioPolicyMixCollection::getInputMixForAttr( status_t AudioPolicyMixCollection::setUidDeviceAffinities(uid_t uid, const Vector<AudioDeviceTypeAddr>& devices) { // verify feasibility: for each player mix: if it already contains a // "match uid" rule for this uid, return an error // (adding a uid-device affinity would result in contradictory rules) for (size_t i = 0; i < size(); i++) { const AudioPolicyMix* mix = valueAt(i).get(); if (!mix->isDeviceAffinityCompatible()) { continue; } if (mix->hasUidRule(true /*match*/, uid)) { return INVALID_OPERATION; } } // remove existing rules for this uid removeUidDeviceAffinities(uid); // for each player mix: add a rule to match or exclude the uid based on the device // for each player mix: // IF device is not a target for the mix, // 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 = valueAt(i).get(); if (mix->mMixType != MIX_TYPE_PLAYERS) { if (!mix->isDeviceAffinityCompatible()) { continue; } // check if this mix goes to a device in the list of devices Loading @@ -418,14 +434,16 @@ status_t AudioPolicyMixCollection::setUidDeviceAffinities(uid_t uid, break; } } if (deviceMatch) { mix->setMatchUid(uid); } else { if (!deviceMatch && !mix->hasMatchUidRule()) { // this mix doesn't go to one of the listed devices for the given uid, // and it's not already restricting the mix on a uid, // modify its rules to exclude the uid if (!mix->hasUidRule(false /*match*/, uid)) { // no need to do it again if uid is already excluded mix->setExcludeUid(uid); } } } return NO_ERROR; } Loading @@ -435,14 +453,15 @@ status_t AudioPolicyMixCollection::removeUidDeviceAffinities(uid_t uid) { for (size_t i = 0; i < size(); i++) { bool foundUidRule = false; const AudioPolicyMix *mix = valueAt(i).get(); if (mix->mMixType != MIX_TYPE_PLAYERS) { 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 affecting the uid? if ((rule == RULE_EXCLUDE_UID || rule == RULE_MATCH_UID) // 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); Loading