From 5452e258441edd77f6d608eea208ea60ce7ec262 Mon Sep 17 00:00:00 2001 From: RoboErik Date: Fri, 6 Feb 2015 15:33:53 -0800 Subject: Delay unmuting on volume down This allows the user to turn the volume down before a stream is unmuted by delaying the unmute call while volume down requests are still being made. bug:19297183 Change-Id: I65a8e489eb4cbfeace4f539103ee0025584102da --- media/java/android/media/AudioService.java | 65 +++++++++++++++++++++++++----- 1 file changed, 55 insertions(+), 10 deletions(-) (limited to 'media') diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java index 3e91e4c..edb6923 100644 --- a/media/java/android/media/AudioService.java +++ b/media/java/android/media/AudioService.java @@ -135,6 +135,9 @@ public class AudioService extends IAudioService.Stub { /** How long to delay before persisting a change in volume/ringer mode. */ private static final int PERSIST_DELAY = 500; + /** How long to delay after a volume down event before unmuting a stream */ + private static final int UNMUTE_STREAM_DELAY = 350; + /** * The delay before playing a sound. This small period exists so the user * can press another key (non-volume keys, too) to have it NOT be audible. @@ -205,6 +208,7 @@ public class AudioService extends IAudioService.Stub { private static final int MSG_SYSTEM_READY = 21; private static final int MSG_PERSIST_MUSIC_ACTIVE_MS = 22; private static final int MSG_PERSIST_MICROPHONE_MUTE = 23; + private static final int MSG_UNMUTE_STREAM = 24; // start of messages handled under wakelock // these messages can only be queued, i.e. sent with queueMsgUnderWakeLock(), // and not with sendMsg(..., ..., SENDMSG_QUEUE, ...) @@ -1109,9 +1113,9 @@ public class AudioService extends IAudioService.Stub { if (ringerMode == AudioManager.RINGER_MODE_VIBRATE) { flags &= ~AudioManager.FLAG_VIBRATE; } - // Check if the ringer mode changes with this volume adjustment. If - // it does, it will handle adjusting the volume, so we won't below - final int result = checkForRingerModeChange(aliasIndex, direction, step); + // Check if the ringer mode handles this adjustment. If it does we don't + // need to adjust the volume further. + final int result = checkForRingerModeChange(aliasIndex, direction, step, streamState.mIsMuted); adjustVolume = (result & FLAG_ADJUST_VOLUME) != 0; // If suppressing a volume adjustment in silent mode, display the UI hint if ((result & AudioManager.FLAG_SHOW_SILENT_HINT) != 0) { @@ -1126,6 +1130,7 @@ public class AudioService extends IAudioService.Stub { int oldIndex = mStreamStates[streamType].getIndex(device); if (adjustVolume && (direction != AudioManager.ADJUST_SAME)) { + mAudioHandler.removeMessages(MSG_UNMUTE_STREAM); // Check if volume update should be send to AVRCP if (streamTypeAlias == AudioSystem.STREAM_MUSIC && @@ -1167,7 +1172,13 @@ public class AudioService extends IAudioService.Stub { // message to persist). if (streamState.mIsMuted) { // Unmute the stream if it was previously muted - streamState.mute(false); + if (direction == AudioManager.ADJUST_RAISE) { + // unmute immediately for volume up + streamState.mute(false); + } else if (direction == AudioManager.ADJUST_LOWER) { + sendMsg(mAudioHandler, MSG_UNMUTE_STREAM, SENDMSG_QUEUE, + streamTypeAlias, flags, null, UNMUTE_STREAM_DELAY); + } } sendMsg(mAudioHandler, MSG_SET_DEVICE_VOLUME, @@ -1203,6 +1214,16 @@ public class AudioService extends IAudioService.Stub { sendVolumeUpdate(streamType, oldIndex, index, flags); } + // Called after a delay when volume down is pressed while muted + private void onUnmuteStream(int stream, int flags) { + VolumeStreamState streamState = mStreamStates[stream]; + streamState.mute(false); + + final int device = getDeviceForStream(stream); + final int index = mStreamStates[stream].getIndex(device); + sendVolumeUpdate(stream, index, index, flags); + } + private void setSystemAudioVolume(int oldVolume, int newVolume, int maxVolume, int flags) { if (mHdmiManager == null || mHdmiTvClient == null @@ -3107,7 +3128,7 @@ public class AudioService extends IAudioService.Stub { * adjusting volume. If so, this will set the proper ringer mode and volume * indices on the stream states. */ - private int checkForRingerModeChange(int oldIndex, int direction, int step) { + private int checkForRingerModeChange(int oldIndex, int direction, int step, boolean isMuted) { int result = FLAG_ADJUST_VOLUME; int ringerMode = getRingerModeInternal(); @@ -3131,6 +3152,15 @@ public class AudioService extends IAudioService.Stub { ringerMode = RINGER_MODE_SILENT; } } + } else if (direction == AudioManager.ADJUST_TOGGLE_MUTE + || direction == AudioManager.ADJUST_MUTE) { + if (mHasVibrator) { + ringerMode = RINGER_MODE_VIBRATE; + } else { + ringerMode = RINGER_MODE_SILENT; + } + // Setting the ringer mode will toggle mute + result &= ~FLAG_ADJUST_VOLUME; } break; case RINGER_MODE_VIBRATE: @@ -3140,26 +3170,38 @@ public class AudioService extends IAudioService.Stub { break; } if ((direction == AudioManager.ADJUST_LOWER)) { - if (mPrevVolDirection != AudioManager.ADJUST_LOWER) { + // This is the case we were muted with the volume turned up + if (oldIndex >= 2 * step && isMuted) { + ringerMode = RINGER_MODE_NORMAL; + } else if (mPrevVolDirection != AudioManager.ADJUST_LOWER) { if (VOLUME_SETS_RINGER_MODE_SILENT) { ringerMode = RINGER_MODE_SILENT; } else { result |= AudioManager.FLAG_SHOW_VIBRATE_HINT; } } - } else if (direction == AudioManager.ADJUST_RAISE) { + } else if (direction == AudioManager.ADJUST_RAISE + || direction == AudioManager.ADJUST_TOGGLE_MUTE + || direction == AudioManager.ADJUST_UNMUTE) { ringerMode = RINGER_MODE_NORMAL; } result &= ~FLAG_ADJUST_VOLUME; break; case RINGER_MODE_SILENT: - if (direction == AudioManager.ADJUST_RAISE) { + if (direction == AudioManager.ADJUST_LOWER && oldIndex >= 2 * step && isMuted) { + // This is the case we were muted with the volume turned up + ringerMode = RINGER_MODE_NORMAL; + } else if (direction == AudioManager.ADJUST_RAISE + || direction == AudioManager.ADJUST_TOGGLE_MUTE + || direction == AudioManager.ADJUST_UNMUTE) { if (PREVENT_VOLUME_ADJUSTMENT_IF_SILENT) { result |= AudioManager.FLAG_SHOW_SILENT_HINT; } else { - if (mHasVibrator) { + if (mHasVibrator && direction == AudioManager.ADJUST_RAISE) { ringerMode = RINGER_MODE_VIBRATE; } else { + // If we don't have a vibrator or they were toggling mute + // go straight back to normal. ringerMode = RINGER_MODE_NORMAL; } } @@ -4384,6 +4426,9 @@ public class AudioService extends IAudioService.Stub { msg.arg1, msg.arg2); break; + case MSG_UNMUTE_STREAM: + onUnmuteStream(msg.arg1, msg.arg2); + break; } } } @@ -4607,7 +4652,7 @@ public class AudioService extends IAudioService.Stub { private boolean handleDeviceConnection(boolean connect, int device, String address, String deviceName) { Slog.i(TAG, "handleDeviceConnection(" + connect + " dev:" + Integer.toHexString(device) + - " address:" + address + + " address:" + address + " name:" + deviceName + ")"); synchronized (mConnectedDevices) { boolean isConnected = (mConnectedDevices.containsKey(device) && -- cgit v1.1