Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d9cd2923 authored by Jean-Michel Trivi's avatar Jean-Michel Trivi Committed by Android (Google) Code Review
Browse files

Merge "Dynamic audio policies: JNI support for UID rules" into nyc-dev

parents 9ca8ed93 ba6b4b40
Loading
Loading
Loading
Loading
+31 −18
Original line number Diff line number Diff line
@@ -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,
        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.mAttr.mSource = (audio_source_t)env->GetIntField(jAttributes,
                nCriterion.mValue.mSource = (audio_source_t)env->GetIntField(jAttributes,
                        gAudioAttributesFields.mSource);
            }
            env->DeleteLocalRef(jAttributes);
            }
            break;
        }

        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");
+18 −18
Original line number Diff line number Diff line
@@ -42,7 +42,7 @@ import java.util.Objects;
@SystemApi
public class AudioMixingRule {

    private AudioMixingRule(int mixType, ArrayList<AttributeMatchCriterion> criteria) {
    private AudioMixingRule(int mixType, ArrayList<AudioMixMatchCriterion> 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<AttributeMatchCriterion> mCriteria;
    ArrayList<AttributeMatchCriterion> getCriteria() { return mCriteria; }
    private final ArrayList<AudioMixMatchCriterion> mCriteria;
    ArrayList<AudioMixMatchCriterion> getCriteria() { return mCriteria; }

    @Override
    public int hashCode() {
@@ -205,7 +205,7 @@ public class AudioMixingRule {
     */
    @SystemApi
    public static class Builder {
        private ArrayList<AttributeMatchCriterion> mCriteria;
        private ArrayList<AudioMixMatchCriterion> mCriteria;
        private int mTargetMixType = AudioMix.MIX_TYPE_INVALID;

        /**
@@ -213,7 +213,7 @@ public class AudioMixingRule {
         */
        @SystemApi
        public Builder() {
            mCriteria = new ArrayList<AttributeMatchCriterion>();
            mCriteria = new ArrayList<AudioMixMatchCriterion>();
        }

        /**
@@ -378,10 +378,10 @@ public class AudioMixingRule {
                throw new IllegalArgumentException("Incompatible rule for mix");
            }
            synchronized (mCriteria) {
                Iterator<AttributeMatchCriterion> crIterator = mCriteria.iterator();
                Iterator<AudioMixMatchCriterion> 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()");
+7 −7
Original line number Diff line number Diff line
@@ -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<AttributeMatchCriterion> criteria = mix.getRule().getCriteria();
            final ArrayList<AudioMixMatchCriterion> 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<AttributeMatchCriterion> criteria = mix.getRule().getCriteria();
            for (AttributeMatchCriterion criterion : criteria) {
            final ArrayList<AudioMixMatchCriterion> 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!";