diff options
author | RoboErik <epastern@google.com> | 2014-12-04 17:39:08 -0800 |
---|---|---|
committer | RoboErik <epastern@google.com> | 2014-12-05 12:41:34 -0800 |
commit | 7c82ced4fc5b66c09a19eed9a5499039530142fb (patch) | |
tree | 8b855217881f6899402d757452a3cbd38989d799 /media | |
parent | fd228a383c0844d69da952460145b1aa3e00ffd7 (diff) | |
download | frameworks_base-7c82ced4fc5b66c09a19eed9a5499039530142fb.zip frameworks_base-7c82ced4fc5b66c09a19eed9a5499039530142fb.tar.gz frameworks_base-7c82ced4fc5b66c09a19eed9a5499039530142fb.tar.bz2 |
Route mute key events through MediaSessionService
This sends mute keys to the MediaSessionService and handles them
by toggling the appropriate stream. Muting remote playback is still
not supported.
bug:17501993
Change-Id: I18c5b037cde2175acbb64b118dd708514acfd8c9
Diffstat (limited to 'media')
5 files changed, 83 insertions, 16 deletions
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java index 543836b..ee9044e 100644 --- a/media/java/android/media/AudioManager.java +++ b/media/java/android/media/AudioManager.java @@ -138,6 +138,17 @@ public class AudioManager { public static final String VOLUME_CHANGED_ACTION = "android.media.VOLUME_CHANGED_ACTION"; /** + * @hide Broadcast intent when a stream mute state changes. + * Includes the stream that changed and the new mute state + * + * @see #EXTRA_VOLUME_STREAM_TYPE + * @see #EXTRA_STREAM_VOLUME_MUTED + */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String STREAM_MUTE_CHANGED_ACTION = + "android.media.STREAM_MUTE_CHANGED_ACTION"; + + /** * @hide Broadcast intent when the master volume changes. * Includes the new volume * @@ -221,6 +232,13 @@ public class AudioManager { "android.media.EXTRA_MASTER_VOLUME_MUTED"; /** + * @hide The new stream volume mute state for the stream mute changed intent. + * Value is boolean + */ + public static final String EXTRA_STREAM_VOLUME_MUTED = + "android.media.EXTRA_STREAM_VOLUME_MUTED"; + + /** * Broadcast Action: Wired Headset plugged in or unplugged. * * You <em>cannot</em> receive this through components declared @@ -728,11 +746,7 @@ public class AudioManager { break; case KeyEvent.KEYCODE_VOLUME_MUTE: if (event.getRepeatCount() == 0) { - if (mUseMasterVolume) { - setMasterMute(!isMasterMute()); - } else { - // TODO: Actually handle MUTE. - } + MediaSessionLegacyHelper.getHelper(mContext).sendVolumeKeyEvent(event, false); } break; } @@ -763,6 +777,9 @@ public class AudioManager { } mVolumeKeyUpTime = SystemClock.uptimeMillis(); break; + case KeyEvent.KEYCODE_VOLUME_MUTE: + MediaSessionLegacyHelper.getHelper(mContext).sendVolumeKeyEvent(event, false); + break; } } diff --git a/media/java/android/media/AudioManagerInternal.java b/media/java/android/media/AudioManagerInternal.java index d9586bc..616bdd1 100644 --- a/media/java/android/media/AudioManagerInternal.java +++ b/media/java/android/media/AudioManagerInternal.java @@ -15,6 +15,8 @@ */ package android.media; +import android.os.IBinder; + import com.android.server.LocalServices; /** @@ -39,6 +41,9 @@ public abstract class AudioManagerInternal { public abstract void adjustMasterVolumeForUid(int steps, int flags, String callingPackage, int uid); + public abstract void setMasterMuteForUid(boolean state, int flags, String callingPackage, + IBinder cb, int uid); + public abstract void setRingerModeDelegate(RingerModeDelegate delegate); public abstract int getRingerModeInternal(); diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java index 9a3ec42..f1d6a0a 100644 --- a/media/java/android/media/AudioService.java +++ b/media/java/android/media/AudioService.java @@ -1517,12 +1517,20 @@ public class AudioService extends IAudioService.Stub { if (mUseFixedVolume) { return; } + if (streamType == AudioManager.USE_DEFAULT_STREAM_TYPE) { + streamType = getActiveStreamType(streamType); + } if (isStreamAffectedByMute(streamType)) { if (streamType == AudioSystem.STREAM_MUSIC) { setSystemAudioMute(state); } mStreamStates[streamType].mute(cb, state); + + Intent intent = new Intent(AudioManager.STREAM_MUTE_CHANGED_ACTION); + intent.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, streamType); + intent.putExtra(AudioManager.EXTRA_STREAM_VOLUME_MUTED, state); + sendBroadcastToAll(intent); } } @@ -1544,6 +1552,9 @@ public class AudioService extends IAudioService.Stub { /** get stream mute state. */ public boolean isStreamMute(int streamType) { + if (streamType == AudioManager.USE_DEFAULT_STREAM_TYPE) { + streamType = getActiveStreamType(streamType); + } synchronized (VolumeStreamState.class) { return mStreamStates[streamType].isMuted_syncVSS(); } @@ -1651,11 +1662,16 @@ public class AudioService extends IAudioService.Stub { /** @see AudioManager#setMasterMute(boolean, int) */ public void setMasterMute(boolean state, int flags, String callingPackage, IBinder cb) { + setMasterMuteInternal(state, flags, callingPackage, cb, Binder.getCallingUid()); + } + + private void setMasterMuteInternal(boolean state, int flags, String callingPackage, IBinder cb, + int uid) { if (mUseFixedVolume) { return; } - if (mAppOps.noteOp(AppOpsManager.OP_AUDIO_MASTER_VOLUME, Binder.getCallingUid(), - callingPackage) != AppOpsManager.MODE_ALLOWED) { + if (mAppOps.noteOp(AppOpsManager.OP_AUDIO_MASTER_VOLUME, uid, callingPackage) + != AppOpsManager.MODE_ALLOWED) { return; } if (state != AudioSystem.getMasterMute()) { @@ -1665,6 +1681,10 @@ public class AudioService extends IAudioService.Stub { sendMsg(mAudioHandler, MSG_PERSIST_MASTER_VOLUME_MUTE, SENDMSG_REPLACE, state ? 1 : 0, UserHandle.getCallingUserId(), null, PERSIST_DELAY); sendMasterMuteUpdate(state, flags); + + Intent intent = new Intent(AudioManager.MASTER_MUTE_CHANGED_ACTION); + intent.putExtra(AudioManager.EXTRA_MASTER_VOLUME_MUTED, state); + sendBroadcastToAll(intent); } } @@ -5781,6 +5801,12 @@ public class AudioService extends IAudioService.Stub { public void setRingerModeInternal(int ringerMode, String caller) { AudioService.this.setRingerModeInternal(ringerMode, caller); } + + @Override + public void setMasterMuteForUid(boolean state, int flags, String callingPackage, IBinder cb, + int uid) { + setMasterMuteInternal(state, flags, callingPackage, cb, uid); + } } //========================================================================================== diff --git a/media/java/android/media/session/MediaSessionLegacyHelper.java b/media/java/android/media/session/MediaSessionLegacyHelper.java index b37ee6e..4b9a929 100644 --- a/media/java/android/media/session/MediaSessionLegacyHelper.java +++ b/media/java/android/media/session/MediaSessionLegacyHelper.java @@ -190,6 +190,7 @@ public class MediaSessionLegacyHelper { boolean down = keyEvent.getAction() == KeyEvent.ACTION_DOWN; boolean up = keyEvent.getAction() == KeyEvent.ACTION_UP; int direction = 0; + boolean isMute = false; switch (keyEvent.getKeyCode()) { case KeyEvent.KEYCODE_VOLUME_UP: direction = AudioManager.ADJUST_RAISE; @@ -198,15 +199,11 @@ public class MediaSessionLegacyHelper { direction = AudioManager.ADJUST_LOWER; break; case KeyEvent.KEYCODE_VOLUME_MUTE: - // TODO + isMute = true; break; } - if ((down || up) && direction != 0) { + if (down || up) { int flags; - // If this is action up we want to send a beep for non-music events - if (up) { - direction = 0; - } if (musicOnly) { // This flag is used when the screen is off to only affect // active media @@ -219,9 +216,23 @@ public class MediaSessionLegacyHelper { flags = AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_VIBRATE; } } - - mSessionManager.dispatchAdjustVolume(AudioManager.USE_DEFAULT_STREAM_TYPE, - direction, flags); + if (direction != 0) { + // If this is action up we want to send a beep for non-music events + if (up) { + direction = 0; + } + mSessionManager.dispatchAdjustVolume(AudioManager.USE_DEFAULT_STREAM_TYPE, + direction, flags); + } else if (isMute) { + if (down) { + // We need to send two volume events on down, one to mute + // and one to show the UI + mSessionManager.dispatchAdjustVolume(AudioManager.USE_DEFAULT_STREAM_TYPE, + MediaSessionManager.DIRECTION_MUTE, flags); + } + mSessionManager.dispatchAdjustVolume(AudioManager.USE_DEFAULT_STREAM_TYPE, + 0 /* direction, causes UI to show on down */, flags); + } } } diff --git a/media/java/android/media/session/MediaSessionManager.java b/media/java/android/media/session/MediaSessionManager.java index b4fff8f..a4ef851 100644 --- a/media/java/android/media/session/MediaSessionManager.java +++ b/media/java/android/media/session/MediaSessionManager.java @@ -59,6 +59,14 @@ public final class MediaSessionManager { private Context mContext; /** + * Special flag for sending the mute key to dispatchAdjustVolume used by the + * system. + * + * @hide + */ + public static final int DIRECTION_MUTE = -99; + + /** * @hide */ public MediaSessionManager(Context context) { |