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

Commit 34ded2e8 authored by Francois Gaffie's avatar Francois Gaffie Committed by Eric Laurent
Browse files

[IMPR] AudioProductStrategy: get volume group from AudioAttributes



This CL adds an API to find a volume group from a given audio attributes.
It allows to fallback or not on default volume group.

Bug: 260298113
Test: adb shell am instrument -w -e class com.android.audiopolicytest.AudioManagerTest com.android.audiopolicytest
adb shell am instrument -w -e class com.android.audiopolicytest.AudioProductStrategyTest com.android.audiopolicytest
adb shell am instrument -w -e class com.android.audiopolicytest.AudioVolumeGroupTest com.android.audiopolicytest
adb shell am instrument -w -e class com.android.audiopolicytest.AudioVolumeGroupChangeHandlerTest com.android.audiopolicytest

Signed-off-by: default avatarFrancois Gaffie <francois.gaffie@renault.com>
Change-Id: I2aaf64fbe0c0fac3bb0110d847453eaf34f80792
parent a1c42fc8
Loading
Loading
Loading
Loading
+44 −9
Original line number Diff line number Diff line
@@ -28,11 +28,11 @@ import android.text.TextUtils;
import android.util.Log;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.Preconditions;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

/**
 * @hide
@@ -140,7 +140,7 @@ public final class AudioProductStrategy implements Parcelable {
     */
    public static int getLegacyStreamTypeForStrategyWithAudioAttributes(
            @NonNull AudioAttributes audioAttributes) {
        Preconditions.checkNotNull(audioAttributes, "AudioAttributes must not be null");
        Objects.requireNonNull(audioAttributes, "AudioAttributes must not be null");
        for (final AudioProductStrategy productStrategy :
                AudioProductStrategy.getAudioProductStrategies()) {
            if (productStrategy.supportsAudioAttributes(audioAttributes)) {
@@ -160,6 +160,30 @@ public final class AudioProductStrategy implements Parcelable {
        return AudioSystem.STREAM_MUSIC;
    }

    /**
     * @hide
     * @param attributes the {@link AudioAttributes} to identify VolumeGroupId with
     * @param fallbackOnDefault if set, allows to fallback on the default group (e.g. the group
     *                          associated to {@link AudioManager#STREAM_MUSIC}).
     * @return volume group id associated with the given {@link AudioAttributes} if found,
     *     default volume group id if fallbackOnDefault is set
     * <p>By convention, the product strategy with default attributes will be associated to the
     * default volume group (e.g. associated to {@link AudioManager#STREAM_MUSIC})
     * or {@link AudioVolumeGroup#DEFAULT_VOLUME_GROUP} if not found.
     */
    public static int getVolumeGroupIdForAudioAttributes(
            @NonNull AudioAttributes attributes, boolean fallbackOnDefault) {
        Objects.requireNonNull(attributes, "attributes must not be null");
        int volumeGroupId = getVolumeGroupIdForAudioAttributesInt(attributes);
        if (volumeGroupId != AudioVolumeGroup.DEFAULT_VOLUME_GROUP) {
            return volumeGroupId;
        }
        if (fallbackOnDefault) {
            return getVolumeGroupIdForAudioAttributesInt(getDefaultAttributes());
        }
        return AudioVolumeGroup.DEFAULT_VOLUME_GROUP;
    }

    private static List<AudioProductStrategy> initializeAudioProductStrategies() {
        ArrayList<AudioProductStrategy> apsList = new ArrayList<AudioProductStrategy>();
        int status = native_list_audio_product_strategies(apsList);
@@ -190,8 +214,8 @@ public final class AudioProductStrategy implements Parcelable {
     */
    private AudioProductStrategy(@NonNull String name, int id,
            @NonNull AudioAttributesGroup[] aag) {
        Preconditions.checkNotNull(name, "name must not be null");
        Preconditions.checkNotNull(aag, "AudioAttributesGroups must not be null");
        Objects.requireNonNull(name, "name must not be null");
        Objects.requireNonNull(aag, "AudioAttributesGroups must not be null");
        mName = name;
        mId = id;
        mAudioAttributesGroups = aag;
@@ -241,7 +265,7 @@ public final class AudioProductStrategy implements Parcelable {
     */
    @TestApi
    public int getLegacyStreamTypeForAudioAttributes(@NonNull AudioAttributes aa) {
        Preconditions.checkNotNull(aa, "AudioAttributes must not be null");
        Objects.requireNonNull(aa, "AudioAttributes must not be null");
        for (final AudioAttributesGroup aag : mAudioAttributesGroups) {
            if (aag.supportsAttributes(aa)) {
                return aag.getStreamType();
@@ -258,7 +282,7 @@ public final class AudioProductStrategy implements Parcelable {
     */
    @SystemApi
    public boolean supportsAudioAttributes(@NonNull AudioAttributes aa) {
        Preconditions.checkNotNull(aa, "AudioAttributes must not be null");
        Objects.requireNonNull(aa, "AudioAttributes must not be null");
        for (final AudioAttributesGroup aag : mAudioAttributesGroups) {
            if (aag.supportsAttributes(aa)) {
                return true;
@@ -291,7 +315,7 @@ public final class AudioProductStrategy implements Parcelable {
     */
    @TestApi
    public int getVolumeGroupIdForAudioAttributes(@NonNull AudioAttributes aa) {
        Preconditions.checkNotNull(aa, "AudioAttributes must not be null");
        Objects.requireNonNull(aa, "AudioAttributes must not be null");
        for (final AudioAttributesGroup aag : mAudioAttributesGroups) {
            if (aag.supportsAttributes(aa)) {
                return aag.getVolumeGroupId();
@@ -300,6 +324,17 @@ public final class AudioProductStrategy implements Parcelable {
        return AudioVolumeGroup.DEFAULT_VOLUME_GROUP;
    }

    private static int getVolumeGroupIdForAudioAttributesInt(@NonNull AudioAttributes attributes) {
        Objects.requireNonNull(attributes, "attributes must not be null");
        for (AudioProductStrategy productStrategy : getAudioProductStrategies()) {
            int volumeGroupId = productStrategy.getVolumeGroupIdForAudioAttributes(attributes);
            if (volumeGroupId != AudioVolumeGroup.DEFAULT_VOLUME_GROUP) {
                return volumeGroupId;
            }
        }
        return AudioVolumeGroup.DEFAULT_VOLUME_GROUP;
    }

    @Override
    public int describeContents() {
        return 0;
@@ -374,8 +409,8 @@ public final class AudioProductStrategy implements Parcelable {
     */
    private static boolean attributesMatches(@NonNull AudioAttributes refAttr,
            @NonNull AudioAttributes attr) {
        Preconditions.checkNotNull(refAttr, "refAttr must not be null");
        Preconditions.checkNotNull(attr, "attr must not be null");
        Objects.requireNonNull(refAttr, "reference AudioAttributes must not be null");
        Objects.requireNonNull(attr, "requester's AudioAttributes must not be null");
        String refFormattedTags = TextUtils.join(";", refAttr.getTags());
        String cliFormattedTags = TextUtils.join(";", attr.getTags());
        if (refAttr.equals(DEFAULT_ATTRIBUTES)) {
+7 −30
Original line number Diff line number Diff line
@@ -3785,12 +3785,13 @@ public class AudioService extends IAudioService.Stub
        super.setVolumeIndexForAttributes_enforcePermission();
        Objects.requireNonNull(attr, "attr must not be null");
        final int volumeGroup = getVolumeGroupIdForAttributes(attr);
        int volumeGroup = AudioProductStrategy.getVolumeGroupIdForAudioAttributes(
                attr, /* fallbackOnDefault= */false);
        if (sVolumeGroupStates.indexOfKey(volumeGroup) < 0) {
            Log.e(TAG, ": no volume group found for attributes " + attr.toString());
            return;
        }
        final VolumeGroupState vgs = sVolumeGroupStates.get(volumeGroup);
        VolumeGroupState vgs = sVolumeGroupStates.get(volumeGroup);
        sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_SET_GROUP_VOL, attr, vgs.name(),
                index/*val1*/, flags/*val2*/, callingPackage));
@@ -3798,7 +3799,7 @@ public class AudioService extends IAudioService.Stub
        vgs.setVolumeIndex(index, flags);
        // For legacy reason, propagate to all streams associated to this volume group
        for (final int groupedStream : vgs.getLegacyStreamTypes()) {
        for (int groupedStream : vgs.getLegacyStreamTypes()) {
            try {
                ensureValidStreamType(groupedStream);
            } catch (IllegalArgumentException e) {
@@ -3830,7 +3831,9 @@ public class AudioService extends IAudioService.Stub
        super.getVolumeIndexForAttributes_enforcePermission();
        Objects.requireNonNull(attr, "attr must not be null");
        final int volumeGroup = getVolumeGroupIdForAttributes(attr);
        final int volumeGroup =
                AudioProductStrategy.getVolumeGroupIdForAudioAttributes(
                        attr, /* fallbackOnDefault= */false);
        if (sVolumeGroupStates.indexOfKey(volumeGroup) < 0) {
            throw new IllegalArgumentException("No volume group for attributes " + attr);
        }
@@ -4380,31 +4383,6 @@ public class AudioService extends IAudioService.Stub
        sendVolumeUpdate(streamType, oldIndex, index, flags, device);
    }
    private int getVolumeGroupIdForAttributes(@NonNull AudioAttributes attributes) {
        Objects.requireNonNull(attributes, "attributes must not be null");
        int volumeGroupId = getVolumeGroupIdForAttributesInt(attributes);
        if (volumeGroupId != AudioVolumeGroup.DEFAULT_VOLUME_GROUP) {
            return volumeGroupId;
        }
        // The default volume group is the one hosted by default product strategy, i.e.
        // supporting Default Attributes
        return getVolumeGroupIdForAttributesInt(AudioProductStrategy.getDefaultAttributes());
    }
    private int getVolumeGroupIdForAttributesInt(@NonNull AudioAttributes attributes) {
        Objects.requireNonNull(attributes, "attributes must not be null");
        for (final AudioProductStrategy productStrategy :
                AudioProductStrategy.getAudioProductStrategies()) {
            int volumeGroupId = productStrategy.getVolumeGroupIdForAudioAttributes(attributes);
            if (volumeGroupId != AudioVolumeGroup.DEFAULT_VOLUME_GROUP) {
                return volumeGroupId;
            }
        }
        return AudioVolumeGroup.DEFAULT_VOLUME_GROUP;
    }
    private void dispatchAbsoluteVolumeChanged(int streamType, AbsoluteVolumeDeviceInfo deviceInfo,
            int index) {
        VolumeInfo volumeInfo = deviceInfo.getMatchingVolumeInfoForStream(streamType);
@@ -4437,7 +4415,6 @@ public class AudioService extends IAudioService.Stub
        }
    }
    // No ringer or zen muted stream volumes can be changed unless it'll exit dnd
    private boolean volumeAdjustmentAllowedByDnd(int streamTypeAlias, int flags) {
        switch (mNm.getZenMode()) {