AudioService: properties for configuring ring/notif steps/default vol
Define 4 new properties that can be used to override the default
notification and ringtone volume number of steps and default value.
Throw IllegalArgumentException when max volume is not strictly
positive, if default volume is greater than max volume or
lower than min volume.
Bug: 228180814
Test: dumpsys audio to check default/max for notif/ring
Change-Id: Ib12fd2207b1201ced4bc838892ed23d10e45c3c9
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 31ea98cc..05b9c8a 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2043,6 +2043,18 @@
are controlled together (aliasing is true) or not. -->
<bool name="config_alias_ring_notif_stream_types">true</bool>
+ <!-- The number of volume steps for the notification stream -->
+ <integer name="config_audio_notif_vol_steps">7</integer>
+
+ <!-- The default volume for the notification stream -->
+ <integer name="config_audio_notif_vol_default">5</integer>
+
+ <!-- The number of volume steps for the ring stream -->
+ <integer name="config_audio_ring_vol_steps">7</integer>
+
+ <!-- The default volume for the ring stream -->
+ <integer name="config_audio_ring_vol_default">5</integer>
+
<!-- Flag indicating whether platform level volume adjustments are enabled for remote sessions
on grouped devices. -->
<bool name="config_volumeAdjustmentForRemoteGroupSessions">true</bool>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index d03550c..205681c 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -274,6 +274,10 @@
<java-symbol type="bool" name="action_bar_embed_tabs" />
<java-symbol type="bool" name="action_bar_expanded_action_views_exclusive" />
<java-symbol type="bool" name="config_alias_ring_notif_stream_types" />
+ <java-symbol type="integer" name="config_audio_notif_vol_default" />
+ <java-symbol type="integer" name="config_audio_notif_vol_steps" />
+ <java-symbol type="integer" name="config_audio_ring_vol_default" />
+ <java-symbol type="integer" name="config_audio_ring_vol_steps" />
<java-symbol type="bool" name="config_avoidGfxAccel" />
<java-symbol type="bool" name="config_bluetooth_address_validation" />
<java-symbol type="integer" name="config_chooser_max_targets_per_row" />
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index 444366a..c666140 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -2294,10 +2294,10 @@
public static int[] DEFAULT_STREAM_VOLUME = new int[] {
4, // STREAM_VOICE_CALL
7, // STREAM_SYSTEM
- 5, // STREAM_RING
+ 5, // STREAM_RING // configured in AudioService by config_audio_notif_vol_default
5, // STREAM_MUSIC
6, // STREAM_ALARM
- 5, // STREAM_NOTIFICATION
+ 5, // STREAM_NOTIFICATION // configured in AudioService by config_audio_ring_vol_default
7, // STREAM_BLUETOOTH_SCO
7, // STREAM_SYSTEM_ENFORCED
5, // STREAM_DTMF
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index bed69b2..c00c298 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -63,6 +63,7 @@
import android.content.pm.ResolveInfo;
import android.content.pm.UserInfo;
import android.content.res.Configuration;
+import android.content.res.Resources;
import android.database.ContentObserver;
import android.hardware.SensorPrivacyManager;
import android.hardware.SensorPrivacyManagerInternal;
@@ -411,10 +412,10 @@
protected static int[] MAX_STREAM_VOLUME = new int[] {
5, // STREAM_VOICE_CALL
7, // STREAM_SYSTEM
- 7, // STREAM_RING
+ 7, // STREAM_RING // configured by config_audio_ring_vol_steps
15, // STREAM_MUSIC
7, // STREAM_ALARM
- 7, // STREAM_NOTIFICATION
+ 7, // STREAM_NOTIFICATION // configured by config_audio_notif_vol_steps
15, // STREAM_BLUETOOTH_SCO
7, // STREAM_SYSTEM_ENFORCED
15, // STREAM_DTMF
@@ -1111,6 +1112,48 @@
MAX_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM];
}
+ // Read following properties to configure max volume (number of steps) and default volume
+ // for STREAM_NOTIFICATION and STREAM_RING:
+ // config_audio_notif_vol_default
+ // config_audio_notif_vol_steps
+ // config_audio_ring_vol_default
+ // config_audio_ring_vol_steps
+ int[] streams = { AudioSystem.STREAM_NOTIFICATION, AudioSystem.STREAM_RING };
+ int[] stepsResId = { com.android.internal.R.integer.config_audio_notif_vol_steps,
+ com.android.internal.R.integer.config_audio_ring_vol_steps };
+ int[] defaultResId = { com.android.internal.R.integer.config_audio_notif_vol_default,
+ com.android.internal.R.integer.config_audio_ring_vol_default };
+ for (int s = 0; s < streams.length; s++) {
+ try {
+ final int maxVol = mContext.getResources().getInteger(stepsResId[s]);
+ if (maxVol <= 0) {
+ throw new IllegalArgumentException("Invalid negative max volume for stream "
+ + streams[s]);
+ }
+ Log.i(TAG, "Stream " + streams[s] + ": using max vol of " + maxVol);
+ MAX_STREAM_VOLUME[streams[s]] = maxVol;
+ } catch (Resources.NotFoundException e) {
+ Log.e(TAG, "Error querying max vol for stream type " + streams[s], e);
+ }
+ try {
+ final int defaultVol = mContext.getResources().getInteger(defaultResId[s]);
+ if (defaultVol > MAX_STREAM_VOLUME[streams[s]]) {
+ throw new IllegalArgumentException("Invalid default volume (" + defaultVol
+ + ") for stream " + streams[s] + ", greater than max volume of "
+ + MAX_STREAM_VOLUME[streams[s]]);
+ }
+ if (defaultVol < MIN_STREAM_VOLUME[streams[s]]) {
+ throw new IllegalArgumentException("Invalid default volume (" + defaultVol
+ + ") for stream " + streams[s] + ", lower than min volume of "
+ + MIN_STREAM_VOLUME[streams[s]]);
+ }
+ Log.i(TAG, "Stream " + streams[s] + ": using default vol of " + defaultVol);
+ AudioSystem.DEFAULT_STREAM_VOLUME[streams[s]] = defaultVol;
+ } catch (Resources.NotFoundException e) {
+ Log.e(TAG, "Error querying default vol for stream type " + streams[s], e);
+ }
+ }
+
if (looper == null) {
createAudioSystemThread();
} else {