diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 287ab9ecdf516..73a8592d176d8 100755 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -3149,6 +3149,13 @@ public final class Settings { */ public static final String VOLUME_BLUETOOTH_SCO = "volume_bluetooth_sco"; + /** + * @hide + * Acessibility volume. This is used internally, changing this + * value will not change the volume. + */ + public static final String VOLUME_ACCESSIBILITY = "volume_a11y"; + /** * Master volume (float in the range 0.0f to 1.0f). * @@ -3211,6 +3218,22 @@ public final class Settings { VOLUME_ALARM, VOLUME_NOTIFICATION, VOLUME_BLUETOOTH_SCO }; + /** + * @hide + * The mapping of stream type (integer) to its setting. + * Unlike the VOLUME_SETTINGS array, this one contains as many entries as + * AudioSystem.NUM_STREAM_TYPES, and has empty strings for stream types whose volumes + * are never persisted. + */ + public static final String[] VOLUME_SETTINGS_INT = { + VOLUME_VOICE, VOLUME_SYSTEM, VOLUME_RING, VOLUME_MUSIC, + VOLUME_ALARM, VOLUME_NOTIFICATION, VOLUME_BLUETOOTH_SCO, + "" /*STREAM_SYSTEM_ENFORCED, no setting for this stream*/, + "" /*STREAM_DTMF, no setting for this stream*/, + "" /*STREAM_TTS, no setting for this stream*/, + VOLUME_ACCESSIBILITY + }; + /** * Appended to various volume related settings to record the previous * values before they the settings were affected by a silent/vibrate diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index c11f5316f7697..268724283351a 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -23,6 +23,7 @@ import static android.media.AudioManager.RINGER_MODE_VIBRATE; import static android.os.Process.FIRST_APPLICATION_UID; import android.Manifest; +import android.annotation.Nullable; import android.app.ActivityManager; import android.app.ActivityManagerInternal; import android.app.AppGlobals; @@ -968,7 +969,8 @@ public class AudioService extends IAudioService.Stub VolumeStreamState[] streams = mStreamStates = new VolumeStreamState[numStreamTypes]; for (int i = 0; i < numStreamTypes; i++) { - streams[i] = new VolumeStreamState(System.VOLUME_SETTINGS[mStreamVolumeAlias[i]], i); + streams[i] = + new VolumeStreamState(System.VOLUME_SETTINGS_INT[mStreamVolumeAlias[i]], i); } checkAllFixedVolumeDevices(); @@ -1020,7 +1022,14 @@ public class AudioService extends IAudioService.Stub } mStreamVolumeAlias[AudioSystem.STREAM_DTMF] = dtmfStreamAlias; - mStreamVolumeAlias[AudioSystem.STREAM_ACCESSIBILITY] = a11yStreamAlias; + final int oldStreamA11yAlias = mStreamVolumeAlias[AudioSystem.STREAM_ACCESSIBILITY]; + if (oldStreamA11yAlias != a11yStreamAlias) { + mStreamVolumeAlias[AudioSystem.STREAM_ACCESSIBILITY] = a11yStreamAlias; + mStreamStates[AudioSystem.STREAM_ACCESSIBILITY].mVolumeIndexSettingName = + System.VOLUME_SETTINGS_INT[a11yStreamAlias]; + // restore the value from the settings when the alias changes + mStreamStates[AudioSystem.STREAM_ACCESSIBILITY].readSettings(); + } if (updateVolumes) { mStreamStates[AudioSystem.STREAM_DTMF].setAllIndexes(mStreamStates[dtmfStreamAlias], @@ -3992,13 +4001,19 @@ public class AudioService extends IAudioService.Stub return devices; } - public String getSettingNameForDevice(int device) { - String name = mVolumeIndexSettingName; - String suffix = AudioSystem.getOutputDeviceName(device); - if (suffix.isEmpty()) { - return name; + public @Nullable String getSettingNameForDevice(int device) { + if (!hasValidSettingsName()) { + return null; } - return name + "_" + suffix; + final String suffix = AudioSystem.getOutputDeviceName(device); + if (suffix.isEmpty()) { + return mVolumeIndexSettingName; + } + return mVolumeIndexSettingName + "_" + suffix; + } + + private boolean hasValidSettingsName() { + return (mVolumeIndexSettingName != null && !mVolumeIndexSettingName.isEmpty()); } public void readSettings() { @@ -4033,13 +4048,18 @@ public class AudioService extends IAudioService.Stub remainingDevices &= ~device; // retrieve current volume for device - String name = getSettingNameForDevice(device); // if no volume stored for current stream and device, use default volume if default // device, continue otherwise int defaultIndex = (device == AudioSystem.DEVICE_OUT_DEFAULT) ? AudioSystem.DEFAULT_STREAM_VOLUME[mStreamType] : -1; - int index = Settings.System.getIntForUser( - mContentResolver, name, defaultIndex, UserHandle.USER_CURRENT); + int index; + if (!hasValidSettingsName()) { + index = defaultIndex; + } else { + String name = getSettingNameForDevice(device); + index = Settings.System.getIntForUser( + mContentResolver, name, defaultIndex, UserHandle.USER_CURRENT); + } if (index == -1) { continue; } @@ -4420,10 +4440,12 @@ public class AudioService extends IAudioService.Stub if (mIsSingleVolume && (streamState.mStreamType != AudioSystem.STREAM_MUSIC)) { return; } - System.putIntForUser(mContentResolver, - streamState.getSettingNameForDevice(device), - (streamState.getIndex(device) + 5)/ 10, - UserHandle.USER_CURRENT); + if (streamState.hasValidSettingsName()) { + System.putIntForUser(mContentResolver, + streamState.getSettingNameForDevice(device), + (streamState.getIndex(device) + 5)/ 10, + UserHandle.USER_CURRENT); + } } private void persistRingerMode(int ringerMode) { @@ -6059,6 +6081,7 @@ public class AudioService extends IAudioService.Stub mVolumeController.setA11yMode(sIndependentA11yVolume ? VolumePolicy.A11Y_MODE_INDEPENDENT_A11Y_VOLUME : VolumePolicy.A11Y_MODE_MEDIA_A11Y_VOLUME); + mVolumeController.postVolumeChanged(AudioManager.STREAM_ACCESSIBILITY, 0); } }