Methods Summary |
---|
public void | adjustVolume(int direction, int flags, java.lang.String packageName, int uid, boolean useSuggested)Send a volume adjustment to the session owner. Direction must be one of
{@link AudioManager#ADJUST_LOWER}, {@link AudioManager#ADJUST_RAISE},
{@link AudioManager#ADJUST_SAME}.
int previousFlagPlaySound = flags & AudioManager.FLAG_PLAY_SOUND;
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) {
direction = -1;
}
if (mVolumeType == PlaybackInfo.PLAYBACK_TYPE_LOCAL) {
if (mUseMasterVolume) {
// If this device only uses master volume and playback is local
// just adjust the master volume and return.
boolean isMasterMute = mAudioManager.isMasterMute();
if (isMute) {
mAudioManagerInternal.setMasterMuteForUid(!isMasterMute,
flags, packageName, mService.mICallback, uid);
} else {
mAudioManagerInternal.adjustMasterVolumeForUid(direction, flags, packageName,
uid);
if (isMasterMute) {
mAudioManagerInternal.setMasterMuteForUid(false,
flags, packageName, mService.mICallback, uid);
}
}
return;
}
int stream = AudioAttributes.toLegacyStreamType(mAudioAttrs);
boolean isStreamMute = mAudioManager.isStreamMute(stream);
if (useSuggested) {
if (AudioSystem.isStreamActive(stream, 0)) {
if (isMute) {
mAudioManager.setStreamMute(stream, !isStreamMute);
} else {
mAudioManagerInternal.adjustSuggestedStreamVolumeForUid(stream, direction,
flags, packageName, uid);
if (isStreamMute && direction != 0) {
mAudioManager.setStreamMute(stream, false);
}
}
} else {
flags |= previousFlagPlaySound;
isStreamMute =
mAudioManager.isStreamMute(AudioManager.USE_DEFAULT_STREAM_TYPE);
if (isMute) {
mAudioManager.setStreamMute(AudioManager.USE_DEFAULT_STREAM_TYPE,
!isStreamMute);
} else {
mAudioManagerInternal.adjustSuggestedStreamVolumeForUid(
AudioManager.USE_DEFAULT_STREAM_TYPE, direction, flags, packageName,
uid);
if (isStreamMute && direction != 0) {
mAudioManager.setStreamMute(AudioManager.USE_DEFAULT_STREAM_TYPE,
false);
}
}
}
} else {
if (isMute) {
mAudioManager.setStreamMute(stream, !isStreamMute);
} else {
mAudioManagerInternal.adjustStreamVolumeForUid(stream, direction, flags,
packageName, uid);
if (isStreamMute && direction != 0) {
mAudioManager.setStreamMute(stream, false);
}
}
}
} 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);
mOptimisticVolume = volumeBefore + direction;
mOptimisticVolume = Math.max(0, Math.min(mOptimisticVolume, mMaxVolume));
mHandler.removeCallbacks(mClearOptimisticVolumeRunnable);
mHandler.postDelayed(mClearOptimisticVolumeRunnable, OPTIMISTIC_VOLUME_TIMEOUT);
if (volumeBefore != mOptimisticVolume) {
pushVolumeUpdate();
}
mService.notifyRemoteVolumeChanged(flags, this);
if (DEBUG) {
Log.d(TAG, "Adjusted optimistic volume to " + mOptimisticVolume + " max is "
+ mMaxVolume);
}
}
|
public void | binderDied()
mService.sessionDied(this);
|
public void | dump(java.io.PrintWriter pw, java.lang.String prefix)
pw.println(prefix + mTag + " " + this);
final String indent = prefix + " ";
pw.println(indent + "ownerPid=" + mOwnerPid + ", ownerUid=" + mOwnerUid
+ ", userId=" + mUserId);
pw.println(indent + "package=" + mPackageName);
pw.println(indent + "launchIntent=" + mLaunchIntent);
pw.println(indent + "mediaButtonReceiver=" + mMediaButtonReceiver);
pw.println(indent + "active=" + mIsActive);
pw.println(indent + "flags=" + mFlags);
pw.println(indent + "rating type=" + mRatingType);
pw.println(indent + "controllers: " + mControllerCallbacks.size());
pw.println(indent + "state=" + (mPlaybackState == null ? null : mPlaybackState.toString()));
pw.println(indent + "audioAttrs=" + mAudioAttrs);
pw.println(indent + "volumeType=" + mVolumeType + ", controlType=" + mVolumeControlType
+ ", max=" + mMaxVolume + ", current=" + mCurrentVolume);
pw.println(indent + "metadata:" + getShortMetadataString());
pw.println(indent + "queueTitle=" + mQueueTitle + ", size="
+ (mQueue == null ? 0 : mQueue.getList().size()));
|
public android.media.AudioAttributes | getAudioAttributes()Get the local audio stream being used. Only valid if playback type is
local.
return mAudioAttrs;
|
public android.media.session.ISessionCallback | getCallback()
return mSessionCb.mCb;
|
public android.media.session.ISessionController | getControllerBinder()Get the binder for the {@link MediaController}.
return mController;
|
private int | getControllerCbIndexForCb(android.media.session.ISessionControllerCallback cb)
IBinder binder = cb.asBinder();
for (int i = mControllerCallbacks.size() - 1; i >= 0; i--) {
if (binder.equals(mControllerCallbacks.get(i).asBinder())) {
return i;
}
}
return -1;
|
public int | getCurrentVolume()Get the current volume for this session. Only valid if playback type is
remote.
return mCurrentVolume;
|
public long | getFlags()Get this session's flags.
return mFlags;
|
public int | getMaxVolume()Get the max volume that can be set. Only valid if playback type is
remote.
return mMaxVolume;
|
public android.app.PendingIntent | getMediaButtonReceiver()Get the intent the app set for their media button receiver.
return mMediaButtonReceiver;
|
public int | getOptimisticVolume()Get the volume we'd like it to be set to. This is only valid for a short
while after a call to adjust or set volume.
return mOptimisticVolume;
|
public java.lang.String | getPackageName()Get the info for this session.
return mPackageName;
|
public int | getPlaybackType()Get the type of playback, either local or remote.
return mVolumeType;
|
public android.media.session.ISession | getSessionBinder()Get the binder for the {@link MediaSession}.
return mSession;
|
private java.lang.String | getShortMetadataString()
int fields = mMetadata == null ? 0 : mMetadata.size();
MediaDescription description = mMetadata == null ? null : mMetadata
.getDescription();
return "size=" + fields + ", description=" + description;
|
private android.media.session.PlaybackState | getStateWithUpdatedPosition()
PlaybackState state;
long duration = -1;
synchronized (mLock) {
state = mPlaybackState;
if (mMetadata != null && mMetadata.containsKey(MediaMetadata.METADATA_KEY_DURATION)) {
duration = mMetadata.getLong(MediaMetadata.METADATA_KEY_DURATION);
}
}
PlaybackState result = null;
if (state != null) {
if (state.getState() == PlaybackState.STATE_PLAYING
|| state.getState() == PlaybackState.STATE_FAST_FORWARDING
|| state.getState() == PlaybackState.STATE_REWINDING) {
long updateTime = state.getLastPositionUpdateTime();
long currentTime = SystemClock.elapsedRealtime();
if (updateTime > 0) {
long position = (long) (state.getPlaybackSpeed()
* (currentTime - updateTime)) + state.getPosition();
if (duration >= 0 && position > duration) {
position = duration;
} else if (position < 0) {
position = 0;
}
PlaybackState.Builder builder = new PlaybackState.Builder(state);
builder.setState(state.getState(), position, state.getPlaybackSpeed(),
currentTime);
result = builder.build();
}
}
}
return result == null ? state : result;
|
public java.lang.String | getTag()Get the tag for the session.
return mTag;
|
public int | getUserId()Get the user id this session was created for.
return mUserId;
|
public int | getVolumeControl()Get the type of volume control. Only valid if playback type is remote.
return mVolumeControlType;
|
public boolean | hasFlag(int flag)Check if this session has the specified flag.
return (mFlags & flag) != 0;
|
public boolean | isActive()Check if this session has been set to active by the app.
return mIsActive && !mDestroyed;
|
public boolean | isPlaybackActive(boolean includeRecentlyActive)Check if the session is currently performing playback. This will also
return true if the session was recently paused.
int state = mPlaybackState == null ? 0 : mPlaybackState.getState();
if (MediaSession.isActiveState(state)) {
return true;
}
if (includeRecentlyActive && state == mPlaybackState.STATE_PAUSED) {
long inactiveTime = SystemClock.uptimeMillis() - mLastActiveTime;
if (inactiveTime < ACTIVE_BUFFER) {
return true;
}
}
return false;
|
public boolean | isSystemPriority()Check if this session has system priorty and should receive media buttons
before any other sessions.
return (mFlags & MediaSession.FLAG_EXCLUSIVE_GLOBAL_PRIORITY) != 0;
|
public boolean | isTransportControlEnabled()
return hasFlag(MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS);
|
public void | onDestroy()Finish cleaning up this session, including disconnecting if connected and
removing the death observer from the callback binder.
synchronized (mLock) {
if (mDestroyed) {
return;
}
mDestroyed = true;
mHandler.post(MessageHandler.MSG_DESTROYED);
}
|
private void | pushEvent(java.lang.String event, android.os.Bundle data)
synchronized (mLock) {
if (mDestroyed) {
return;
}
for (int i = mControllerCallbacks.size() - 1; i >= 0; i--) {
ISessionControllerCallback cb = mControllerCallbacks.get(i);
try {
cb.onEvent(event, data);
} catch (DeadObjectException e) {
Log.w(TAG, "Removing dead callback in pushEvent.", e);
mControllerCallbacks.remove(i);
} catch (RemoteException e) {
Log.w(TAG, "unexpected exception in pushEvent.", e);
}
}
}
|
private void | pushExtrasUpdate()
synchronized (mLock) {
if (mDestroyed) {
return;
}
for (int i = mControllerCallbacks.size() - 1; i >= 0; i--) {
ISessionControllerCallback cb = mControllerCallbacks.get(i);
try {
cb.onExtrasChanged(mExtras);
} catch (DeadObjectException e) {
mControllerCallbacks.remove(i);
Log.w(TAG, "Removed dead callback in pushExtrasUpdate.", e);
} catch (RemoteException e) {
Log.w(TAG, "unexpected exception in pushExtrasUpdate.", e);
}
}
}
|
private void | pushMetadataUpdate()
synchronized (mLock) {
if (mDestroyed) {
return;
}
for (int i = mControllerCallbacks.size() - 1; i >= 0; i--) {
ISessionControllerCallback cb = mControllerCallbacks.get(i);
try {
cb.onMetadataChanged(mMetadata);
} catch (DeadObjectException e) {
Log.w(TAG, "Removing dead callback in pushMetadataUpdate. ", e);
mControllerCallbacks.remove(i);
} catch (RemoteException e) {
Log.w(TAG, "unexpected exception in pushMetadataUpdate. ", e);
}
}
}
|
private void | pushPlaybackStateUpdate()
synchronized (mLock) {
if (mDestroyed) {
return;
}
for (int i = mControllerCallbacks.size() - 1; i >= 0; i--) {
ISessionControllerCallback cb = mControllerCallbacks.get(i);
try {
cb.onPlaybackStateChanged(mPlaybackState);
} catch (DeadObjectException e) {
mControllerCallbacks.remove(i);
Log.w(TAG, "Removed dead callback in pushPlaybackStateUpdate.", e);
} catch (RemoteException e) {
Log.w(TAG, "unexpected exception in pushPlaybackStateUpdate.", e);
}
}
}
|
private void | pushQueueTitleUpdate()
synchronized (mLock) {
if (mDestroyed) {
return;
}
for (int i = mControllerCallbacks.size() - 1; i >= 0; i--) {
ISessionControllerCallback cb = mControllerCallbacks.get(i);
try {
cb.onQueueTitleChanged(mQueueTitle);
} catch (DeadObjectException e) {
mControllerCallbacks.remove(i);
Log.w(TAG, "Removed dead callback in pushQueueTitleUpdate.", e);
} catch (RemoteException e) {
Log.w(TAG, "unexpected exception in pushQueueTitleUpdate.", e);
}
}
}
|
private void | pushQueueUpdate()
synchronized (mLock) {
if (mDestroyed) {
return;
}
for (int i = mControllerCallbacks.size() - 1; i >= 0; i--) {
ISessionControllerCallback cb = mControllerCallbacks.get(i);
try {
cb.onQueueChanged(mQueue);
} catch (DeadObjectException e) {
mControllerCallbacks.remove(i);
Log.w(TAG, "Removed dead callback in pushQueueUpdate.", e);
} catch (RemoteException e) {
Log.w(TAG, "unexpected exception in pushQueueUpdate.", e);
}
}
}
|
private void | pushSessionDestroyed()
synchronized (mLock) {
// This is the only method that may be (and can only be) called
// after the session is destroyed.
if (!mDestroyed) {
return;
}
for (int i = mControllerCallbacks.size() - 1; i >= 0; i--) {
ISessionControllerCallback cb = mControllerCallbacks.get(i);
try {
cb.onSessionDestroyed();
} catch (DeadObjectException e) {
Log.w(TAG, "Removing dead callback in pushEvent.", e);
mControllerCallbacks.remove(i);
} catch (RemoteException e) {
Log.w(TAG, "unexpected exception in pushEvent.", e);
}
}
// After notifying clear all listeners
mControllerCallbacks.clear();
}
|
private void | pushVolumeUpdate()
synchronized (mLock) {
if (mDestroyed) {
return;
}
ParcelableVolumeInfo info = mController.getVolumeAttributes();
for (int i = mControllerCallbacks.size() - 1; i >= 0; i--) {
ISessionControllerCallback cb = mControllerCallbacks.get(i);
try {
cb.onVolumeInfoChanged(info);
} catch (DeadObjectException e) {
Log.w(TAG, "Removing dead callback in pushVolumeUpdate. ", e);
} catch (RemoteException e) {
Log.w(TAG, "Unexpected exception in pushVolumeUpdate. ", e);
}
}
}
|
public void | sendMediaButton(android.view.KeyEvent ke, int sequenceId, android.os.ResultReceiver cb)
mSessionCb.sendMediaButton(ke, sequenceId, cb);
|
public void | setVolumeTo(int value, int flags, java.lang.String packageName, int uid)
if (mVolumeType == PlaybackInfo.PLAYBACK_TYPE_LOCAL) {
int stream = AudioAttributes.toLegacyStreamType(mAudioAttrs);
mAudioManagerInternal.setStreamVolumeForUid(stream, value, flags, packageName, uid);
} else {
if (mVolumeControlType != VolumeProvider.VOLUME_CONTROL_ABSOLUTE) {
// Nothing to do. The volume can't be set directly.
return;
}
value = Math.max(0, Math.min(value, mMaxVolume));
mSessionCb.setVolumeTo(value);
int volumeBefore = (mOptimisticVolume < 0 ? mCurrentVolume : mOptimisticVolume);
mOptimisticVolume = Math.max(0, Math.min(value, mMaxVolume));
mHandler.removeCallbacks(mClearOptimisticVolumeRunnable);
mHandler.postDelayed(mClearOptimisticVolumeRunnable, OPTIMISTIC_VOLUME_TIMEOUT);
if (volumeBefore != mOptimisticVolume) {
pushVolumeUpdate();
}
mService.notifyRemoteVolumeChanged(flags, this);
if (DEBUG) {
Log.d(TAG, "Set optimistic volume to " + mOptimisticVolume + " max is "
+ mMaxVolume);
}
}
|
public java.lang.String | toString()
return mPackageName + "/" + mTag;
|