From ba6b4b400d850ba18fcb9d5bf9789d490f390acc Mon Sep 17 00:00:00 2001 From: Jean-Michel Trivi Date: Wed, 10 Feb 2016 14:26:35 -0800 Subject: [PATCH] Dynamic audio policies: JNI support for UID rules Rename AttributeMatchCriterion to AudioMixMatchCriterion to be consistent with the fact that now mixing rules are not always about audio attributes. AudioSystem JNI: add support for UID-based rules. Bug 26798796 Change-Id: Icb0f57841c94f410e1fac9ed071a829a26b9a58e --- core/jni/android_media_AudioSystem.cpp | 49 ++++++++++++++-------- .../android/media/audiopolicy/AudioMixingRule.java | 36 ++++++++-------- .../media/audiopolicy/AudioPolicyConfig.java | 14 +++---- 3 files changed, 56 insertions(+), 43 deletions(-) diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp index 8e8f6c371204..80f8a64122e3 100644 --- a/core/jni/android_media_AudioSystem.cpp +++ b/core/jni/android_media_AudioSystem.cpp @@ -128,11 +128,12 @@ static struct { // other fields unused by JNI } gAudioMixingRuleFields; -static jclass gAttributeMatchCriterionClass; +static jclass gAudioMixMatchCriterionClass; static struct { jfieldID mAttr; + jfieldID mIntProp; jfieldID mRule; -} gAttributeMatchCriterionFields; +} gAudioMixMatchCriterionFields; static jclass gAudioAttributesClass; static struct { @@ -1563,22 +1564,32 @@ static jint convertAudioMixToNative(JNIEnv *env, } for (jint i = 0; i < numCriteria; i++) { - AttributeMatchCriterion nCriterion; + AudioMixMatchCriterion nCriterion; jobject jCriterion = env->GetObjectArrayElement(jCriteria, i); - nCriterion.mRule = env->GetIntField(jCriterion, gAttributeMatchCriterionFields.mRule); + nCriterion.mRule = env->GetIntField(jCriterion, gAudioMixMatchCriterionFields.mRule); - jobject jAttributes = env->GetObjectField(jCriterion, gAttributeMatchCriterionFields.mAttr); - if (nCriterion.mRule == RULE_MATCH_ATTRIBUTE_USAGE || - nCriterion.mRule == RULE_EXCLUDE_ATTRIBUTE_USAGE) { - nCriterion.mAttr.mUsage = (audio_usage_t)env->GetIntField(jAttributes, - gAudioAttributesFields.mUsage); - } else { - nCriterion.mAttr.mSource = (audio_source_t)env->GetIntField(jAttributes, - gAudioAttributesFields.mSource); + const uint32_t match_rule = nCriterion.mRule & ~RULE_EXCLUSION_MASK; + switch (match_rule) { + case RULE_MATCH_UID: + nCriterion.mValue.mUid = env->GetIntField(jCriterion, + gAudioMixMatchCriterionFields.mIntProp); + break; + case RULE_MATCH_ATTRIBUTE_USAGE: + case RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET: { + jobject jAttributes = env->GetObjectField(jCriterion, gAudioMixMatchCriterionFields.mAttr); + if (match_rule == RULE_MATCH_ATTRIBUTE_USAGE) { + nCriterion.mValue.mUsage = (audio_usage_t)env->GetIntField(jAttributes, + gAudioAttributesFields.mUsage); + } else { + nCriterion.mValue.mSource = (audio_source_t)env->GetIntField(jAttributes, + gAudioAttributesFields.mSource); + } + env->DeleteLocalRef(jAttributes); + } + break; } - env->DeleteLocalRef(jAttributes); nAudioMix->mCriteria.add(nCriterion); env->DeleteLocalRef(jCriterion); @@ -1833,12 +1844,14 @@ int register_android_media_AudioSystem(JNIEnv *env) gAudioMixingRuleFields.mCriteria = GetFieldIDOrDie(env, audioMixingRuleClass, "mCriteria", "Ljava/util/ArrayList;"); - jclass attributeMatchCriterionClass = - FindClassOrDie(env, "android/media/audiopolicy/AudioMixingRule$AttributeMatchCriterion"); - gAttributeMatchCriterionClass = MakeGlobalRefOrDie(env, attributeMatchCriterionClass); - gAttributeMatchCriterionFields.mAttr = GetFieldIDOrDie(env, attributeMatchCriterionClass, "mAttr", + jclass audioMixMatchCriterionClass = + FindClassOrDie(env, "android/media/audiopolicy/AudioMixingRule$AudioMixMatchCriterion"); + gAudioMixMatchCriterionClass = MakeGlobalRefOrDie(env,audioMixMatchCriterionClass); + gAudioMixMatchCriterionFields.mAttr = GetFieldIDOrDie(env, audioMixMatchCriterionClass, "mAttr", "Landroid/media/AudioAttributes;"); - gAttributeMatchCriterionFields.mRule = GetFieldIDOrDie(env, attributeMatchCriterionClass, "mRule", + gAudioMixMatchCriterionFields.mIntProp = GetFieldIDOrDie(env, audioMixMatchCriterionClass, "mIntProp", + "I"); + gAudioMixMatchCriterionFields.mRule = GetFieldIDOrDie(env, audioMixMatchCriterionClass, "mRule", "I"); jclass audioAttributesClass = FindClassOrDie(env, "android/media/AudioAttributes"); diff --git a/media/java/android/media/audiopolicy/AudioMixingRule.java b/media/java/android/media/audiopolicy/AudioMixingRule.java index 54543ec43f89..e197141e0214 100644 --- a/media/java/android/media/audiopolicy/AudioMixingRule.java +++ b/media/java/android/media/audiopolicy/AudioMixingRule.java @@ -42,7 +42,7 @@ import java.util.Objects; @SystemApi public class AudioMixingRule { - private AudioMixingRule(int mixType, ArrayList criteria) { + private AudioMixingRule(int mixType, ArrayList criteria) { mCriteria = criteria; mTargetMixType = mixType; } @@ -91,21 +91,21 @@ public class AudioMixingRule { public static final int RULE_EXCLUDE_UID = RULE_EXCLUSION_MASK | RULE_MATCH_UID; - static final class AttributeMatchCriterion { + static final class AudioMixMatchCriterion { final AudioAttributes mAttr; - final Integer mIntProp; + final int mIntProp; final int mRule; /** input parameters must be valid */ - AttributeMatchCriterion(AudioAttributes attributes, int rule) { + AudioMixMatchCriterion(AudioAttributes attributes, int rule) { mAttr = attributes; - mIntProp = null; + mIntProp = Integer.MIN_VALUE; mRule = rule; } /** input parameters must be valid */ - AttributeMatchCriterion(Integer intProp, int rule) { + AudioMixMatchCriterion(Integer intProp, int rule) { mAttr = null; - mIntProp = intProp; + mIntProp = intProp.intValue(); mRule = rule; } @@ -125,10 +125,10 @@ public class AudioMixingRule { dest.writeInt(mAttr.getCapturePreset()); break; case RULE_MATCH_UID: - dest.writeInt(mIntProp.intValue()); + dest.writeInt(mIntProp); break; default: - Log.e("AttributeMatchCriterion", "Unknown match rule" + match_rule + Log.e("AudioMixMatchCriterion", "Unknown match rule" + match_rule + " when writing to Parcel"); dest.writeInt(-1); } @@ -137,8 +137,8 @@ public class AudioMixingRule { private final int mTargetMixType; int getTargetMixType() { return mTargetMixType; } - private final ArrayList mCriteria; - ArrayList getCriteria() { return mCriteria; } + private final ArrayList mCriteria; + ArrayList getCriteria() { return mCriteria; } @Override public int hashCode() { @@ -205,7 +205,7 @@ public class AudioMixingRule { */ @SystemApi public static class Builder { - private ArrayList mCriteria; + private ArrayList mCriteria; private int mTargetMixType = AudioMix.MIX_TYPE_INVALID; /** @@ -213,7 +213,7 @@ public class AudioMixingRule { */ @SystemApi public Builder() { - mCriteria = new ArrayList(); + mCriteria = new ArrayList(); } /** @@ -378,10 +378,10 @@ public class AudioMixingRule { throw new IllegalArgumentException("Incompatible rule for mix"); } synchronized (mCriteria) { - Iterator crIterator = mCriteria.iterator(); + Iterator crIterator = mCriteria.iterator(); final int match_rule = rule & ~RULE_EXCLUSION_MASK; while (crIterator.hasNext()) { - final AttributeMatchCriterion criterion = crIterator.next(); + final AudioMixMatchCriterion criterion = crIterator.next(); switch (match_rule) { case RULE_MATCH_ATTRIBUTE_USAGE: // "usage"-based rule @@ -413,7 +413,7 @@ public class AudioMixingRule { break; case RULE_MATCH_UID: // "usage"-based rule - if (criterion.mIntProp.intValue() == intProp.intValue()) { + if (criterion.mIntProp == intProp.intValue()) { if (criterion.mRule == rule) { // rule already exists, we're done return this; @@ -431,10 +431,10 @@ public class AudioMixingRule { switch (match_rule) { case RULE_MATCH_ATTRIBUTE_USAGE: case RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET: - mCriteria.add(new AttributeMatchCriterion(attrToMatch, rule)); + mCriteria.add(new AudioMixMatchCriterion(attrToMatch, rule)); break; case RULE_MATCH_UID: - mCriteria.add(new AttributeMatchCriterion(intProp, rule)); + mCriteria.add(new AudioMixMatchCriterion(intProp, rule)); break; default: throw new IllegalStateException("Unreachable code in addRuleInternal()"); diff --git a/media/java/android/media/audiopolicy/AudioPolicyConfig.java b/media/java/android/media/audiopolicy/AudioPolicyConfig.java index 5ad61265f439..5d2bac02a5e0 100644 --- a/media/java/android/media/audiopolicy/AudioPolicyConfig.java +++ b/media/java/android/media/audiopolicy/AudioPolicyConfig.java @@ -17,7 +17,7 @@ package android.media.audiopolicy; import android.media.AudioFormat; -import android.media.audiopolicy.AudioMixingRule.AttributeMatchCriterion; +import android.media.audiopolicy.AudioMixingRule.AudioMixMatchCriterion; import android.os.Parcel; import android.os.Parcelable; import android.util.Log; @@ -86,9 +86,9 @@ public class AudioPolicyConfig implements Parcelable { dest.writeInt(mix.getFormat().getEncoding()); dest.writeInt(mix.getFormat().getChannelMask()); // write mix rules - final ArrayList criteria = mix.getRule().getCriteria(); + final ArrayList criteria = mix.getRule().getCriteria(); dest.writeInt(criteria.size()); - for (AttributeMatchCriterion criterion : criteria) { + for (AudioMixMatchCriterion criterion : criteria) { criterion.writeToParcel(dest); } } @@ -150,8 +150,8 @@ public class AudioPolicyConfig implements Parcelable { textDump += " channels=0x"; textDump += Integer.toHexString(mix.getFormat().getChannelMask()).toUpperCase() +"\n"; // write mix rules - final ArrayList criteria = mix.getRule().getCriteria(); - for (AttributeMatchCriterion criterion : criteria) { + final ArrayList criteria = mix.getRule().getCriteria(); + for (AudioMixMatchCriterion criterion : criteria) { switch(criterion.mRule) { case AudioMixingRule.RULE_EXCLUDE_ATTRIBUTE_USAGE: textDump += " exclude usage "; @@ -171,11 +171,11 @@ public class AudioPolicyConfig implements Parcelable { break; case AudioMixingRule.RULE_MATCH_UID: textDump += " match UID "; - textDump += criterion.mIntProp.toString(); + textDump += criterion.mIntProp; break; case AudioMixingRule.RULE_EXCLUDE_UID: textDump += " exclude UID "; - textDump += criterion.mIntProp.toString(); + textDump += criterion.mIntProp; break; default: textDump += "invalid rule!"; -- 2.11.0