Loading media/java/android/media/IAudioService.aidl +4 −0 Original line number Diff line number Diff line Loading @@ -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} Loading Loading @@ -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); Loading services/core/java/com/android/server/audio/AudioService.java +75 −9 Original line number Diff line number Diff line Loading @@ -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, Loading Loading @@ -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 Loading Loading @@ -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) Loading @@ -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; } Loading Loading @@ -2195,8 +2248,21 @@ public class AudioService extends IAudioService.Stub if (keyCode != KeyEvent.KEYCODE_UNKNOWN) { final long ident = Binder.clearCallingIdentity(); try { 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); } Loading Loading @@ -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 Loading @@ -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 Loading services/core/java/com/android/server/policy/PhoneWindowManager.java +8 −36 Original line number Diff line number Diff line Loading @@ -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. Loading @@ -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); getAudioService().handleVolumeKey(event, mUseTvRouting, mContext.getOpPackageName(), 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; Log.e(TAG, "Error dispatching volume key in handleVolumeKey for event:" + event, e); } } Loading Loading
media/java/android/media/IAudioService.aidl +4 −0 Original line number Diff line number Diff line Loading @@ -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} Loading Loading @@ -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); Loading
services/core/java/com/android/server/audio/AudioService.java +75 −9 Original line number Diff line number Diff line Loading @@ -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, Loading Loading @@ -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 Loading Loading @@ -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) Loading @@ -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; } Loading Loading @@ -2195,8 +2248,21 @@ public class AudioService extends IAudioService.Stub if (keyCode != KeyEvent.KEYCODE_UNKNOWN) { final long ident = Binder.clearCallingIdentity(); try { 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); } Loading Loading @@ -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 Loading @@ -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 Loading
services/core/java/com/android/server/policy/PhoneWindowManager.java +8 −36 Original line number Diff line number Diff line Loading @@ -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. Loading @@ -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); getAudioService().handleVolumeKey(event, mUseTvRouting, mContext.getOpPackageName(), 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; Log.e(TAG, "Error dispatching volume key in handleVolumeKey for event:" + event, e); } } Loading