diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 3edc17be35929..eca623a0fbdab 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -3936,6 +3936,9 @@
false
+
+ false
+
- .10
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index ce558fb63bb8d..f2328567e577f 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3632,6 +3632,7 @@
+
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index a3c590409d444..136916af109db 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -413,6 +413,26 @@ public class AudioService extends IAudioService.Stub
AudioSystem.STREAM_MUSIC, // STREAM_ACCESSIBILITY
AudioSystem.STREAM_MUSIC // STREAM_ASSISTANT
};
+ /**
+ * Using Volume groups configuration allows to control volume per attributes
+ * and group definition may differ from stream aliases.
+ * So, do not alias any stream on one another when using volume groups.
+ * TODO(b/181140246): volume group definition hosting alias definition.
+ */
+ private final int[] STREAM_VOLUME_ALIAS_NONE = new int[] {
+ AudioSystem.STREAM_VOICE_CALL, // STREAM_VOICE_CALL
+ AudioSystem.STREAM_SYSTEM, // STREAM_SYSTEM
+ AudioSystem.STREAM_RING, // STREAM_RING
+ AudioSystem.STREAM_MUSIC, // STREAM_MUSIC
+ AudioSystem.STREAM_ALARM, // STREAM_ALARM
+ AudioSystem.STREAM_NOTIFICATION, // STREAM_NOTIFICATION
+ AudioSystem.STREAM_BLUETOOTH_SCO, // STREAM_BLUETOOTH_SCO
+ AudioSystem.STREAM_SYSTEM_ENFORCED, // STREAM_SYSTEM_ENFORCED
+ AudioSystem.STREAM_DTMF, // STREAM_DTMF
+ AudioSystem.STREAM_TTS, // STREAM_TTS
+ AudioSystem.STREAM_ACCESSIBILITY, // STREAM_ACCESSIBILITY
+ AudioSystem.STREAM_ASSISTANT // STREAM_ASSISTANT
+ };
private final int[] STREAM_VOLUME_ALIAS_DEFAULT = new int[] {
AudioSystem.STREAM_VOICE_CALL, // STREAM_VOICE_CALL
AudioSystem.STREAM_RING, // STREAM_SYSTEM
@@ -428,6 +448,7 @@ public class AudioService extends IAudioService.Stub
AudioSystem.STREAM_MUSIC // STREAM_ASSISTANT
};
protected static int[] mStreamVolumeAlias;
+ private static final int UNSET_INDEX = -1;
/**
* Map AudioSystem.STREAM_* constants to app ops. This should be used
@@ -449,6 +470,7 @@ public class AudioService extends IAudioService.Stub
};
private final boolean mUseFixedVolume;
+ private final boolean mUseVolumeGroupAliases;
// If absolute volume is supported in AVRCP device
private volatile boolean mAvrcpAbsVolSupported = false;
@@ -849,6 +871,9 @@ public class AudioService extends IAudioService.Stub
mSupportsMicPrivacyToggle = context.getSystemService(SensorPrivacyManager.class)
.supportsSensorToggle(SensorPrivacyManager.Sensors.MICROPHONE);
+ mUseVolumeGroupAliases = mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_handleVolumeAliasesUsingVolumeGroups);
+
// Initialize volume
// Priority 1 - Android Property
// Priority 2 - Audio Policy Service
@@ -869,6 +894,12 @@ public class AudioService extends IAudioService.Stub
MIN_STREAM_VOLUME[streamType] = minVolume;
}
}
+ if (mUseVolumeGroupAliases) {
+ // Set all default to uninitialized.
+ for (int stream = 0; stream < AudioSystem.DEFAULT_STREAM_VOLUME.length; stream++) {
+ AudioSystem.DEFAULT_STREAM_VOLUME[stream] = UNSET_INDEX;
+ }
+ }
}
int maxCallVolume = SystemProperties.getInt("ro.config.vc_call_vol_steps", -1);
@@ -1705,18 +1736,42 @@ public class AudioService extends IAudioService.Stub
updateDefaultVolumes();
}
- // Update default indexes from aliased streams. Must be called after mStreamStates is created
+ /**
+ * Update default indexes from aliased streams. Must be called after mStreamStates is created
+ * TODO(b/181140246): when using VolumeGroup alias, we are lacking configurability for default
+ * index. Need to make default index configurable and independent of streams.
+ * Fallback on music stream for default initialization to take benefit of property based default
+ * initialization.
+ * For other volume groups not linked to any streams, default music stream index is considered.
+ */
private void updateDefaultVolumes() {
for (int stream = 0; stream < mStreamStates.length; stream++) {
- if (stream != mStreamVolumeAlias[stream]) {
- AudioSystem.DEFAULT_STREAM_VOLUME[stream] = (rescaleIndex(
- AudioSystem.DEFAULT_STREAM_VOLUME[mStreamVolumeAlias[stream]] * 10,
- mStreamVolumeAlias[stream],
- stream) + 5) / 10;
+ int streamVolumeAlias = mStreamVolumeAlias[stream];
+ if (mUseVolumeGroupAliases) {
+ if (AudioSystem.DEFAULT_STREAM_VOLUME[stream] != UNSET_INDEX) {
+ // Already initialized through default property based mecanism.
+ continue;
+ }
+ streamVolumeAlias = AudioSystem.STREAM_MUSIC;
+ int defaultAliasVolume = getUiDefaultRescaledIndex(streamVolumeAlias, stream);
+ if ((defaultAliasVolume >= MIN_STREAM_VOLUME[stream])
+ && (defaultAliasVolume <= MAX_STREAM_VOLUME[stream])) {
+ AudioSystem.DEFAULT_STREAM_VOLUME[stream] = defaultAliasVolume;
+ continue;
+ }
+ }
+ if (stream != streamVolumeAlias) {
+ AudioSystem.DEFAULT_STREAM_VOLUME[stream] =
+ getUiDefaultRescaledIndex(streamVolumeAlias, stream);
}
}
}
+ private int getUiDefaultRescaledIndex(int srcStream, int dstStream) {
+ return (rescaleIndex(AudioSystem.DEFAULT_STREAM_VOLUME[srcStream] * 10,
+ srcStream, dstStream) + 5) / 10;
+ }
+
private void dumpStreamStates(PrintWriter pw) {
pw.println("\nStream volumes (device: index)");
int numStreamTypes = AudioSystem.getNumStreamTypes();
@@ -1740,6 +1795,9 @@ public class AudioService extends IAudioService.Stub
if (mIsSingleVolume) {
mStreamVolumeAlias = STREAM_VOLUME_ALIAS_TELEVISION;
dtmfStreamAlias = AudioSystem.STREAM_MUSIC;
+ } else if (mUseVolumeGroupAliases) {
+ mStreamVolumeAlias = STREAM_VOLUME_ALIAS_NONE;
+ dtmfStreamAlias = AudioSystem.STREAM_DTMF;
} else {
switch (mPlatformType) {
case AudioSystem.PLATFORM_VOICE:
@@ -2768,7 +2826,7 @@ public class AudioService extends IAudioService.Stub
// If either the client forces allowing ringer modes for this adjustment,
// or the stream type is one that is affected by ringer modes
if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) ||
- (streamTypeAlias == getUiSoundsStreamType())) {
+ (isUiSoundsStreamType(streamTypeAlias))) {
int ringerMode = getRingerModeInternal();
// do not vibrate if already in vibrate mode
if (ringerMode == AudioManager.RINGER_MODE_VIBRATE) {
@@ -3570,7 +3628,7 @@ public class AudioService extends IAudioService.Stub
case Settings.Global.ZEN_MODE_ALARMS:
case Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS:
return !isStreamMutedByRingerOrZenMode(streamTypeAlias)
- || streamTypeAlias == getUiSoundsStreamType()
+ || isUiSoundsStreamType(streamTypeAlias)
|| (flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0;
}
@@ -3987,9 +4045,26 @@ public class AudioService extends IAudioService.Stub
return (mStreamStates[streamType].getIndex(device) + 5) / 10;
}
- /** @see AudioManager#getUiSoundsStreamType() */
+ /** @see AudioManager#getUiSoundsStreamType()
+ * TODO(b/181140246): when using VolumeGroup alias, we are lacking configurability for
+ * UI Sounds identification.
+ * Fallback on Voice configuration to ensure correct behavior of DnD feature.
+ */
public int getUiSoundsStreamType() {
- return mStreamVolumeAlias[AudioSystem.STREAM_SYSTEM];
+ return mUseVolumeGroupAliases ? STREAM_VOLUME_ALIAS_VOICE[AudioSystem.STREAM_SYSTEM]
+ : mStreamVolumeAlias[AudioSystem.STREAM_SYSTEM];
+ }
+
+ /**
+ * TODO(b/181140246): when using VolumeGroup alias, we are lacking configurability for
+ * UI Sounds identification.
+ * Fallback on Voice configuration to ensure correct behavior of DnD feature.
+ */
+ private boolean isUiSoundsStreamType(int aliasStreamType) {
+ return mUseVolumeGroupAliases
+ ? STREAM_VOLUME_ALIAS_VOICE[aliasStreamType]
+ == STREAM_VOLUME_ALIAS_VOICE[AudioSystem.STREAM_SYSTEM]
+ : aliasStreamType == mStreamVolumeAlias[AudioSystem.STREAM_SYSTEM];
}
/** @see AudioManager#setMicrophoneMute(boolean) */