Merge "APM: uid-device affinity: fix for multiple concurrent apps" into qt-dev

gugelfrei
TreeHugger Robot 5 years ago committed by Android (Google) Code Review
commit b09f621af6

@ -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

@ -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;

@ -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;

@ -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
@ -418,12 +434,14 @@ 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
mix->setExcludeUid(uid);
if (!mix->hasUidRule(false /*match*/, uid)) {
// no need to do it again if uid is already excluded
mix->setExcludeUid(uid);
}
}
}
@ -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…
Cancel
Save