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

Commit b288d9d2 authored by Ján Sebechlebský's avatar Ján Sebechlebský Committed by Android (Google) Code Review
Browse files

Merge changes from topic "update_mix_rule" into main

* changes:
  Move AudioMix related unit tests to CTS
  Add API to update mix rule for registered AudioMix-es
  Make AudioMix, AudioMixMatchCriterion & AudioMixingRule Parcelable
parents 26b682c0 18c19668
Loading
Loading
Loading
Loading
+11 −4
Original line number Diff line number Diff line
@@ -7286,8 +7286,11 @@ package android.media.audiofx {
package android.media.audiopolicy {
  public class AudioMix {
  public class AudioMix implements android.os.Parcelable {
    method public int describeContents();
    method public int getMixState();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.media.audiopolicy.AudioMix> CREATOR;
    field public static final int MIX_STATE_DISABLED = -1; // 0xffffffff
    field public static final int MIX_STATE_IDLE = 0; // 0x0
    field public static final int MIX_STATE_MIXING = 1; // 0x1
@@ -7296,15 +7299,18 @@ package android.media.audiopolicy {
  }
  public static class AudioMix.Builder {
    ctor public AudioMix.Builder(android.media.audiopolicy.AudioMixingRule) throws java.lang.IllegalArgumentException;
    ctor public AudioMix.Builder(@NonNull android.media.audiopolicy.AudioMixingRule) throws java.lang.IllegalArgumentException;
    method public android.media.audiopolicy.AudioMix build() throws java.lang.IllegalArgumentException;
    method public android.media.audiopolicy.AudioMix.Builder setDevice(@NonNull android.media.AudioDeviceInfo) throws java.lang.IllegalArgumentException;
    method public android.media.audiopolicy.AudioMix.Builder setFormat(android.media.AudioFormat) throws java.lang.IllegalArgumentException;
    method public android.media.audiopolicy.AudioMix.Builder setFormat(@NonNull android.media.AudioFormat) throws java.lang.IllegalArgumentException;
    method public android.media.audiopolicy.AudioMix.Builder setRouteFlags(int) throws java.lang.IllegalArgumentException;
  }
  public class AudioMixingRule {
  public class AudioMixingRule implements android.os.Parcelable {
    method public int describeContents();
    method public int getTargetMixRole();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.media.audiopolicy.AudioMixingRule> CREATOR;
    field public static final int MIX_ROLE_INJECTOR = 1; // 0x1
    field public static final int MIX_ROLE_PLAYERS = 0; // 0x0
    field public static final int RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET = 2; // 0x2
@@ -7341,6 +7347,7 @@ package android.media.audiopolicy {
    method public boolean setUidDeviceAffinity(int, @NonNull java.util.List<android.media.AudioDeviceInfo>);
    method public boolean setUserIdDeviceAffinity(int, @NonNull java.util.List<android.media.AudioDeviceInfo>);
    method public String toLogFriendlyString();
    method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int updateMixingRules(@NonNull java.util.List<android.util.Pair<android.media.audiopolicy.AudioMix,android.media.audiopolicy.AudioMixingRule>>);
    field public static final int FOCUS_POLICY_DUCKING_DEFAULT = 0; // 0x0
    field public static final int FOCUS_POLICY_DUCKING_IN_APP = 0; // 0x0
    field public static final int FOCUS_POLICY_DUCKING_IN_POLICY = 1; // 0x1
+107 −60
Original line number Diff line number Diff line
@@ -2071,35 +2071,10 @@ jobject convertAudioMixerAttributesFromNative(JNIEnv *env,
                          mixerBehavior);
}

static jint convertAudioMixToNative(JNIEnv *env,
                                    AudioMix *nAudioMix,
                                    const jobject jAudioMix)
{
    nAudioMix->mMixType = env->GetIntField(jAudioMix, gAudioMixFields.mMixType);
    nAudioMix->mRouteFlags = env->GetIntField(jAudioMix, gAudioMixFields.mRouteFlags);
    nAudioMix->mDeviceType =
            static_cast<audio_devices_t>(env->GetIntField(jAudioMix, gAudioMixFields.mDeviceType));

    jstring jDeviceAddress =
            static_cast<jstring>(env->GetObjectField(jAudioMix, gAudioMixFields.mDeviceAddress));
    const char *nDeviceAddress = env->GetStringUTFChars(jDeviceAddress, NULL);
    nAudioMix->mDeviceAddress = String8(nDeviceAddress);
    env->ReleaseStringUTFChars(jDeviceAddress, nDeviceAddress);
    env->DeleteLocalRef(jDeviceAddress);

    nAudioMix->mCbFlags = env->GetIntField(jAudioMix, gAudioMixFields.mCallbackFlags);

    jobject jFormat = env->GetObjectField(jAudioMix, gAudioMixFields.mFormat);
    javaAudioFormatToNativeAudioConfig(env, &nAudioMix->mFormat, jFormat, false /*isInput*/);
    env->DeleteLocalRef(jFormat);
static jint convertAudioMixingRuleToNative(JNIEnv *env, const jobject audioMixingRule,
                                           std::vector<AudioMixMatchCriterion> *nCriteria) {
    jobject jRuleCriteria = env->GetObjectField(audioMixingRule, gAudioMixingRuleFields.mCriteria);

    jobject jRule = env->GetObjectField(jAudioMix, gAudioMixFields.mRule);
    jobject jRuleCriteria = env->GetObjectField(jRule, gAudioMixingRuleFields.mCriteria);
    nAudioMix->mAllowPrivilegedMediaPlaybackCapture =
            env->GetBooleanField(jRule, gAudioMixingRuleFields.mAllowPrivilegedPlaybackCapture);
    nAudioMix->mVoiceCommunicationCaptureAllowed =
            env->GetBooleanField(jRule, gAudioMixingRuleFields.mVoiceCommunicationCaptureAllowed);
    env->DeleteLocalRef(jRule);
    jobjectArray jCriteria = static_cast<jobjectArray>(
            env->CallObjectMethod(jRuleCriteria, gArrayListMethods.toArray));
    env->DeleteLocalRef(jRuleCriteria);
@@ -2109,8 +2084,9 @@ static jint convertAudioMixToNative(JNIEnv *env,
        numCriteria = MAX_CRITERIA_PER_MIX;
    }

    nCriteria->resize(numCriteria);
    for (jint i = 0; i < numCriteria; i++) {
        AudioMixMatchCriterion nCriterion;
        AudioMixMatchCriterion &nCriterion = (*nCriteria)[i];

        jobject jCriterion = env->GetObjectArrayElement(jCriteria, i);

@@ -2119,8 +2095,8 @@ static jint convertAudioMixToNative(JNIEnv *env,
        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);
                nCriterion.mValue.mUid =
                        env->GetIntField(jCriterion, gAudioMixMatchCriterionFields.mIntProp);
                break;
            case RULE_MATCH_USERID:
                nCriterion.mValue.mUserId =
@@ -2133,7 +2109,8 @@ static jint convertAudioMixToNative(JNIEnv *env,
            } break;
            case RULE_MATCH_ATTRIBUTE_USAGE:
            case RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET: {
            jobject jAttributes = env->GetObjectField(jCriterion, gAudioMixMatchCriterionFields.mAttr);
                jobject jAttributes =
                        env->GetObjectField(jCriterion, gAudioMixMatchCriterionFields.mAttr);

                auto paa = JNIAudioAttributeHelper::makeUnique();
                jint jStatus = JNIAudioAttributeHelper::nativeFromJava(env, jAttributes, paa.get());
@@ -2146,19 +2123,46 @@ static jint convertAudioMixToNative(JNIEnv *env,
                    nCriterion.mValue.mSource = paa->source;
                }
                env->DeleteLocalRef(jAttributes);
            } break;
        }
            break;
        }

        nAudioMix->mCriteria.push_back(nCriterion);
        env->DeleteLocalRef(jCriterion);
    }

    env->DeleteLocalRef(jCriteria);

    return AUDIO_JAVA_SUCCESS;
}

static jint convertAudioMixToNative(JNIEnv *env, AudioMix *nAudioMix, const jobject jAudioMix) {
    nAudioMix->mMixType = env->GetIntField(jAudioMix, gAudioMixFields.mMixType);
    nAudioMix->mRouteFlags = env->GetIntField(jAudioMix, gAudioMixFields.mRouteFlags);
    nAudioMix->mDeviceType =
            static_cast<audio_devices_t>(env->GetIntField(jAudioMix, gAudioMixFields.mDeviceType));

    jstring jDeviceAddress =
            static_cast<jstring>(env->GetObjectField(jAudioMix, gAudioMixFields.mDeviceAddress));
    const char *nDeviceAddress = env->GetStringUTFChars(jDeviceAddress, NULL);
    nAudioMix->mDeviceAddress = String8(nDeviceAddress);
    env->ReleaseStringUTFChars(jDeviceAddress, nDeviceAddress);
    env->DeleteLocalRef(jDeviceAddress);

    nAudioMix->mCbFlags = env->GetIntField(jAudioMix, gAudioMixFields.mCallbackFlags);

    jobject jFormat = env->GetObjectField(jAudioMix, gAudioMixFields.mFormat);
    javaAudioFormatToNativeAudioConfig(env, &nAudioMix->mFormat, jFormat, false /*isInput*/);
    env->DeleteLocalRef(jFormat);

    jobject jRule = env->GetObjectField(jAudioMix, gAudioMixFields.mRule);
    nAudioMix->mAllowPrivilegedMediaPlaybackCapture =
            env->GetBooleanField(jRule, gAudioMixingRuleFields.mAllowPrivilegedPlaybackCapture);
    nAudioMix->mVoiceCommunicationCaptureAllowed =
            env->GetBooleanField(jRule, gAudioMixingRuleFields.mVoiceCommunicationCaptureAllowed);

    jint status = convertAudioMixingRuleToNative(env, jRule, &(nAudioMix->mCriteria));

    env->DeleteLocalRef(jRule);

    return status;
}

static jint
android_media_AudioSystem_registerPolicyMixes(JNIEnv *env, jobject clazz,
                                              jobject jMixesList, jboolean registration)
@@ -2200,6 +2204,45 @@ android_media_AudioSystem_registerPolicyMixes(JNIEnv *env, jobject clazz,
    return nativeToJavaStatus(status);
}

static jint android_media_AudioSystem_updatePolicyMixes(JNIEnv *env, jobject clazz,
                                                        jobjectArray mixes,
                                                        jobjectArray updatedMixingRules) {
    if (mixes == nullptr || updatedMixingRules == nullptr) {
        return AUDIO_JAVA_BAD_VALUE;
    }

    jsize updatesCount = env->GetArrayLength(mixes);
    if (updatesCount == 0 || updatesCount != env->GetArrayLength(updatedMixingRules)) {
        return AUDIO_JAVA_BAD_VALUE;
    }

    std::vector<std::pair<AudioMix, std::vector<AudioMixMatchCriterion>>> updates(updatesCount);
    for (int i = 0; i < updatesCount; i++) {
        jobject jAudioMix = env->GetObjectArrayElement(mixes, i);
        jobject jAudioMixingRule = env->GetObjectArrayElement(updatedMixingRules, i);
        if (!env->IsInstanceOf(jAudioMix, gAudioMixClass) ||
            !env->IsInstanceOf(jAudioMixingRule, gAudioMixingRuleClass)) {
            return AUDIO_JAVA_BAD_VALUE;
        }

        jint ret;
        if ((ret = convertAudioMixToNative(env, &updates[i].first, jAudioMix)) !=
            AUDIO_JAVA_SUCCESS) {
            return ret;
        }
        if ((ret = convertAudioMixingRuleToNative(env, jAudioMixingRule, &updates[i].second)) !=
            AUDIO_JAVA_SUCCESS) {
            return ret;
        }
    }

    ALOGV("AudioSystem::updatePolicyMixes numMixes %d", updatesCount);
    int status = AudioSystem::updatePolicyMixes(updates);
    ALOGV("AudioSystem::updatePolicyMixes returned %d", status);

    return nativeToJavaStatus(status);
}

static jint android_media_AudioSystem_setUidDeviceAffinities(JNIEnv *env, jobject clazz,
        jint uid, jintArray deviceTypes, jobjectArray deviceAddresses) {
    AudioDeviceTypeAddrVector deviceVector;
@@ -3158,6 +3201,10 @@ static const JNINativeMethod gMethods[] =
         MAKE_AUDIO_SYSTEM_METHOD(getAudioHwSyncForSession),
         MAKE_JNI_NATIVE_METHOD("registerPolicyMixes", "(Ljava/util/ArrayList;Z)I",
                                android_media_AudioSystem_registerPolicyMixes),
         MAKE_JNI_NATIVE_METHOD("updatePolicyMixes",
                                "([Landroid/media/audiopolicy/AudioMix;[Landroid/media/audiopolicy/"
                                "AudioMixingRule;)I",
                                android_media_AudioSystem_updatePolicyMixes),
         MAKE_JNI_NATIVE_METHOD("setUidDeviceAffinities", "(I[I[Ljava/lang/String;)I",
                                android_media_AudioSystem_setUidDeviceAffinities),
         MAKE_AUDIO_SYSTEM_METHOD(removeUidDeviceAffinities),
+6 −0
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import android.content.pm.PackageManager;
import android.media.audio.common.AidlConversion;
import android.media.audiofx.AudioEffect;
import android.media.audiopolicy.AudioMix;
import android.media.audiopolicy.AudioMixingRule;
import android.media.audiopolicy.AudioProductStrategy;
import android.os.Build;
import android.os.IBinder;
@@ -1955,6 +1956,11 @@ public class AudioSystem
    /** @hide */
    public static native int registerPolicyMixes(ArrayList<AudioMix> mixes, boolean register);

    /** @hide */
    public static native int updatePolicyMixes(
            AudioMix[] mixes,
            AudioMixingRule[] updatedMixingRules);

    /** @hide see AudioPolicy.setUidDeviceAffinities() */
    public static native int setUidDeviceAffinities(int uid, @NonNull int[] types,
            @NonNull String[] addresses);
+7 −0
Original line number Diff line number Diff line
@@ -54,6 +54,8 @@ import android.media.IVolumeController;
import android.media.PlayerBase;
import android.media.VolumeInfo;
import android.media.VolumePolicy;
import android.media.audiopolicy.AudioMix;
import android.media.audiopolicy.AudioMixingRule;
import android.media.audiopolicy.AudioPolicyConfig;
import android.media.audiopolicy.AudioProductStrategy;
import android.media.audiopolicy.AudioVolumeGroup;
@@ -356,6 +358,11 @@ interface IAudioService {

    int removeMixForPolicy(in AudioPolicyConfig policyConfig, in IAudioPolicyCallback pcb);

    @EnforcePermission("MODIFY_AUDIO_ROUTING")
    int updateMixingRulesForPolicy(in AudioMix[] mixesToUpdate,
                                   in AudioMixingRule[] updatedMixingRules,
                                   in IAudioPolicyCallback pcb);

    int setFocusPropertiesForPolicy(int duckingBehavior, in IAudioPolicyCallback pcb);

    void setVolumePolicy(in VolumePolicy policy);
+3 −0
Original line number Diff line number Diff line
package android.media.audiopolicy;

parcelable AudioMix;
 No newline at end of file
Loading