diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl index 8137275da76a8..4cf236a84eb0a 100755 --- a/media/java/android/media/IAudioService.aidl +++ b/media/java/android/media/IAudioService.aidl @@ -40,6 +40,7 @@ import android.media.audiopolicy.AudioVolumeGroup; import android.media.audiopolicy.IAudioPolicyCallback; import android.media.projection.IMediaProjection; import android.net.Uri; +import android.view.KeyEvent; /** * {@hide} @@ -78,6 +79,9 @@ interface IAudioService { @UnsupportedAppUsage void setStreamVolume(int streamType, int index, int flags, String callingPackage); + oneway void handleVolumeKey(in KeyEvent event, boolean isOnTv, + String callingPackage, String caller); + boolean isStreamMute(int streamType); void forceRemoteSubmixFullVolume(boolean startForcing, IBinder cb); diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index 78e06a30be80d..d5f014ba38c0f 100755 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -1852,6 +1852,57 @@ public class AudioService extends IAudioService.Stub return AudioSystem.getDevicesForAttributes(attributes); } + /** Indicates no special treatment in the handling of the volume adjustement */ + private static final int VOL_ADJUST_NORMAL = 0; + /** Indicates the start of a volume adjustement */ + private static final int VOL_ADJUST_START = 1; + /** Indicates the end of a volume adjustment */ + private static final int VOL_ADJUST_END = 2; + + // pre-condition: event.getKeyCode() is one of KeyEvent.KEYCODE_VOLUME_UP, + // KeyEvent.KEYCODE_VOLUME_DOWN, KeyEvent.KEYCODE_VOLUME_MUTE + public void handleVolumeKey(@NonNull KeyEvent event, boolean isOnTv, + @NonNull String callingPackage, @NonNull String caller) { + int keyEventMode = VOL_ADJUST_NORMAL; + if (isOnTv) { + if (event.getAction() == KeyEvent.ACTION_DOWN) { + keyEventMode = VOL_ADJUST_START; + } else { // may catch more than ACTION_UP, but will end vol adjustement + // the vol key is either released (ACTION_UP), or multiple keys are pressed + // (ACTION_MULTIPLE) and we don't know what to do for volume control on CEC, end + // the repeated volume adjustement + keyEventMode = VOL_ADJUST_END; + } + } else if (event.getAction() != KeyEvent.ACTION_DOWN) { + return; + } + + int flags = AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_PLAY_SOUND + | AudioManager.FLAG_FROM_KEY; + + switch (event.getKeyCode()) { + case KeyEvent.KEYCODE_VOLUME_UP: + adjustSuggestedStreamVolume(AudioManager.ADJUST_RAISE, + AudioManager.USE_DEFAULT_STREAM_TYPE, flags, callingPackage, caller, + Binder.getCallingUid(), true, keyEventMode); + break; + case KeyEvent.KEYCODE_VOLUME_DOWN: + adjustSuggestedStreamVolume(AudioManager.ADJUST_LOWER, + AudioManager.USE_DEFAULT_STREAM_TYPE, flags, callingPackage, caller, + Binder.getCallingUid(), true, keyEventMode); + break; + case KeyEvent.KEYCODE_VOLUME_MUTE: + if (event.getRepeatCount() == 0) { + adjustSuggestedStreamVolume(AudioManager.ADJUST_TOGGLE_MUTE, + AudioManager.USE_DEFAULT_STREAM_TYPE, flags, callingPackage, caller, + Binder.getCallingUid(), true, VOL_ADJUST_NORMAL); + } + break; + default: + Log.e(TAG, "Invalid key code " + event.getKeyCode() + " sent by " + callingPackage); + return; // not needed but added if code gets added below this switch statement + } + } /** @see AudioManager#adjustVolume(int, int) */ public void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags, @@ -1879,12 +1930,13 @@ public class AudioService extends IAudioService.Stub mContext.checkCallingPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS) == PackageManager.PERMISSION_GRANTED; adjustSuggestedStreamVolume(direction, suggestedStreamType, flags, callingPackage, - caller, Binder.getCallingUid(), hasModifyAudioSettings); + caller, Binder.getCallingUid(), hasModifyAudioSettings, VOL_ADJUST_NORMAL); } } private void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags, - String callingPackage, String caller, int uid, boolean hasModifyAudioSettings) { + String callingPackage, String caller, int uid, boolean hasModifyAudioSettings, + int keyEventMode) { if (DEBUG_VOL) Log.d(TAG, "adjustSuggestedStreamVolume() stream=" + suggestedStreamType + ", flags=" + flags + ", caller=" + caller + ", volControlStream=" + mVolumeControlStream @@ -1939,7 +1991,7 @@ public class AudioService extends IAudioService.Stub } adjustStreamVolume(streamType, direction, flags, callingPackage, caller, uid, - hasModifyAudioSettings); + hasModifyAudioSettings, keyEventMode); } /** @see AudioManager#adjustStreamVolume(int, int, int) @@ -1957,11 +2009,12 @@ public class AudioService extends IAudioService.Stub sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_ADJUST_STREAM_VOL, streamType, direction/*val1*/, flags/*val2*/, callingPackage)); adjustStreamVolume(streamType, direction, flags, callingPackage, callingPackage, - Binder.getCallingUid(), hasModifyAudioSettings); + Binder.getCallingUid(), hasModifyAudioSettings, VOL_ADJUST_NORMAL); } protected void adjustStreamVolume(int streamType, int direction, int flags, - String callingPackage, String caller, int uid, boolean hasModifyAudioSettings) { + String callingPackage, String caller, int uid, boolean hasModifyAudioSettings, + int keyEventMode) { if (mUseFixedVolume) { return; } @@ -2195,8 +2248,21 @@ public class AudioService extends IAudioService.Stub if (keyCode != KeyEvent.KEYCODE_UNKNOWN) { final long ident = Binder.clearCallingIdentity(); try { - mHdmiPlaybackClient.sendVolumeKeyEvent(keyCode, true); - mHdmiPlaybackClient.sendVolumeKeyEvent(keyCode, false); + final long time = java.lang.System.currentTimeMillis(); + switch (keyEventMode) { + case VOL_ADJUST_NORMAL: + mHdmiPlaybackClient.sendVolumeKeyEvent(keyCode, true); + mHdmiPlaybackClient.sendVolumeKeyEvent(keyCode, false); + break; + case VOL_ADJUST_START: + mHdmiPlaybackClient.sendVolumeKeyEvent(keyCode, true); + break; + case VOL_ADJUST_END: + mHdmiPlaybackClient.sendVolumeKeyEvent(keyCode, false); + break; + default: + Log.e(TAG, "Invalid keyEventMode " + keyEventMode); + } } finally { Binder.restoreCallingIdentity(ident); } @@ -7560,7 +7626,7 @@ public class AudioService extends IAudioService.Stub // direction and stream type swap here because the public // adjustSuggested has a different order than the other methods. adjustSuggestedStreamVolume(direction, streamType, flags, callingPackage, - callingPackage, uid, hasModifyAudioSettings); + callingPackage, uid, hasModifyAudioSettings, VOL_ADJUST_NORMAL); } @Override @@ -7575,7 +7641,7 @@ public class AudioService extends IAudioService.Stub mContext.checkPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS, pid, uid) == PackageManager.PERMISSION_GRANTED; adjustStreamVolume(streamType, direction, flags, callingPackage, - callingPackage, uid, hasModifyAudioSettings); + callingPackage, uid, hasModifyAudioSettings, VOL_ADJUST_NORMAL); } @Override diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index 014997b7ff208..0890b9212d2c3 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -4200,6 +4200,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { return false; } + // pre-condition: event.getKeyCode() is one of KeyEvent.KEYCODE_VOLUME_UP, + // KeyEvent.KEYCODE_VOLUME_DOWN, KeyEvent.KEYCODE_VOLUME_MUTE private void dispatchDirectAudioEvent(KeyEvent event) { // When System Audio Mode is off, volume keys received by AVR can be either consumed by AVR // or forwarded to the TV. It's up to Amplifier manufacturer’s implementation. @@ -4214,42 +4216,12 @@ public class PhoneWindowManager implements WindowManagerPolicy { return; } } - if (event.getAction() != KeyEvent.ACTION_DOWN) { - return; - } - int keyCode = event.getKeyCode(); - int flags = AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_PLAY_SOUND - | AudioManager.FLAG_FROM_KEY; - String pkgName = mContext.getOpPackageName(); - - switch (keyCode) { - case KeyEvent.KEYCODE_VOLUME_UP: - try { - getAudioService().adjustSuggestedStreamVolume(AudioManager.ADJUST_RAISE, - AudioManager.USE_DEFAULT_STREAM_TYPE, flags, pkgName, TAG); - } catch (Exception e) { - Log.e(TAG, "Error dispatching volume up in dispatchTvAudioEvent.", e); - } - break; - case KeyEvent.KEYCODE_VOLUME_DOWN: - try { - getAudioService().adjustSuggestedStreamVolume(AudioManager.ADJUST_LOWER, - AudioManager.USE_DEFAULT_STREAM_TYPE, flags, pkgName, TAG); - } catch (Exception e) { - Log.e(TAG, "Error dispatching volume down in dispatchTvAudioEvent.", e); - } - break; - case KeyEvent.KEYCODE_VOLUME_MUTE: - try { - if (event.getRepeatCount() == 0) { - getAudioService().adjustSuggestedStreamVolume( - AudioManager.ADJUST_TOGGLE_MUTE, - AudioManager.USE_DEFAULT_STREAM_TYPE, flags, pkgName, TAG); - } - } catch (Exception e) { - Log.e(TAG, "Error dispatching mute in dispatchTvAudioEvent.", e); - } - break; + try { + getAudioService().handleVolumeKey(event, mUseTvRouting, + mContext.getOpPackageName(), TAG); + } catch (Exception e) { + Log.e(TAG, "Error dispatching volume key in handleVolumeKey for event:" + + event, e); } }