summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/api/system-current.txt1
-rw-r--r--core/jni/android_media_AudioSystem.cpp5
-rw-r--r--media/java/android/media/audiopolicy/AudioMixingRule.java32
-rw-r--r--media/java/android/media/audiopolicy/AudioPolicyConfig.java8
-rw-r--r--media/tests/AudioPolicyTest/src/com/android/audiopolicytest/AudioMixingRuleUnitTests.java57
5 files changed, 98 insertions, 5 deletions
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 5e1c2347664b..e89269a70f68 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -6534,6 +6534,7 @@ package android.media.audiopolicy {
field public static final int MIX_ROLE_PLAYERS = 0; // 0x0
field public static final int RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET = 2; // 0x2
field public static final int RULE_MATCH_ATTRIBUTE_USAGE = 1; // 0x1
+ field public static final int RULE_MATCH_AUDIO_SESSION_ID = 16; // 0x10
field public static final int RULE_MATCH_UID = 4; // 0x4
field public static final int RULE_MATCH_USERID = 8; // 0x8
}
diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp
index 77317d1c3c1a..2433a05a4e9b 100644
--- a/core/jni/android_media_AudioSystem.cpp
+++ b/core/jni/android_media_AudioSystem.cpp
@@ -2160,6 +2160,11 @@ static jint convertAudioMixToNative(JNIEnv *env,
nCriterion.mValue.mUserId =
env->GetIntField(jCriterion, gAudioMixMatchCriterionFields.mIntProp);
break;
+ case RULE_MATCH_AUDIO_SESSION_ID: {
+ jint jAudioSessionId =
+ env->GetIntField(jCriterion, gAudioMixMatchCriterionFields.mIntProp);
+ nCriterion.mValue.mAudioSessionId = static_cast<audio_session_t>(jAudioSessionId);
+ } break;
case RULE_MATCH_ATTRIBUTE_USAGE:
case RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET: {
jobject jAttributes = env->GetObjectField(jCriterion, gAudioMixMatchCriterionFields.mAttr);
diff --git a/media/java/android/media/audiopolicy/AudioMixingRule.java b/media/java/android/media/audiopolicy/AudioMixingRule.java
index 6aead4337245..08655ca6ad6b 100644
--- a/media/java/android/media/audiopolicy/AudioMixingRule.java
+++ b/media/java/android/media/audiopolicy/AudioMixingRule.java
@@ -87,6 +87,13 @@ public class AudioMixingRule {
* parameter is an instance of {@link java.lang.Integer}.
*/
public static final int RULE_MATCH_USERID = 0x1 << 3;
+ /**
+ * A rule requiring the audio session id of the audio stream to match that specified.
+ * This mixing rule can be added with {@link Builder#addMixRule(int, Object)} where Object
+ * parameter is an instance of {@link java.lang.Integer}.
+ * @see android.media.AudioTrack.Builder#setSessionId
+ */
+ public static final int RULE_MATCH_AUDIO_SESSION_ID = 0x1 << 4;
private final static int RULE_EXCLUSION_MASK = 0x8000;
/**
@@ -115,6 +122,13 @@ public class AudioMixingRule {
public static final int RULE_EXCLUDE_USERID =
RULE_EXCLUSION_MASK | RULE_MATCH_USERID;
+ /**
+ * @hide
+ * A rule requiring the audio session id information to differ.
+ */
+ public static final int RULE_EXCLUDE_AUDIO_SESSION_ID =
+ RULE_EXCLUSION_MASK | RULE_MATCH_AUDIO_SESSION_ID;
+
/** @hide */
public static final class AudioMixMatchCriterion {
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
@@ -166,6 +180,7 @@ public class AudioMixingRule {
break;
case RULE_MATCH_UID:
case RULE_MATCH_USERID:
+ case RULE_MATCH_AUDIO_SESSION_ID:
dest.writeInt(mIntProp);
break;
default:
@@ -315,6 +330,7 @@ public class AudioMixingRule {
case RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET:
case RULE_MATCH_UID:
case RULE_MATCH_USERID:
+ case RULE_MATCH_AUDIO_SESSION_ID:
return true;
default:
return false;
@@ -338,6 +354,7 @@ public class AudioMixingRule {
case RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET:
case RULE_MATCH_UID:
case RULE_MATCH_USERID:
+ case RULE_MATCH_AUDIO_SESSION_ID:
return true;
default:
return false;
@@ -445,7 +462,8 @@ public class AudioMixingRule {
* @param rule one of {@link AudioMixingRule#RULE_MATCH_ATTRIBUTE_USAGE},
* {@link AudioMixingRule#RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET} or
* {@link AudioMixingRule#RULE_MATCH_UID} or
- * {@link AudioMixingRule#RULE_MATCH_USERID}.
+ * {@link AudioMixingRule#RULE_MATCH_USERID} or
+ * {@link AudioMixingRule#RULE_MATCH_AUDIO_SESSION_ID}.
* @param property see the definition of each rule for the type to use (either an
* {@link AudioAttributes} or an {@link java.lang.Integer}).
* @return the same Builder instance.
@@ -476,7 +494,8 @@ public class AudioMixingRule {
* @param rule one of {@link AudioMixingRule#RULE_MATCH_ATTRIBUTE_USAGE},
* {@link AudioMixingRule#RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET} or
* {@link AudioMixingRule#RULE_MATCH_UID} or
- * {@link AudioMixingRule#RULE_MATCH_USERID}.
+ * {@link AudioMixingRule#RULE_MATCH_USERID} or
+ * {@link AudioMixingRule#RULE_MATCH_AUDIO_SESSION_ID}.
* @param property see the definition of each rule for the type to use (either an
* {@link AudioAttributes} or an {@link java.lang.Integer}).
* @return the same Builder instance.
@@ -606,9 +625,12 @@ public class AudioMixingRule {
* @param intProp an integer property to match or exclude, null if not used.
* @param rule one of {@link AudioMixingRule#RULE_EXCLUDE_ATTRIBUTE_USAGE},
* {@link AudioMixingRule#RULE_MATCH_ATTRIBUTE_USAGE},
- * {@link AudioMixingRule#RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET} or
+ * {@link AudioMixingRule#RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET},
* {@link AudioMixingRule#RULE_EXCLUDE_ATTRIBUTE_CAPTURE_PRESET},
- * {@link AudioMixingRule#RULE_MATCH_UID}, {@link AudioMixingRule#RULE_EXCLUDE_UID}.
+ * {@link AudioMixingRule#RULE_MATCH_UID},
+ * {@link AudioMixingRule#RULE_EXCLUDE_UID},
+ * {@link AudioMixingRule#RULE_MATCH_AUDIO_SESSION_ID},
+ * {@link AudioMixingRule#RULE_EXCLUDE_AUDIO_SESSION_ID}
* {@link AudioMixingRule#RULE_MATCH_USERID},
* {@link AudioMixingRule#RULE_EXCLUDE_USERID}.
* @return the same Builder instance.
@@ -645,6 +667,7 @@ public class AudioMixingRule {
break;
case RULE_MATCH_UID:
case RULE_MATCH_USERID:
+ case RULE_MATCH_AUDIO_SESSION_ID:
mCriteria.add(new AudioMixMatchCriterion(intProp, rule));
break;
default:
@@ -666,6 +689,7 @@ public class AudioMixingRule {
break;
case RULE_MATCH_UID:
case RULE_MATCH_USERID:
+ case RULE_MATCH_AUDIO_SESSION_ID:
intProp = new Integer(in.readInt());
break;
default:
diff --git a/media/java/android/media/audiopolicy/AudioPolicyConfig.java b/media/java/android/media/audiopolicy/AudioPolicyConfig.java
index f3731b68f787..440447e5ec1d 100644
--- a/media/java/android/media/audiopolicy/AudioPolicyConfig.java
+++ b/media/java/android/media/audiopolicy/AudioPolicyConfig.java
@@ -217,6 +217,14 @@ public class AudioPolicyConfig implements Parcelable {
textDump += " exclude userId ";
textDump += criterion.mIntProp;
break;
+ case AudioMixingRule.RULE_MATCH_AUDIO_SESSION_ID:
+ textDump += " match audio session id";
+ textDump += criterion.mIntProp;
+ break;
+ case AudioMixingRule.RULE_EXCLUDE_AUDIO_SESSION_ID:
+ textDump += " exclude audio session id ";
+ textDump += criterion.mIntProp;
+ break;
default:
textDump += "invalid rule!";
}
diff --git a/media/tests/AudioPolicyTest/src/com/android/audiopolicytest/AudioMixingRuleUnitTests.java b/media/tests/AudioPolicyTest/src/com/android/audiopolicytest/AudioMixingRuleUnitTests.java
index ad7ab971d5f2..a83e7d3a6ef1 100644
--- a/media/tests/AudioPolicyTest/src/com/android/audiopolicytest/AudioMixingRuleUnitTests.java
+++ b/media/tests/AudioPolicyTest/src/com/android/audiopolicytest/AudioMixingRuleUnitTests.java
@@ -22,9 +22,11 @@ import static android.media.audiopolicy.AudioMixingRule.MIX_ROLE_INJECTOR;
import static android.media.audiopolicy.AudioMixingRule.MIX_ROLE_PLAYERS;
import static android.media.audiopolicy.AudioMixingRule.RULE_EXCLUDE_ATTRIBUTE_CAPTURE_PRESET;
import static android.media.audiopolicy.AudioMixingRule.RULE_EXCLUDE_ATTRIBUTE_USAGE;
+import static android.media.audiopolicy.AudioMixingRule.RULE_EXCLUDE_AUDIO_SESSION_ID;
import static android.media.audiopolicy.AudioMixingRule.RULE_EXCLUDE_UID;
import static android.media.audiopolicy.AudioMixingRule.RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET;
import static android.media.audiopolicy.AudioMixingRule.RULE_MATCH_ATTRIBUTE_USAGE;
+import static android.media.audiopolicy.AudioMixingRule.RULE_MATCH_AUDIO_SESSION_ID;
import static android.media.audiopolicy.AudioMixingRule.RULE_MATCH_UID;
import static org.hamcrest.MatcherAssert.assertThat;
@@ -61,12 +63,14 @@ public class AudioMixingRuleUnitTests {
new AudioAttributes.Builder().setCapturePreset(VOICE_RECOGNITION).build();
private static final int TEST_UID = 42;
private static final int OTHER_UID = 77;
+ private static final int TEST_SESSION_ID = 1234;
@Test
public void testConstructValidRule() {
AudioMixingRule rule = new AudioMixingRule.Builder()
.addMixRule(RULE_MATCH_ATTRIBUTE_USAGE, USAGE_MEDIA_AUDIO_ATTRIBUTES)
.addMixRule(RULE_MATCH_UID, TEST_UID)
+ .excludeMixRule(RULE_MATCH_AUDIO_SESSION_ID, TEST_SESSION_ID)
.build();
// Based on the rules, the mix type should fall back to MIX_ROLE_PLAYERS,
@@ -74,7 +78,8 @@ public class AudioMixingRuleUnitTests {
assertEquals(rule.getTargetMixRole(), MIX_ROLE_PLAYERS);
assertThat(rule.getCriteria(), containsInAnyOrder(
isAudioMixMatchUsageCriterion(USAGE_MEDIA),
- isAudioMixMatchUidCriterion(TEST_UID)));
+ isAudioMixMatchUidCriterion(TEST_UID),
+ isAudioMixExcludeSessionCriterion(TEST_SESSION_ID)));
}
@Test
@@ -183,6 +188,30 @@ public class AudioMixingRuleUnitTests {
.build());
}
+ @Test
+ public void sessionIdRuleCompatibleWithPlayersMix() {
+ int sessionId = 42;
+ AudioMixingRule rule = new AudioMixingRule.Builder()
+ .addMixRule(RULE_MATCH_AUDIO_SESSION_ID, sessionId)
+ .setTargetMixRole(MIX_ROLE_PLAYERS)
+ .build();
+
+ assertEquals(rule.getTargetMixRole(), MIX_ROLE_PLAYERS);
+ assertThat(rule.getCriteria(), containsInAnyOrder(isAudioMixSessionCriterion(sessionId)));
+ }
+
+ @Test
+ public void sessionIdRuleCompatibleWithInjectorMix() {
+ AudioMixingRule rule = new AudioMixingRule.Builder()
+ .addMixRule(RULE_MATCH_AUDIO_SESSION_ID, TEST_SESSION_ID)
+ .setTargetMixRole(MIX_ROLE_INJECTOR)
+ .build();
+
+ assertEquals(rule.getTargetMixRole(), MIX_ROLE_INJECTOR);
+ assertThat(rule.getCriteria(),
+ containsInAnyOrder(isAudioMixSessionCriterion(TEST_SESSION_ID)));
+ }
+
private static Matcher isAudioMixUidCriterion(int uid, boolean exclude) {
return new CustomTypeSafeMatcher<AudioMixMatchCriterion>("uid mix criterion") {
@@ -257,5 +286,31 @@ public class AudioMixingRuleUnitTests {
return isAudioMixUsageCriterion(usage, /*exclude=*/ false);
}
+ private static Matcher isAudioMixSessionCriterion(int sessionId, boolean exclude) {
+ return new CustomTypeSafeMatcher<AudioMixMatchCriterion>("sessionId mix criterion") {
+ @Override
+ public boolean matchesSafely(AudioMixMatchCriterion item) {
+ int excludeRule =
+ exclude ? RULE_EXCLUDE_AUDIO_SESSION_ID : RULE_MATCH_AUDIO_SESSION_ID;
+ return item.getRule() == excludeRule && item.getIntProp() == sessionId;
+ }
+
+ @Override
+ public void describeMismatchSafely(
+ AudioMixMatchCriterion item, Description mismatchDescription) {
+ mismatchDescription.appendText(
+ String.format("is not %s criterion with session id %d",
+ exclude ? "exclude" : "match", sessionId));
+ }
+ };
+ }
+
+ private static Matcher isAudioMixSessionCriterion(int sessionId) {
+ return isAudioMixSessionCriterion(sessionId, /*exclude=*/ false);
+ }
+
+ private static Matcher isAudioMixExcludeSessionCriterion(int sessionId) {
+ return isAudioMixSessionCriterion(sessionId, /*exclude=*/ true);
+ }
}