Merge "Route mute key events through MediaSessionService" into lmp-mr1-dev
This commit is contained in:
@@ -137,6 +137,17 @@ public class AudioManager {
|
||||
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
|
||||
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
|
||||
@@ -220,6 +231,13 @@ public class AudioManager {
|
||||
public static final String EXTRA_MASTER_VOLUME_MUTED =
|
||||
"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.
|
||||
*
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================================
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -58,6 +58,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
|
||||
*/
|
||||
|
||||
@@ -35,6 +35,7 @@ import android.media.session.ISessionControllerCallback;
|
||||
import android.media.session.MediaController;
|
||||
import android.media.session.MediaController.PlaybackInfo;
|
||||
import android.media.session.MediaSession;
|
||||
import android.media.session.MediaSessionManager;
|
||||
import android.media.session.ParcelableVolumeInfo;
|
||||
import android.media.session.PlaybackState;
|
||||
import android.media.AudioAttributes;
|
||||
@@ -92,6 +93,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient {
|
||||
private final MediaSessionService mService;
|
||||
private final boolean mUseMasterVolume;
|
||||
|
||||
private final IBinder mICallback = new Binder();
|
||||
private final Object mLock = new Object();
|
||||
private final ArrayList<ISessionControllerCallback> mControllerCallbacks =
|
||||
new ArrayList<ISessionControllerCallback>();
|
||||
@@ -245,6 +247,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient {
|
||||
if (isPlaybackActive(false) || hasFlag(MediaSession.FLAG_EXCLUSIVE_GLOBAL_PRIORITY)) {
|
||||
flags &= ~AudioManager.FLAG_PLAY_SOUND;
|
||||
}
|
||||
boolean isMute = direction == MediaSessionManager.DIRECTION_MUTE;
|
||||
if (direction > 1) {
|
||||
direction = 1;
|
||||
} else if (direction < -1) {
|
||||
@@ -254,29 +257,52 @@ public class MediaSessionRecord implements IBinder.DeathRecipient {
|
||||
if (mUseMasterVolume) {
|
||||
// If this device only uses master volume and playback is local
|
||||
// just adjust the master volume and return.
|
||||
mAudioManagerInternal.adjustMasterVolumeForUid(direction, flags, packageName, uid);
|
||||
if (isMute) {
|
||||
mAudioManagerInternal.setMasterMuteForUid(!mAudioManager.isMasterMute(),
|
||||
flags, packageName, mICallback, uid);
|
||||
} else {
|
||||
mAudioManagerInternal.adjustMasterVolumeForUid(direction, flags, packageName,
|
||||
uid);
|
||||
}
|
||||
return;
|
||||
}
|
||||
int stream = AudioAttributes.toLegacyStreamType(mAudioAttrs);
|
||||
if (useSuggested) {
|
||||
if (AudioSystem.isStreamActive(stream, 0)) {
|
||||
mAudioManagerInternal.adjustSuggestedStreamVolumeForUid(stream, direction,
|
||||
flags, packageName, uid);
|
||||
if (isMute) {
|
||||
mAudioManager.setStreamMute(stream, !mAudioManager.isStreamMute(stream));
|
||||
} else {
|
||||
mAudioManagerInternal.adjustSuggestedStreamVolumeForUid(stream, direction,
|
||||
flags, packageName, uid);
|
||||
}
|
||||
} else {
|
||||
flags |= previousFlagPlaySound;
|
||||
mAudioManagerInternal.adjustSuggestedStreamVolumeForUid(
|
||||
AudioManager.USE_DEFAULT_STREAM_TYPE, direction, flags, packageName,
|
||||
uid);
|
||||
if (isMute) {
|
||||
mAudioManager.setStreamMute(AudioManager.USE_DEFAULT_STREAM_TYPE,
|
||||
!mAudioManager.isStreamMute(AudioManager.USE_DEFAULT_STREAM_TYPE));
|
||||
} else {
|
||||
mAudioManagerInternal.adjustSuggestedStreamVolumeForUid(
|
||||
AudioManager.USE_DEFAULT_STREAM_TYPE, direction, flags, packageName,
|
||||
uid);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mAudioManagerInternal.adjustStreamVolumeForUid(stream, direction, flags,
|
||||
packageName, uid);
|
||||
if (isMute) {
|
||||
mAudioManager.setStreamMute(stream, !mAudioManager.isStreamMute(stream));
|
||||
} else {
|
||||
mAudioManagerInternal.adjustStreamVolumeForUid(stream, direction, flags,
|
||||
packageName, uid);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (mVolumeControlType == VolumeProvider.VOLUME_CONTROL_FIXED) {
|
||||
// Nothing to do, the volume cannot be changed
|
||||
return;
|
||||
}
|
||||
if (isMute) {
|
||||
Log.w(TAG, "Muting remote playback is not supported");
|
||||
return;
|
||||
}
|
||||
mSessionCb.adjustVolume(direction);
|
||||
|
||||
int volumeBefore = (mOptimisticVolume < 0 ? mCurrentVolume : mOptimisticVolume);
|
||||
|
||||
@@ -40,6 +40,7 @@ import android.media.session.ISessionCallback;
|
||||
import android.media.session.ISessionManager;
|
||||
import android.media.session.MediaController.PlaybackInfo;
|
||||
import android.media.session.MediaSession;
|
||||
import android.media.session.MediaSessionManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Binder;
|
||||
import android.os.Bundle;
|
||||
@@ -588,6 +589,8 @@ public class MediaSessionService extends SystemService implements Monitor {
|
||||
"android.media.AudioService.WAKELOCK_ACQUIRED";
|
||||
private static final int WAKELOCK_RELEASE_ON_FINISHED = 1980; // magic number
|
||||
|
||||
private final IBinder mICallback = new Binder();
|
||||
|
||||
private boolean mVoiceButtonDown = false;
|
||||
private boolean mVoiceButtonHandled = false;
|
||||
|
||||
@@ -720,8 +723,7 @@ public class MediaSessionService extends SystemService implements Monitor {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatchAdjustVolume(int suggestedStream, int delta, int flags)
|
||||
throws RemoteException {
|
||||
public void dispatchAdjustVolume(int suggestedStream, int delta, int flags) {
|
||||
final int pid = Binder.getCallingPid();
|
||||
final int uid = Binder.getCallingUid();
|
||||
final long token = Binder.clearCallingIdentity();
|
||||
@@ -828,11 +830,21 @@ public class MediaSessionService extends SystemService implements Monitor {
|
||||
}
|
||||
try {
|
||||
if (mUseMasterVolume) {
|
||||
mAudioService.adjustMasterVolume(direction, flags,
|
||||
getContext().getOpPackageName());
|
||||
if (direction == MediaSessionManager.DIRECTION_MUTE) {
|
||||
mAudioService.setMasterMute(!mAudioService.isMasterMute(), flags,
|
||||
getContext().getOpPackageName(), mICallback);
|
||||
} else {
|
||||
mAudioService.adjustMasterVolume(direction, flags,
|
||||
getContext().getOpPackageName());
|
||||
}
|
||||
} else {
|
||||
mAudioService.adjustSuggestedStreamVolume(direction, suggestedStream, flags,
|
||||
getContext().getOpPackageName());
|
||||
if (direction == MediaSessionManager.DIRECTION_MUTE) {
|
||||
mAudioService.setStreamMute(suggestedStream,
|
||||
!mAudioService.isStreamMute(suggestedStream), mICallback);
|
||||
} else {
|
||||
mAudioService.adjustSuggestedStreamVolume(direction, suggestedStream,
|
||||
flags, getContext().getOpPackageName());
|
||||
}
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Error adjusting default volume.", e);
|
||||
@@ -841,7 +853,7 @@ public class MediaSessionService extends SystemService implements Monitor {
|
||||
session.adjustVolume(direction, flags, getContext().getPackageName(),
|
||||
UserHandle.myUserId(), true);
|
||||
if (session.getPlaybackType() == PlaybackInfo.PLAYBACK_TYPE_REMOTE
|
||||
&& mRvc != null) {
|
||||
&& mRvc != null && direction != MediaSessionManager.DIRECTION_MUTE) {
|
||||
try {
|
||||
mRvc.remoteVolumeChanged(session.getControllerBinder(), flags);
|
||||
} catch (Exception e) {
|
||||
|
||||
Reference in New Issue
Block a user