Loading media/java/android/media/audiopolicy/AudioProductStrategy.java +44 −9 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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)) { Loading @@ -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); Loading Loading @@ -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; Loading Loading @@ -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(); Loading @@ -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; Loading Loading @@ -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(); Loading @@ -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; Loading Loading @@ -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)) { Loading services/core/java/com/android/server/audio/AudioService.java +7 −30 Original line number Diff line number Diff line Loading @@ -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)); Loading @@ -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) { Loading Loading @@ -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); } Loading Loading @@ -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); Loading Loading @@ -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()) { Loading Loading
media/java/android/media/audiopolicy/AudioProductStrategy.java +44 −9 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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)) { Loading @@ -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); Loading Loading @@ -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; Loading Loading @@ -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(); Loading @@ -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; Loading Loading @@ -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(); Loading @@ -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; Loading Loading @@ -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)) { Loading
services/core/java/com/android/server/audio/AudioService.java +7 −30 Original line number Diff line number Diff line Loading @@ -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)); Loading @@ -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) { Loading Loading @@ -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); } Loading Loading @@ -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); Loading Loading @@ -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()) { Loading