UID mixing rule support both RECORDERS and PLAYERS mix type
Export API in AudioMixingRule#Builder to allow application specify the mix type when using UID mixing rule.
Bug: 169964607
Test: atest com.google.android.gts.audio.AudioHostTest, manual testing
Change-Id: Icf7c83f280aeec7b11aa3bc43fb31657c863e7fd
diff --git a/media/java/android/media/audiopolicy/AudioMixingRule.java b/media/java/android/media/audiopolicy/AudioMixingRule.java
index 1f07705..cb47ba2 100644
--- a/media/java/android/media/audiopolicy/AudioMixingRule.java
+++ b/media/java/android/media/audiopolicy/AudioMixingRule.java
@@ -291,7 +291,6 @@
final int match_rule = rule & ~RULE_EXCLUSION_MASK;
switch (match_rule) {
case RULE_MATCH_ATTRIBUTE_USAGE:
- case RULE_MATCH_UID:
case RULE_MATCH_USERID:
return true;
default:
@@ -299,6 +298,16 @@
}
}
+ private static boolean isRecorderRule(int rule) {
+ final int match_rule = rule & ~RULE_EXCLUSION_MASK;
+ switch (match_rule) {
+ case RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET:
+ return true;
+ default:
+ return false;
+ }
+ }
+
private static boolean isAudioAttributeRule(int match_rule) {
switch(match_rule) {
case RULE_MATCH_ATTRIBUTE_USAGE:
@@ -460,6 +469,23 @@
}
/**
+ * Set target mix type of the mixing rule.
+ *
+ * <p>Note: If the mix type was not specified, it will be decided automatically by mixing
+ * rule. For {@link #RULE_MATCH_UID}, the default type is {@link AudioMix#MIX_TYPE_PLAYERS}.
+ *
+ * @param mixType {@link AudioMix#MIX_TYPE_PLAYERS} or {@link AudioMix#MIX_TYPE_RECORDERS}
+ * @return the same Builder instance.
+ *
+ * @hide
+ */
+ public @NonNull Builder setTargetMixType(int mixType) {
+ mTargetMixType = mixType;
+ Log.i("AudioMixingRule", "Builder setTargetMixType " + mixType);
+ return this;
+ }
+
+ /**
* Add or exclude a rule for the selection of which streams are mixed together.
* Does error checking on the parameters.
* @param rule
@@ -515,11 +541,15 @@
if (mTargetMixType == AudioMix.MIX_TYPE_INVALID) {
if (isPlayerRule(rule)) {
mTargetMixType = AudioMix.MIX_TYPE_PLAYERS;
- } else {
+ } else if (isRecorderRule(rule)) {
mTargetMixType = AudioMix.MIX_TYPE_RECORDERS;
+ } else {
+ // For rules which are not player or recorder specific (e.g. RULE_MATCH_UID),
+ // the default mix type is MIX_TYPE_PLAYERS.
+ mTargetMixType = AudioMix.MIX_TYPE_PLAYERS;
}
- } else if (((mTargetMixType == AudioMix.MIX_TYPE_PLAYERS) && !isPlayerRule(rule))
- || ((mTargetMixType == AudioMix.MIX_TYPE_RECORDERS) && isPlayerRule(rule)))
+ } else if ((isPlayerRule(rule) && (mTargetMixType != AudioMix.MIX_TYPE_PLAYERS))
+ || (isRecorderRule(rule)) && (mTargetMixType != AudioMix.MIX_TYPE_RECORDERS))
{
throw new IllegalArgumentException("Incompatible rule for mix");
}
diff --git a/media/java/android/media/audiopolicy/AudioPolicyConfig.java b/media/java/android/media/audiopolicy/AudioPolicyConfig.java
index ede68bd..346edc3 100644
--- a/media/java/android/media/audiopolicy/AudioPolicyConfig.java
+++ b/media/java/android/media/audiopolicy/AudioPolicyConfig.java
@@ -100,6 +100,8 @@
dest.writeBoolean(mix.getRule().allowPrivilegedMediaPlaybackCapture());
// write voice communication capture allowed flag
dest.writeBoolean(mix.getRule().voiceCommunicationCaptureAllowed());
+ // write specified mix type
+ dest.writeInt(mix.getRule().getTargetMixType());
// write mix rules
final ArrayList<AudioMixMatchCriterion> criteria = mix.getRule().getCriteria();
dest.writeInt(criteria.size());
@@ -134,6 +136,8 @@
ruleBuilder.allowPrivilegedPlaybackCapture(in.readBoolean());
// read voice capture allowed flag
ruleBuilder.voiceCommunicationCaptureAllowed(in.readBoolean());
+ // read specified mix type
+ ruleBuilder.setTargetMixType(in.readInt());
// read mix rules
int nbRules = in.readInt();
for (int j = 0 ; j < nbRules ; j++) {
@@ -176,6 +180,8 @@
textDump += " allow voice communication capture="
+ mix.getRule().voiceCommunicationCaptureAllowed() + "\n";
// write mix rules
+ textDump += " specified mix type="
+ + mix.getRule().getTargetMixType() + "\n";
final ArrayList<AudioMixMatchCriterion> criteria = mix.getRule().getCriteria();
for (AudioMixMatchCriterion criterion : criteria) {
switch(criterion.mRule) {