Merge "Merge TP1A.221005.003"
diff --git a/media/codec2/components/gav1/C2SoftGav1Dec.h b/media/codec2/components/gav1/C2SoftGav1Dec.h
index e51c511..f0e14d7 100644
--- a/media/codec2/components/gav1/C2SoftGav1Dec.h
+++ b/media/codec2/components/gav1/C2SoftGav1Dec.h
@@ -23,8 +23,8 @@
#include <SimpleC2Component.h>
#include <C2Config.h>
-#include "libgav1/src/gav1/decoder.h"
-#include "libgav1/src/gav1/decoder_settings.h"
+#include <gav1/decoder.h>
+#include <gav1/decoder_settings.h>
namespace android {
diff --git a/media/libaudioclient/AudioPolicy.cpp b/media/libaudioclient/AudioPolicy.cpp
index c2f7229..4d2b6b1 100644
--- a/media/libaudioclient/AudioPolicy.cpp
+++ b/media/libaudioclient/AudioPolicy.cpp
@@ -71,6 +71,10 @@
return NO_ERROR;
}
+bool AudioMixMatchCriterion::isExcludeCriterion() const {
+ return mRule & RULE_EXCLUSION_MASK;
+}
+
//
// AudioMix implementation
//
@@ -91,10 +95,11 @@
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 +140,18 @@
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 +174,18 @@
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 {
diff --git a/media/libaudioclient/include/media/AudioPolicy.h b/media/libaudioclient/include/media/AudioPolicy.h
index 08b3da1..d42d962 100644
--- a/media/libaudioclient/include/media/AudioPolicy.h
+++ b/media/libaudioclient/include/media/AudioPolicy.h
@@ -72,6 +72,7 @@
status_t readFromParcel(Parcel *parcel);
status_t writeToParcel(Parcel *parcel) const;
+ bool isExcludeCriterion() const;
union {
audio_usage_t mUsage;
audio_source_t mSource;
@@ -88,23 +89,24 @@
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 ®istrationId,
+ 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 +114,7 @@
/** 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;
diff --git a/media/libaudioclient/tests/audioclient_serialization_tests.cpp b/media/libaudioclient/tests/audioclient_serialization_tests.cpp
index 93baefd6..ef8500b 100644
--- a/media/libaudioclient/tests/audioclient_serialization_tests.cpp
+++ b/media/libaudioclient/tests/audioclient_serialization_tests.cpp
@@ -189,12 +189,13 @@
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;
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h
index bb1699e..afffcd5 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h
@@ -55,7 +55,7 @@
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);
@@ -124,7 +124,7 @@
void dump(String8 *dst) const;
private:
- enum class MixMatchStatus { MATCH, NO_MATCH, INVALID_MIX };
+ enum class MixMatchStatus { MATCH, NO_MATCH };
MixMatchStatus mixMatch(const AudioMix* mix, size_t mixIndex,
const audio_attributes_t& attributes,
const audio_config_base_t& config,
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
index 551eab6..667cac0 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
@@ -17,6 +17,7 @@
#define LOG_TAG "APM_AudioPolicyMix"
//#define LOG_NDEBUG 0
+#include <algorithm>
#include "AudioPolicyMix.h"
#include "TypeConverter.h"
#include "HwModule.h"
@@ -25,6 +26,34 @@
#include <AudioOutputDescriptor.h>
namespace android {
+namespace {
+
+// Consistency checks: for each "dimension" of rules (usage, uid...), we can
+// only have MATCH rules, or EXCLUDE rules in each dimension, not a combination.
+bool areMixCriteriaConsistent(const std::vector<AudioMixMatchCriterion>& criteria) {
+ std::set<uint32_t> positiveCriteria;
+ for (const AudioMixMatchCriterion& c : criteria) {
+ if (c.isExcludeCriterion()) {
+ continue;
+ }
+ positiveCriteria.insert(c.mRule);
+ }
+
+ auto isConflictingCriterion = [&positiveCriteria](const AudioMixMatchCriterion& c) {
+ uint32_t ruleWithoutExclusion = c.mRule & ~RULE_EXCLUSION_MASK;
+ return c.isExcludeCriterion() &&
+ (positiveCriteria.find(ruleWithoutExclusion) != positiveCriteria.end());
+ };
+ return std::none_of(criteria.begin(), criteria.end(), isConflictingCriterion);
+}
+
+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
{
@@ -78,7 +107,8 @@
}
}
-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 +119,17 @@
return BAD_VALUE;
}
}
- sp<AudioPolicyMix> policyMix = new AudioPolicyMix(mix);
+ if (!areMixCriteriaConsistent(mix.mCriteria)) {
+ ALOGE("registerMix(): Mix contains inconsistent criteria "
+ "(MATCH & EXCLUDE criteria of the same type)");
+ return BAD_VALUE;
+ }
+ 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);
}
@@ -177,15 +212,9 @@
continue; // Primary output already found
}
- switch (mixMatch(policyMix.get(), i, attributes, config, uid)) {
- case MixMatchStatus::INVALID_MIX:
- // The mix has contradictory rules, ignore it
- // TODO: reject invalid mix at registration
- continue;
- case MixMatchStatus::NO_MATCH:
- ALOGV("%s: Mix %zu: does not match", __func__, i);
- continue; // skip the mix
- case MixMatchStatus::MATCH:;
+ if(mixMatch(policyMix.get(), i, attributes, config, uid) == MixMatchStatus::NO_MATCH) {
+ ALOGV("%s: Mix %zu: does not match", __func__, i);
+ continue; // skip the mix
}
if (primaryOutputMix) {
@@ -331,23 +360,6 @@
break;
}
- // consistency checks: for each "dimension" of rules (usage, uid...), we can
- // only have MATCH rules, or EXCLUDE rules in each dimension, not a combination
- if (hasUsageMatchRules && hasUsageExcludeRules) {
- ALOGE("getOutputForAttr: invalid combination of RULE_MATCH_ATTRIBUTE_USAGE"
- " and RULE_EXCLUDE_ATTRIBUTE_USAGE in mix %zu", mixIndex);
- return MixMatchStatus::INVALID_MIX;
- }
- if (hasUidMatchRules && hasUidExcludeRules) {
- ALOGE("getOutputForAttr: invalid combination of RULE_MATCH_UID"
- " and RULE_EXCLUDE_UID in mix %zu", mixIndex);
- return MixMatchStatus::INVALID_MIX;
- }
- if (hasUserIdMatchRules && hasUserIdExcludeRules) {
- ALOGE("getOutputForAttr: invalid combination of RULE_MATCH_USERID"
- " and RULE_EXCLUDE_USERID in mix %zu", mixIndex);
- return MixMatchStatus::INVALID_MIX;
- }
if ((hasUsageExcludeRules && usageExclusionFound)
|| (hasUidExcludeRules && uidExclusionFound)
@@ -500,7 +512,7 @@
// 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 +542,16 @@
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]);
- }
- }
+
+ // is this rule excluding the uid? (not considering uid match rules
+ // as those are not used for uid-device affinity)
+ EraseCriteriaIf(mix->mCriteria, [uid](const AudioMixMatchCriterion& c) {
+ return c.mRule == RULE_EXCLUDE_UID && c.mValue.mUid == uid;
+ });
}
return NO_ERROR;
}
@@ -585,7 +586,7 @@
// "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 +603,7 @@
// 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 +633,16 @@
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]);
- }
- }
+
+ // is this rule excluding the userId? (not considering userId match rules
+ // as those are not used for userId-device affinity)
+ EraseCriteriaIf(mix->mCriteria, [userId](const AudioMixMatchCriterion& c) {
+ return c.mRule == RULE_EXCLUDE_USERID && c.mValue.mUserId == userId;
+ });
}
return NO_ERROR;
}
diff --git a/services/audiopolicy/engine/common/src/VolumeCurve.cpp b/services/audiopolicy/engine/common/src/VolumeCurve.cpp
index 8aa4b08..fccbc60 100644
--- a/services/audiopolicy/engine/common/src/VolumeCurve.cpp
+++ b/services/audiopolicy/engine/common/src/VolumeCurve.cpp
@@ -52,7 +52,7 @@
volIdx = volIndexMin;
} else {
// This would result in a divide-by-zero below
- ALOG_ASSERT(volIndexmin != volIndexMax, "Invalid volume index range & value: 0");
+ ALOG_ASSERT(volIndexMin != volIndexMax, "Invalid volume index range & value: 0");
return NAN;
}
} else {
diff --git a/services/audiopolicy/fuzzer/audiopolicy_fuzzer.cpp b/services/audiopolicy/fuzzer/audiopolicy_fuzzer.cpp
index 48f7410..28268c9 100644
--- a/services/audiopolicy/fuzzer/audiopolicy_fuzzer.cpp
+++ b/services/audiopolicy/fuzzer/audiopolicy_fuzzer.cpp
@@ -544,10 +544,11 @@
status_t AudioPolicyManagerFuzzerDynamicPolicy::addPolicyMix(
int mixType, int mixFlag, audio_devices_t deviceType, std::string mixAddress,
const audio_config_t &audioConfig, const std::vector<PolicyMixTuple> &rules) {
- Vector<AudioMixMatchCriterion> myMixMatchCriteria;
+ std::vector<AudioMixMatchCriterion> myMixMatchCriteria;
+ myMixMatchCriteria.reserve(rules.size());
for (const auto &rule : rules) {
- myMixMatchCriteria.add(
+ myMixMatchCriteria.push_back(
AudioMixMatchCriterion(std::get<0>(rule), std::get<1>(rule), std::get<2>(rule)));
}
diff --git a/services/audiopolicy/tests/audiopolicymanager_tests.cpp b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
index bb00c48..d51c57c 100644
--- a/services/audiopolicy/tests/audiopolicymanager_tests.cpp
+++ b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
@@ -42,6 +42,32 @@
using testing::UnorderedElementsAre;
using android::content::AttributionSourceState;
+namespace {
+
+AudioMixMatchCriterion createUidCriterion(uint32_t uid, bool exclude = false) {
+ AudioMixMatchCriterion criterion;
+ criterion.mValue.mUid = uid;
+ criterion.mRule = exclude ? RULE_EXCLUDE_UID : RULE_MATCH_UID;
+ return criterion;
+}
+
+AudioMixMatchCriterion createUsageCriterion(audio_usage_t usage, bool exclude = false) {
+ AudioMixMatchCriterion criterion;
+ criterion.mValue.mUsage = usage;
+ criterion.mRule = exclude ? RULE_EXCLUDE_ATTRIBUTE_USAGE : RULE_MATCH_ATTRIBUTE_USAGE;
+ return criterion;
+}
+
+AudioMixMatchCriterion createCapturePresetCriterion(audio_source_t source, bool exclude = false) {
+ AudioMixMatchCriterion criterion;
+ criterion.mValue.mSource = source;
+ criterion.mRule = exclude ?
+ RULE_EXCLUDE_ATTRIBUTE_CAPTURE_PRESET : RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET;
+ return criterion;
+}
+
+} // namespace
+
TEST(AudioPolicyManagerTestInit, EngineFailure) {
AudioPolicyTestClient client;
AudioPolicyTestManager manager(&client);
@@ -943,15 +969,13 @@
}
}
-using PolicyMixTuple = std::tuple<audio_usage_t, audio_source_t, uint32_t>;
-
class AudioPolicyManagerTestDynamicPolicy : public AudioPolicyManagerTestWithConfigurationFile {
protected:
void TearDown() override;
status_t addPolicyMix(int mixType, int mixFlag, audio_devices_t deviceType,
std::string mixAddress, const audio_config_t& audioConfig,
- const std::vector<PolicyMixTuple>& rules);
+ const std::vector<AudioMixMatchCriterion>& matchCriteria);
void clearPolicyMix();
Vector<AudioMix> mAudioMixes;
@@ -965,15 +989,8 @@
status_t AudioPolicyManagerTestDynamicPolicy::addPolicyMix(int mixType, int mixFlag,
audio_devices_t deviceType, std::string mixAddress, const audio_config_t& audioConfig,
- const std::vector<PolicyMixTuple>& rules) {
- Vector<AudioMixMatchCriterion> myMixMatchCriteria;
-
- for(const auto &rule: rules) {
- myMixMatchCriteria.add(AudioMixMatchCriterion(
- std::get<0>(rule), std::get<1>(rule), std::get<2>(rule)));
- }
-
- AudioMix myAudioMix(myMixMatchCriteria, mixType, audioConfig, mixFlag,
+ const std::vector<AudioMixMatchCriterion>& matchCriteria = {}) {
+ AudioMix myAudioMix(matchCriteria, mixType, audioConfig, mixFlag,
String8(mixAddress.c_str()), 0);
myAudioMix.mDeviceType = deviceType;
// Clear mAudioMix before add new one to make sure we don't add already exist mixes.
@@ -1007,13 +1024,13 @@
// Only capture of playback is allowed in LOOP_BACK &RENDER mode
ret = addPolicyMix(MIX_TYPE_RECORDERS, MIX_ROUTE_FLAG_LOOP_BACK_AND_RENDER,
- AUDIO_DEVICE_OUT_REMOTE_SUBMIX, "", audioConfig, std::vector<PolicyMixTuple>());
+ AUDIO_DEVICE_OUT_REMOTE_SUBMIX, "", audioConfig);
ASSERT_EQ(INVALID_OPERATION, ret);
// Fail due to the device is already connected.
clearPolicyMix();
ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_LOOP_BACK,
- AUDIO_DEVICE_OUT_REMOTE_SUBMIX, "", audioConfig, std::vector<PolicyMixTuple>());
+ AUDIO_DEVICE_OUT_REMOTE_SUBMIX, "", audioConfig);
ASSERT_EQ(INVALID_OPERATION, ret);
// The first time to register policy mixes with valid parameter should succeed.
@@ -1022,8 +1039,7 @@
audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
audioConfig.sample_rate = k48000SamplingRate;
ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_LOOP_BACK,
- AUDIO_DEVICE_OUT_REMOTE_SUBMIX, mMixAddress, audioConfig,
- std::vector<PolicyMixTuple>());
+ AUDIO_DEVICE_OUT_REMOTE_SUBMIX, mMixAddress, audioConfig);
ASSERT_EQ(NO_ERROR, ret);
// Registering the same policy mixes should fail.
ret = mManager->registerPolicyMixes(mAudioMixes);
@@ -1034,19 +1050,19 @@
// This will need to be updated if earpiece is added in the test configuration file.
clearPolicyMix();
ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
- AUDIO_DEVICE_OUT_EARPIECE, "", audioConfig, std::vector<PolicyMixTuple>());
+ AUDIO_DEVICE_OUT_EARPIECE, "", audioConfig);
ASSERT_EQ(INVALID_OPERATION, ret);
// Registration should fail due to output not found.
clearPolicyMix();
ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
- AUDIO_DEVICE_OUT_REMOTE_SUBMIX, "", audioConfig, std::vector<PolicyMixTuple>());
+ AUDIO_DEVICE_OUT_REMOTE_SUBMIX, "", audioConfig);
ASSERT_EQ(INVALID_OPERATION, ret);
// The first time to register valid policy mixes should succeed.
clearPolicyMix();
ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
- AUDIO_DEVICE_OUT_SPEAKER, "", audioConfig, std::vector<PolicyMixTuple>());
+ AUDIO_DEVICE_OUT_SPEAKER, "", audioConfig);
ASSERT_EQ(NO_ERROR, ret);
// Registering the same policy mixes should fail.
ret = mManager->registerPolicyMixes(mAudioMixes);
@@ -1061,8 +1077,7 @@
audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
audioConfig.sample_rate = k48000SamplingRate;
ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_LOOP_BACK,
- AUDIO_DEVICE_OUT_REMOTE_SUBMIX, mMixAddress, audioConfig,
- std::vector<PolicyMixTuple>());
+ AUDIO_DEVICE_OUT_REMOTE_SUBMIX, mMixAddress, audioConfig);
ASSERT_EQ(NO_ERROR, ret);
// After successfully registering policy mixes, it should be able to unregister.
@@ -1075,6 +1090,37 @@
ASSERT_EQ(INVALID_OPERATION, ret);
}
+TEST_F(AudioPolicyManagerTestDynamicPolicy, RegisterPolicyWithConsistentMixSucceeds) {
+ audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
+ audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
+ audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
+ audioConfig.sample_rate = k48000SamplingRate;
+
+ std::vector<AudioMixMatchCriterion> mixMatchCriteria = {
+ createUidCriterion(/*uid=*/42),
+ createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/true)};
+ status_t ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_LOOP_BACK,
+ AUDIO_DEVICE_OUT_REMOTE_SUBMIX, mMixAddress, audioConfig,
+ mixMatchCriteria);
+ ASSERT_EQ(NO_ERROR, ret);
+}
+
+TEST_F(AudioPolicyManagerTestDynamicPolicy, RegisterPolicyWithInconsistentMixFails) {
+ audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
+ audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
+ audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
+ audioConfig.sample_rate = k48000SamplingRate;
+
+ std::vector<AudioMixMatchCriterion> mixMatchCriteria = {
+ createUidCriterion(/*uid=*/42),
+ createUidCriterion(/*uid=*/1235, /*exclude=*/true),
+ createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/true)};
+ status_t ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_LOOP_BACK,
+ AUDIO_DEVICE_OUT_REMOTE_SUBMIX, mMixAddress, audioConfig,
+ mixMatchCriteria);
+ ASSERT_EQ(INVALID_OPERATION, ret);
+}
+
class AudioPolicyManagerTestForHdmi
: public AudioPolicyManagerTestWithConfigurationFile,
public testing::WithParamInterface<audio_format_t> {
@@ -1299,7 +1345,7 @@
audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
audioConfig.sample_rate = k48000SamplingRate;
ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_LOOP_BACK,
- AUDIO_DEVICE_OUT_REMOTE_SUBMIX, "", audioConfig, std::vector<PolicyMixTuple>());
+ AUDIO_DEVICE_OUT_REMOTE_SUBMIX, "", audioConfig);
ASSERT_EQ(INVALID_OPERATION, ret);
ret = mManager->unregisterPolicyMixes(mAudioMixes);
@@ -1314,9 +1360,9 @@
std::unique_ptr<RecordingActivityTracker> mTracker;
- std::vector<PolicyMixTuple> mUsageRules = {
- {AUDIO_USAGE_MEDIA, AUDIO_SOURCE_DEFAULT, RULE_MATCH_ATTRIBUTE_USAGE},
- {AUDIO_USAGE_ALARM, AUDIO_SOURCE_DEFAULT, RULE_MATCH_ATTRIBUTE_USAGE}
+ std::vector<AudioMixMatchCriterion> mUsageRules = {
+ createUsageCriterion(AUDIO_USAGE_MEDIA),
+ createUsageCriterion(AUDIO_USAGE_ALARM)
};
struct audio_port_v7 mInjectionPort;
@@ -1376,9 +1422,10 @@
getOutputForAttr(&playbackRoutedPortId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
k48000SamplingRate, AUDIO_OUTPUT_FLAG_NONE, nullptr /*output*/, nullptr /*portId*/,
attr);
- if (std::find_if(begin(mUsageRules), end(mUsageRules), [&usage](const auto &usageRule) {
- return (std::get<0>(usageRule) == usage) &&
- (std::get<2>(usageRule) == RULE_MATCH_ATTRIBUTE_USAGE);}) != end(mUsageRules) ||
+ if (std::find_if(begin(mUsageRules), end(mUsageRules),
+ [&usage](const AudioMixMatchCriterion &c) {
+ return c.mRule == RULE_MATCH_ATTRIBUTE_USAGE &&
+ c.mValue.mUsage == usage;}) != end(mUsageRules) ||
(strncmp(attr.tags, "addr=", strlen("addr=")) == 0 &&
strncmp(attr.tags + strlen("addr="), mMixAddress.c_str(),
AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - strlen("addr=") - 1) == 0)) {
@@ -1499,10 +1546,10 @@
std::unique_ptr<RecordingActivityTracker> mTracker;
- std::vector<PolicyMixTuple> mSourceRules = {
- {AUDIO_USAGE_UNKNOWN, AUDIO_SOURCE_CAMCORDER, RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET},
- {AUDIO_USAGE_UNKNOWN, AUDIO_SOURCE_MIC, RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET},
- {AUDIO_USAGE_UNKNOWN, AUDIO_SOURCE_VOICE_COMMUNICATION, RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET}
+ std::vector<AudioMixMatchCriterion> mSourceRules = {
+ createCapturePresetCriterion(AUDIO_SOURCE_CAMCORDER),
+ createCapturePresetCriterion(AUDIO_SOURCE_MIC),
+ createCapturePresetCriterion(AUDIO_SOURCE_VOICE_COMMUNICATION)
};
struct audio_port_v7 mExtractionPort;
@@ -1562,9 +1609,10 @@
audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE;
getInputForAttr(attr, mTracker->getRiid(), &captureRoutedPortId, AUDIO_FORMAT_PCM_16_BIT,
AUDIO_CHANNEL_IN_STEREO, k48000SamplingRate, AUDIO_INPUT_FLAG_NONE, &portId);
- if (std::find_if(begin(mSourceRules), end(mSourceRules), [&source](const auto &sourceRule) {
- return (std::get<1>(sourceRule) == source) &&
- (std::get<2>(sourceRule) == RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET);})
+ if (std::find_if(begin(mSourceRules), end(mSourceRules),
+ [&source](const AudioMixMatchCriterion &c) {
+ return c.mRule == RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET &&
+ c.mValue.mSource == source;})
!= end(mSourceRules)) {
EXPECT_EQ(mExtractionPort.id, captureRoutedPortId);
} else {
@@ -1801,7 +1849,7 @@
audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
const std::string kTestBusMediaOutput = "bus0_media_out";
ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
- AUDIO_DEVICE_OUT_BUS, kTestBusMediaOutput, audioConfig, std::vector<PolicyMixTuple>());
+ AUDIO_DEVICE_OUT_BUS, kTestBusMediaOutput, audioConfig);
ASSERT_EQ(NO_ERROR, ret);
audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;