From 79fa4630bbca7c6c251eea99fe8997e4b45becee Mon Sep 17 00:00:00 2001 From: RoboErik Date: Tue, 27 May 2014 16:49:09 -0700 Subject: API changes to sessions Changes requested by API Council review. A second CL will refactor TransportController and TransportPerformer based on feedback. Change-Id: Ie26a7d01d7021232a66c2edf1eb58120437fdfde --- media/java/android/media/MediaMetadata.java | 11 ++ media/java/android/media/RemoteControlClient.java | 4 +- .../android/media/session/ISessionController.aidl | 2 +- .../android/media/session/MediaController.java | 29 ++--- media/java/android/media/session/MediaSession.java | 52 ++++---- .../android/media/session/MediaSessionInfo.java | 2 + .../media/session/MediaSessionLegacyHelper.java | 22 ++-- .../android/media/session/MediaSessionManager.java | 1 + .../android/media/session/MediaSessionToken.java | 7 +- .../java/android/media/session/PlaybackState.java | 132 ++++++++++----------- .../media/session/RemoteVolumeProvider.java | 37 ++++-- .../android/media/session/TransportController.java | 6 +- .../android/media/session/TransportPerformer.java | 117 +++++++++--------- 13 files changed, 226 insertions(+), 196 deletions(-) (limited to 'media') diff --git a/media/java/android/media/MediaMetadata.java b/media/java/android/media/MediaMetadata.java index ff73a10..5dc8e1b 100644 --- a/media/java/android/media/MediaMetadata.java +++ b/media/java/android/media/MediaMetadata.java @@ -23,6 +23,8 @@ import android.util.ArrayMap; import android.util.Log; import android.util.SparseArray; +import java.util.Set; + /** * Contains metadata about an item, such as the title, artist, etc. */ @@ -301,6 +303,15 @@ public final class MediaMetadata implements Parcelable { } /** + * Returns a Set containing the Strings used as keys in this metadata. + * + * @return a Set of String keys + */ + public Set keySet() { + return mBundle.keySet(); + } + + /** * Helper for getting the String key used by {@link MediaMetadata} from the * integer key that {@link MediaMetadataEditor} uses. * diff --git a/media/java/android/media/RemoteControlClient.java b/media/java/android/media/RemoteControlClient.java index 26ae3cc..b89affd 100644 --- a/media/java/android/media/RemoteControlClient.java +++ b/media/java/android/media/RemoteControlClient.java @@ -1317,7 +1317,7 @@ public class RemoteControlClient } // USE_SESSIONS - private TransportPerformer.Listener mTransportListener = new TransportPerformer.Listener() { + private TransportPerformer.Callback mTransportListener = new TransportPerformer.Callback() { @Override public void onSeekTo(long pos) { @@ -1325,7 +1325,7 @@ public class RemoteControlClient } @Override - public void onRate(Rating rating) { + public void onSetRating(Rating rating) { if ((mTransportControlFlags & FLAG_KEY_MEDIA_RATING) != 0) { if (mEventHandler != null) { mEventHandler.sendMessage(mEventHandler.obtainMessage( diff --git a/media/java/android/media/session/ISessionController.aidl b/media/java/android/media/session/ISessionController.aidl index 5ddb6db..9ce0692 100644 --- a/media/java/android/media/session/ISessionController.aidl +++ b/media/java/android/media/session/ISessionController.aidl @@ -30,7 +30,7 @@ import android.view.KeyEvent; */ interface ISessionController { void sendCommand(String command, in Bundle extras, in ResultReceiver cb); - void sendMediaButton(in KeyEvent mediaButton); + boolean sendMediaButton(in KeyEvent mediaButton); void registerCallbackListener(in ISessionControllerCallback cb); void unregisterCallbackListener(in ISessionControllerCallback cb); boolean isTransportControlEnabled(); diff --git a/media/java/android/media/session/MediaController.java b/media/java/android/media/session/MediaController.java index 642ac2f..63c0839 100644 --- a/media/java/android/media/session/MediaController.java +++ b/media/java/android/media/session/MediaController.java @@ -103,24 +103,25 @@ public final class MediaController { } /** - * Send the specified media button to the session. Only media keys can be - * sent using this method. + * Send the specified media button event to the session. Only media keys can + * be sent by this method, other keys will be ignored. * - * @param keycode The media button keycode, such as - * {@link KeyEvent#KEYCODE_MEDIA_PLAY}. + * @param keyEvent The media button event to dispatch. + * @return true if the event was sent to the session, false otherwise. */ - public void sendMediaButton(int keycode) { - if (!KeyEvent.isMediaKey(keycode)) { - throw new IllegalArgumentException("May only send media buttons through " - + "sendMediaButton"); + public boolean dispatchMediaButtonEvent(KeyEvent keyEvent) { + if (keyEvent == null) { + throw new IllegalArgumentException("KeyEvent may not be null"); + } + if (!KeyEvent.isMediaKey(keyEvent.getKeyCode())) { + return false; } - // TODO do something better than key down/up events - KeyEvent event = new KeyEvent(KeyEvent.ACTION_UP, keycode); try { - mSessionBinder.sendMediaButton(event); + return mSessionBinder.sendMediaButton(keyEvent); } catch (RemoteException e) { Log.d(TAG, "Dead object in sendMediaButton", e); } + return false; } /** @@ -171,7 +172,7 @@ public final class MediaController { * @param params Any parameters to include with the command * @param cb The callback to receive the result on */ - public void sendCommand(String command, Bundle params, ResultReceiver cb) { + public void sendControlCommand(String command, Bundle params, ResultReceiver cb) { if (TextUtils.isEmpty(command)) { throw new IllegalArgumentException("command cannot be null or empty"); } @@ -282,7 +283,7 @@ public final class MediaController { * * @param event */ - public void onEvent(String event, Bundle extras) { + public void onSessionEvent(String event, Bundle extras) { } /** @@ -354,7 +355,7 @@ public final class MediaController { public void handleMessage(Message msg) { switch (msg.what) { case MSG_EVENT: - mCallback.onEvent((String) msg.obj, msg.getData()); + mCallback.onSessionEvent((String) msg.obj, msg.getData()); break; case MSG_ROUTE: mCallback.onRouteChanged((RouteInfo) msg.obj); diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java index 539dc3c..51dcee1 100644 --- a/media/java/android/media/session/MediaSession.java +++ b/media/java/android/media/session/MediaSession.java @@ -49,12 +49,8 @@ import java.util.List; *

* A MediaSession is created by calling * {@link MediaSessionManager#createSession(String)}. Once a session is created - * apps that have the MEDIA_CONTENT_CONTROL permission can interact with the - * session through - * {@link MediaSessionManager#getActiveSessions(android.content.ComponentName)}. - * The owner of the session may also use {@link #getSessionToken()} to allow - * apps without this permission to create a {@link MediaController} to interact - * with this session. + * the owner of the session may use {@link #getSessionToken()} to allow apps to + * create a {@link MediaController} to interact with this session. *

* To receive commands, media keys, and other events a Callback must be set with * {@link #addCallback(Callback)}. @@ -166,7 +162,9 @@ public final class MediaSession { } /** - * Set the callback to receive updates on. + * Add a callback to receive updates on for the MediaSession. This includes + * media button and volume events. The caller's thread will be used to post + * events. * * @param callback The callback object */ @@ -246,7 +244,7 @@ public final class MediaSession { /** * Set the stream this session is playing on. This will affect the system's - * volume handling for this session. If {@link #useRemotePlayback} was + * volume handling for this session. If {@link #setPlaybackToRemote} was * previously called it will stop receiving volume commands and the system * will begin sending volume changes to the appropriate stream. *

@@ -254,21 +252,21 @@ public final class MediaSession { * * @param stream The {@link AudioManager} stream this session is playing on. */ - public void useLocalPlayback(int stream) { + public void setPlaybackToLocal(int stream) { // TODO } /** * Configure this session to use remote volume handling. This must be called * to receive volume button events, otherwise the system will adjust the - * current stream volume for this session. If {@link #useLocalPlayback} was - * previously called that stream will stop receiving volume changes for this - * session. + * current stream volume for this session. If {@link #setPlaybackToLocal} + * was previously called that stream will stop receiving volume changes for + * this session. * * @param volumeProvider The provider that will handle volume changes. May * not be null. */ - public void useRemotePlayback(RemoteVolumeProvider volumeProvider) { + public void setPlaybackToRemote(RemoteVolumeProvider volumeProvider) { if (volumeProvider == null) { throw new IllegalArgumentException("volumeProvider may not be null!"); } @@ -312,7 +310,7 @@ public final class MediaSession { * @param event The name of the event to send * @param extras Any extras included with the event */ - public void sendEvent(String event, Bundle extras) { + public void sendSessionEvent(String event, Bundle extras) { if (TextUtils.isEmpty(event)) { throw new IllegalArgumentException("event cannot be null or empty"); } @@ -525,7 +523,7 @@ public final class MediaSession { * @param mediaButtonIntent an intent containing the KeyEvent as an * extra */ - public void onMediaButton(Intent mediaButtonIntent) { + public void onMediaButtonEvent(Intent mediaButtonIntent) { } /** @@ -536,7 +534,7 @@ public final class MediaSession { * @param command * @param extras optional */ - public void onCommand(String command, Bundle extras, ResultReceiver cb) { + public void onControlCommand(String command, Bundle extras, ResultReceiver cb) { } /** @@ -645,7 +643,7 @@ public final class MediaSession { if (session != null) { TransportPerformer tp = session.getTransportPerformer(); if (tp != null) { - tp.onPlay(); + tp.dispatchPlay(); } } } @@ -656,7 +654,7 @@ public final class MediaSession { if (session != null) { TransportPerformer tp = session.getTransportPerformer(); if (tp != null) { - tp.onPause(); + tp.dispatchPause(); } } } @@ -667,7 +665,7 @@ public final class MediaSession { if (session != null) { TransportPerformer tp = session.getTransportPerformer(); if (tp != null) { - tp.onStop(); + tp.dispatchStop(); } } } @@ -678,7 +676,7 @@ public final class MediaSession { if (session != null) { TransportPerformer tp = session.getTransportPerformer(); if (tp != null) { - tp.onNext(); + tp.dispatchNext(); } } } @@ -689,7 +687,7 @@ public final class MediaSession { if (session != null) { TransportPerformer tp = session.getTransportPerformer(); if (tp != null) { - tp.onPrevious(); + tp.dispatchPrevious(); } } } @@ -700,7 +698,7 @@ public final class MediaSession { if (session != null) { TransportPerformer tp = session.getTransportPerformer(); if (tp != null) { - tp.onFastForward(); + tp.dispatchFastForward(); } } } @@ -711,7 +709,7 @@ public final class MediaSession { if (session != null) { TransportPerformer tp = session.getTransportPerformer(); if (tp != null) { - tp.onRewind(); + tp.dispatchRewind(); } } } @@ -722,7 +720,7 @@ public final class MediaSession { if (session != null) { TransportPerformer tp = session.getTransportPerformer(); if (tp != null) { - tp.onSeekTo(pos); + tp.dispatchSeekTo(pos); } } } @@ -733,7 +731,7 @@ public final class MediaSession { if (session != null) { TransportPerformer tp = session.getTransportPerformer(); if (tp != null) { - tp.onRate(rating); + tp.dispatchRate(rating); } } } @@ -776,11 +774,11 @@ public final class MediaSession { } switch (msg.what) { case MSG_MEDIA_BUTTON: - mCallback.onMediaButton((Intent) msg.obj); + mCallback.onMediaButtonEvent((Intent) msg.obj); break; case MSG_COMMAND: Command cmd = (Command) msg.obj; - mCallback.onCommand(cmd.command, cmd.extras, cmd.stub); + mCallback.onControlCommand(cmd.command, cmd.extras, cmd.stub); break; case MSG_ROUTE_CHANGE: mCallback.onRequestRouteChange((RouteInfo) msg.obj); diff --git a/media/java/android/media/session/MediaSessionInfo.java b/media/java/android/media/session/MediaSessionInfo.java index 3d8d33f..f701211 100644 --- a/media/java/android/media/session/MediaSessionInfo.java +++ b/media/java/android/media/session/MediaSessionInfo.java @@ -20,6 +20,8 @@ import android.os.Parcelable; /** * Information about a media session, including the owner's package name. + * + * @hide */ public final class MediaSessionInfo implements Parcelable { private final String mId; diff --git a/media/java/android/media/session/MediaSessionLegacyHelper.java b/media/java/android/media/session/MediaSessionLegacyHelper.java index 249b9c4..bdf3628 100644 --- a/media/java/android/media/session/MediaSessionLegacyHelper.java +++ b/media/java/android/media/session/MediaSessionLegacyHelper.java @@ -76,7 +76,7 @@ public class MediaSessionLegacyHelper { } } - public void addRccListener(PendingIntent pi, TransportPerformer.Listener listener) { + public void addRccListener(PendingIntent pi, TransportPerformer.Callback listener) { if (pi == null) { Log.w(TAG, "Pending intent was null, can't add rcc listener."); return; @@ -92,9 +92,9 @@ public class MediaSessionLegacyHelper { return; } // Otherwise it changed so we need to switch to the new one - performer.removeListener(holder.mRccListener); + performer.removeCallback(holder.mRccListener); } - performer.addListener(listener, mHandler); + performer.addCallback(listener, mHandler); holder.mRccListener = listener; holder.mFlags |= MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS; holder.mSession.setFlags(holder.mFlags); @@ -110,7 +110,7 @@ public class MediaSessionLegacyHelper { } SessionHolder holder = getHolder(pi, false); if (holder != null && holder.mRccListener != null) { - holder.mSession.getTransportPerformer().removeListener(holder.mRccListener); + holder.mSession.getTransportPerformer().removeCallback(holder.mRccListener); holder.mRccListener = null; holder.mFlags &= ~MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS; holder.mSession.setFlags(holder.mFlags); @@ -141,7 +141,7 @@ public class MediaSessionLegacyHelper { // set this flag holder.mFlags |= MediaSession.FLAG_HANDLES_MEDIA_BUTTONS; holder.mSession.setFlags(holder.mFlags); - holder.mSession.getTransportPerformer().addListener(holder.mMediaButtonListener, mHandler); + holder.mSession.getTransportPerformer().addCallback(holder.mMediaButtonListener, mHandler); holder.mMediaButtonReceiver = new MediaButtonReceiver(pi, context); holder.mSession.addCallback(holder.mMediaButtonReceiver, mHandler); @@ -156,7 +156,7 @@ public class MediaSessionLegacyHelper { } SessionHolder holder = getHolder(pi, false); if (holder != null && holder.mMediaButtonListener != null) { - holder.mSession.getTransportPerformer().removeListener(holder.mMediaButtonListener); + holder.mSession.getTransportPerformer().removeCallback(holder.mMediaButtonListener); holder.mFlags &= ~MediaSession.FLAG_HANDLES_MEDIA_BUTTONS; holder.mSession.setFlags(holder.mFlags); holder.mMediaButtonListener = null; @@ -201,12 +201,12 @@ public class MediaSessionLegacyHelper { } @Override - public void onMediaButton(Intent mediaButtonIntent) { + public void onMediaButtonEvent(Intent mediaButtonIntent) { MediaSessionLegacyHelper.sendKeyEvent(mPendingIntent, mContext, mediaButtonIntent); } } - private static final class MediaButtonListener extends TransportPerformer.Listener { + private static final class MediaButtonListener extends TransportPerformer.Callback { private final PendingIntent mPendingIntent; private final Context mContext; @@ -226,12 +226,12 @@ public class MediaSessionLegacyHelper { } @Override - public void onNext() { + public void onSkipToNext() { sendKeyEvent(KeyEvent.KEYCODE_MEDIA_NEXT); } @Override - public void onPrevious() { + public void onSkipToPrevious() { sendKeyEvent(KeyEvent.KEYCODE_MEDIA_PREVIOUS); } @@ -272,7 +272,7 @@ public class MediaSessionLegacyHelper { public final PendingIntent mPi; public MediaButtonListener mMediaButtonListener; public MediaButtonReceiver mMediaButtonReceiver; - public TransportPerformer.Listener mRccListener; + public TransportPerformer.Callback mRccListener; public int mFlags; public SessionHolder(MediaSession session, PendingIntent pi) { diff --git a/media/java/android/media/session/MediaSessionManager.java b/media/java/android/media/session/MediaSessionManager.java index 0589a7d..8d5e338 100644 --- a/media/java/android/media/session/MediaSessionManager.java +++ b/media/java/android/media/session/MediaSessionManager.java @@ -106,6 +106,7 @@ public final class MediaSessionManager { * @param notificationListener The enabled notification listener component. * May be null. * @return A list of controllers for ongoing sessions + * @hide */ public List getActiveSessions(ComponentName notificationListener) { return getActiveSessionsForUser(notificationListener, UserHandle.myUserId()); diff --git a/media/java/android/media/session/MediaSessionToken.java b/media/java/android/media/session/MediaSessionToken.java index f5569a4..86f5662 100644 --- a/media/java/android/media/session/MediaSessionToken.java +++ b/media/java/android/media/session/MediaSessionToken.java @@ -20,7 +20,12 @@ import android.media.session.ISessionController; import android.os.Parcel; import android.os.Parcelable; -public class MediaSessionToken implements Parcelable { +/** + * Represents an ongoing session. This may be passed to apps by the session + * owner to allow them to create a {@link MediaController} to communicate with + * the session. + */ +public final class MediaSessionToken implements Parcelable { private ISessionController mBinder; /** diff --git a/media/java/android/media/session/PlaybackState.java b/media/java/android/media/session/PlaybackState.java index 7ef38eaa..e09ac3f 100644 --- a/media/java/android/media/session/PlaybackState.java +++ b/media/java/android/media/session/PlaybackState.java @@ -22,7 +22,7 @@ import android.os.SystemClock; /** * Playback state for a {@link MediaSession}. This includes a state like - * {@link PlaybackState#PLAYSTATE_PLAYING}, the current playback position, + * {@link PlaybackState#STATE_PLAYING}, the current playback position, * and the current control capabilities. */ public final class PlaybackState implements Parcelable { @@ -59,28 +59,28 @@ public final class PlaybackState implements Parcelable { * * @see #setActions */ - public static final long ACTION_PREVIOUS_ITEM = 1 << 4; + public static final long ACTION_SKIP_TO_PREVIOUS = 1 << 4; /** * Indicates this performer supports the next command. * * @see #setActions */ - public static final long ACTION_NEXT_ITEM = 1 << 5; + public static final long ACTION_SKIP_TO_NEXT = 1 << 5; /** * Indicates this performer supports the fast forward command. * * @see #setActions */ - public static final long ACTION_FASTFORWARD = 1 << 6; + public static final long ACTION_FAST_FORWARD = 1 << 6; /** * Indicates this performer supports the set rating command. * * @see #setActions */ - public static final long ACTION_RATING = 1 << 7; + public static final long ACTION_SET_RATING = 1 << 7; /** * Indicates this performer supports the seek to command. @@ -102,42 +102,42 @@ public final class PlaybackState implements Parcelable { * * @see #setState */ - public final static int PLAYSTATE_NONE = 0; + public final static int STATE_NONE = 0; /** * State indicating this item is currently stopped. * * @see #setState */ - public final static int PLAYSTATE_STOPPED = 1; + public final static int STATE_STOPPED = 1; /** * State indicating this item is currently paused. * * @see #setState */ - public final static int PLAYSTATE_PAUSED = 2; + public final static int STATE_PAUSED = 2; /** * State indicating this item is currently playing. * * @see #setState */ - public final static int PLAYSTATE_PLAYING = 3; + public final static int STATE_PLAYING = 3; /** * State indicating this item is currently fast forwarding. * * @see #setState */ - public final static int PLAYSTATE_FAST_FORWARDING = 4; + public final static int STATE_FAST_FORWARDING = 4; /** * State indicating this item is currently rewinding. * * @see #setState */ - public final static int PLAYSTATE_REWINDING = 5; + public final static int STATE_REWINDING = 5; /** * State indicating this item is currently buffering and will begin playing @@ -145,7 +145,7 @@ public final class PlaybackState implements Parcelable { * * @see #setState */ - public final static int PLAYSTATE_BUFFERING = 6; + public final static int STATE_BUFFERING = 6; /** * State indicating this item is currently in an error state. The error @@ -153,30 +153,30 @@ public final class PlaybackState implements Parcelable { * * @see #setState */ - public final static int PLAYSTATE_ERROR = 7; + public final static int STATE_ERROR = 7; /** * State indicating the class doing playback is currently connecting to a * route. Depending on the implementation you may return to the previous - * state when the connection finishes or enter {@link #PLAYSTATE_NONE}. If - * the connection failed {@link #PLAYSTATE_ERROR} should be used. + * state when the connection finishes or enter {@link #STATE_NONE}. If + * the connection failed {@link #STATE_ERROR} should be used. * @hide */ - public final static int PLAYSTATE_CONNECTING = 8; + public final static int STATE_CONNECTING = 8; /** * State indicating the player is currently skipping to the previous item. * * @see #setState */ - public final static int PLAYSTATE_SKIPPING_BACKWARDS = 9; + public final static int STATE_SKIPPING_TO_PREVIOUS = 9; /** * State indicating the player is currently skipping to the next item. * * @see #setState */ - public final static int PLAYSTATE_SKIPPING_FORWARDS = 10; + public final static int STATE_SKIPPING_TO_NEXT = 10; /** * Use this value for the position to indicate the position is not known. @@ -188,7 +188,7 @@ public final class PlaybackState implements Parcelable { private long mBufferPosition; private float mRate; private long mActions; - private String mErrorMessage; + private CharSequence mErrorMessage; private long mUpdateTime; /** @@ -221,7 +221,7 @@ public final class PlaybackState implements Parcelable { mUpdateTime = in.readLong(); mBufferPosition = in.readLong(); mActions = in.readLong(); - mErrorMessage = in.readString(); + mErrorMessage = in.readCharSequence(); } @@ -252,20 +252,20 @@ public final class PlaybackState implements Parcelable { dest.writeLong(mUpdateTime); dest.writeLong(mBufferPosition); dest.writeLong(mActions); - dest.writeString(mErrorMessage); + dest.writeCharSequence(mErrorMessage); } /** * Get the current state of playback. One of the following: *