diff options
3 files changed, 71 insertions, 19 deletions
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java index 3e91e4c46939..edb692304cae 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) && diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java b/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java index acdcfc190740..19a631a467a3 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java +++ b/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java @@ -602,7 +602,7 @@ public class VolumePanel extends Handler implements DemoMode { private int getStreamVolume(int streamType) { if (streamType == STREAM_MASTER) { - return mAudioManager.getMasterVolume(); + return mAudioManager.getLastAudibleMasterVolume(); } else if (streamType == STREAM_REMOTE_MUSIC) { if (mStreamControls != null) { StreamControl sc = mStreamControls.get(streamType); @@ -613,7 +613,7 @@ public class VolumePanel extends Handler implements DemoMode { } return -1; } else { - return mAudioManager.getStreamVolume(streamType); + return mAudioManager.getLastAudibleStreamVolume(streamType); } } diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java index 6771988adbea..ab51f570a8dd 100644 --- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java @@ -1758,9 +1758,20 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { switch (keyCode) { case KeyEvent.KEYCODE_VOLUME_UP: - case KeyEvent.KEYCODE_VOLUME_DOWN: { - int direction = keyCode == KeyEvent.KEYCODE_VOLUME_UP ? AudioManager.ADJUST_RAISE - : AudioManager.ADJUST_LOWER; + case KeyEvent.KEYCODE_VOLUME_DOWN: + case KeyEvent.KEYCODE_VOLUME_MUTE: { + int direction = 0; + switch (keyCode) { + case KeyEvent.KEYCODE_VOLUME_UP: + direction = AudioManager.ADJUST_RAISE; + break; + case KeyEvent.KEYCODE_VOLUME_DOWN: + direction = AudioManager.ADJUST_LOWER; + break; + case KeyEvent.KEYCODE_VOLUME_MUTE: + direction = AudioManager.ADJUST_TOGGLE_MUTE; + break; + } // If we have a session send it the volume command, otherwise // use the suggested stream. if (mMediaController != null) { @@ -1772,10 +1783,6 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { } return true; } - case KeyEvent.KEYCODE_VOLUME_MUTE: { - getAudioManager().handleKeyDown(event, mVolumeControlStreamType); - return true; - } // These are all the recognized media key codes in // KeyEvent.isMediaKey() case KeyEvent.KEYCODE_MEDIA_PLAY: |