diff options
-rw-r--r-- | api/current.txt | 40 | ||||
-rw-r--r-- | media/java/android/media/RemoteControlClient.java | 3 | ||||
-rw-r--r-- | media/java/android/media/session/MediaController.java | 3 | ||||
-rw-r--r-- | media/java/android/media/session/MediaSession.java | 391 | ||||
-rw-r--r-- | media/java/android/media/session/MediaSessionLegacyHelper.java | 122 | ||||
-rw-r--r-- | media/java/android/media/session/PlaybackState.java | 27 | ||||
-rw-r--r-- | tests/OneMedia/src/com/android/onemedia/PlayerSession.java | 28 |
7 files changed, 280 insertions, 334 deletions
diff --git a/api/current.txt b/api/current.txt index 5710415..680d315 100644 --- a/api/current.txt +++ b/api/current.txt @@ -16717,18 +16717,14 @@ package android.media.session { public final class MediaSession { ctor public MediaSession(android.content.Context, java.lang.String); - method public void addCallback(android.media.session.MediaSession.Callback); - method public void addCallback(android.media.session.MediaSession.Callback, android.os.Handler); - method public void addTransportControlsCallback(android.media.session.MediaSession.TransportControlsCallback); - method public void addTransportControlsCallback(android.media.session.MediaSession.TransportControlsCallback, android.os.Handler); method public android.media.session.MediaController getController(); method public android.media.session.MediaSession.Token getSessionToken(); method public boolean isActive(); method public void release(); - method public void removeCallback(android.media.session.MediaSession.Callback); - method public void removeTransportControlsCallback(android.media.session.MediaSession.TransportControlsCallback); method public void sendSessionEvent(java.lang.String, android.os.Bundle); method public void setActive(boolean); + method public void setCallback(android.media.session.MediaSession.Callback); + method public void setCallback(android.media.session.MediaSession.Callback, android.os.Handler); method public void setExtras(android.os.Bundle); method public void setFlags(int); method public void setLaunchActivity(android.app.PendingIntent); @@ -16749,7 +16745,20 @@ package android.media.session { public static abstract class MediaSession.Callback { ctor public MediaSession.Callback(); method public void onCommand(java.lang.String, android.os.Bundle, android.os.ResultReceiver); - method public void onMediaButtonEvent(android.content.Intent); + method public void onCustomAction(java.lang.String, android.os.Bundle); + method public void onFastForward(); + method public boolean onMediaButtonEvent(android.content.Intent); + method public void onPause(); + method public void onPlay(); + method public void onPlayFromSearch(java.lang.String, android.os.Bundle); + method public void onPlayUri(android.net.Uri, android.os.Bundle); + method public void onRewind(); + method public void onSeekTo(long); + method public void onSetRating(android.media.Rating); + method public void onSkipToNext(); + method public void onSkipToPrevious(); + method public void onSkipToTrack(long); + method public void onStop(); } public static final class MediaSession.Token implements android.os.Parcelable { @@ -16775,23 +16784,6 @@ package android.media.session { method public android.media.session.MediaSession.Track.Builder setExtras(android.os.Bundle); } - public static abstract class MediaSession.TransportControlsCallback { - ctor public MediaSession.TransportControlsCallback(); - method public void onCustomAction(java.lang.String, android.os.Bundle); - method public void onFastForward(); - method public void onPause(); - method public void onPlay(); - method public void onPlayFromSearch(java.lang.String, android.os.Bundle); - method public void onPlayUri(android.net.Uri, android.os.Bundle); - method public void onRewind(); - method public void onSeekTo(long); - method public void onSetRating(android.media.Rating); - method public void onSkipToNext(); - method public void onSkipToPrevious(); - method public void onSkipToTrack(long); - method public void onStop(); - } - public final class MediaSessionManager { method public void addActiveSessionsListener(android.media.session.MediaSessionManager.SessionListener, android.content.ComponentName); method public java.util.List<android.media.session.MediaController> getActiveSessions(android.content.ComponentName); diff --git a/media/java/android/media/RemoteControlClient.java b/media/java/android/media/RemoteControlClient.java index 96c66c5..2a0fd83 100644 --- a/media/java/android/media/RemoteControlClient.java +++ b/media/java/android/media/RemoteControlClient.java @@ -970,8 +970,7 @@ import java.lang.IllegalArgumentException; public final static int RCSE_ID_UNREGISTERED = -1; // USE_SESSIONS - private MediaSession.TransportControlsCallback mTransportListener - = new MediaSession.TransportControlsCallback() { + private MediaSession.Callback mTransportListener = new MediaSession.Callback() { @Override public void onSeekTo(long pos) { diff --git a/media/java/android/media/session/MediaController.java b/media/java/android/media/session/MediaController.java index e3c198e..f6e189a 100644 --- a/media/java/android/media/session/MediaController.java +++ b/media/java/android/media/session/MediaController.java @@ -179,7 +179,8 @@ public final class MediaController { } /** - * Get the current play queue for this session. + * Get the current play queue for this session if one is set. If you only + * care about the current item {@link #getMetadata()} should be used. * * @return The current play queue or null. */ diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java index cf8e3dd..cf73c2a 100644 --- a/media/java/android/media/session/MediaSession.java +++ b/media/java/android/media/session/MediaSession.java @@ -21,12 +21,10 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.app.Activity; import android.app.PendingIntent; -import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.ParceledListSlice; import android.media.AudioAttributes; -import android.media.AudioManager; import android.media.MediaMetadata; import android.media.Rating; import android.media.VolumeProvider; @@ -43,11 +41,11 @@ import android.os.ResultReceiver; import android.os.UserHandle; import android.text.TextUtils; import android.util.Log; +import android.view.KeyEvent; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.ref.WeakReference; -import java.util.ArrayList; import java.util.List; /** @@ -64,10 +62,8 @@ import java.util.List; * create a {@link MediaController} to interact with the session. * <p> * To receive commands, media keys, and other events a {@link Callback} must be - * set with {@link #addCallback(Callback)} and {@link #setActive(boolean) - * setActive(true)} must be called. To receive transport control commands a - * {@link TransportControlsCallback} must be set with - * {@link #addTransportControlsCallback}. + * set with {@link #setCallback(Callback)} and {@link #setActive(boolean) + * setActive(true)} must be called. * <p> * When an app is finished performing playback it must call {@link #release()} * to clean up the session and notify any controllers. @@ -85,8 +81,7 @@ public final class MediaSession { /** * Set this flag on the session to indicate that it handles transport - * control commands through a {@link TransportControlsCallback}. - * The callback can be retrieved by calling {@link #addTransportControlsCallback}. + * control commands through its {@link Callback}. */ public static final int FLAG_HANDLES_TRANSPORT_CONTROLS = 1 << 1; @@ -124,12 +119,9 @@ public final class MediaSession { private final ISession mBinder; private final CallbackStub mCbStub; - private final ArrayList<CallbackMessageHandler> mCallbacks - = new ArrayList<CallbackMessageHandler>(); - private final ArrayList<TransportMessageHandler> mTransportCallbacks - = new ArrayList<TransportMessageHandler>(); - + private CallbackMessageHandler mCallback; private VolumeProvider mVolumeProvider; + private PlaybackState mPlaybackState; private boolean mActive = false; @@ -177,30 +169,35 @@ public final class MediaSession { } /** - * 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. + * Set the callback to receive updates for the MediaSession. This includes + * media button events and transport controls. The caller's thread will be + * used to post updates. + * <p> + * Set the callback to null to stop receiving updates. * * @param callback The callback object */ - public void addCallback(@NonNull Callback callback) { - addCallback(callback, null); + public void setCallback(@Nullable Callback callback) { + setCallback(callback, null); } /** - * Add a callback to receive updates for the MediaSession. This includes - * media button and volume events. + * Set the callback to receive updates for the MediaSession. This includes + * media button events and transport controls. + * <p> + * Set the callback to null to stop receiving updates. * * @param callback The callback to receive updates on. * @param handler The handler that events should be posted on. */ - public void addCallback(@NonNull Callback callback, @Nullable Handler handler) { + public void setCallback(@Nullable Callback callback, @Nullable Handler handler) { if (callback == null) { - throw new IllegalArgumentException("Callback cannot be null"); + mCallback = null; + return; } synchronized (mLock) { - if (getHandlerForCallbackLocked(callback) != null) { - Log.w(TAG, "Callback is already added, ignoring"); + if (mCallback != null && mCallback.mCallback == callback) { + Log.w(TAG, "Tried to set same callback, ignoring"); return; } if (handler == null) { @@ -208,18 +205,7 @@ public final class MediaSession { } CallbackMessageHandler msgHandler = new CallbackMessageHandler(handler.getLooper(), callback); - mCallbacks.add(msgHandler); - } - } - - /** - * Remove a callback. It will no longer receive updates. - * - * @param callback The callback to remove. - */ - public void removeCallback(@NonNull Callback callback) { - synchronized (mLock) { - removeCallbackLocked(callback); + mCallback = msgHandler; } } @@ -421,63 +407,12 @@ public final class MediaSession { } /** - * Add a callback to receive transport controls on, such as play, rewind, or - * fast forward. - * - * @param callback The callback object - */ - public void addTransportControlsCallback(@NonNull TransportControlsCallback callback) { - addTransportControlsCallback(callback, null); - } - - /** - * Add a callback to receive transport controls on, such as play, rewind, or - * fast forward. The updates will be posted to the specified handler. If no - * handler is provided they will be posted to the caller's thread. - * - * @param callback The callback to receive updates on - * @param handler The handler to post the updates on - */ - public void addTransportControlsCallback(@NonNull TransportControlsCallback callback, - @Nullable Handler handler) { - if (callback == null) { - throw new IllegalArgumentException("Callback cannot be null"); - } - synchronized (mLock) { - if (getTransportControlsHandlerForCallbackLocked(callback) != null) { - Log.w(TAG, "Callback is already added, ignoring"); - return; - } - if (handler == null) { - handler = new Handler(); - } - TransportMessageHandler msgHandler = new TransportMessageHandler(handler.getLooper(), - callback); - mTransportCallbacks.add(msgHandler); - } - } - - /** - * Stop receiving transport controls on the specified callback. If an update - * has already been posted you may still receive it after this call returns. - * - * @param callback The callback to stop receiving updates on - */ - public void removeTransportControlsCallback(@NonNull TransportControlsCallback callback) { - if (callback == null) { - throw new IllegalArgumentException("Callback cannot be null"); - } - synchronized (mLock) { - removeTransportControlsCallbackLocked(callback); - } - } - - /** * Update the current playback state. * * @param state The current state of playback */ public void setPlaybackState(@Nullable PlaybackState state) { + mPlaybackState = state; try { mBinder.setPlaybackState(state); } catch (RemoteException e) { @@ -566,138 +501,78 @@ public final class MediaSession { } private void dispatchPlay() { - postToTransportCallbacks(TransportMessageHandler.MSG_PLAY); + postToCallback(CallbackMessageHandler.MSG_PLAY); } private void dispatchPlayUri(Uri uri, Bundle extras) { - postToTransportCallbacks(TransportMessageHandler.MSG_PLAY_URI, uri, extras); + postToCallback(CallbackMessageHandler.MSG_PLAY_URI, uri, extras); } private void dispatchPlayFromSearch(String query, Bundle extras) { - postToTransportCallbacks(TransportMessageHandler.MSG_PLAY_SEARCH, query, extras); + postToCallback(CallbackMessageHandler.MSG_PLAY_SEARCH, query, extras); } private void dispatchSkipToTrack(long id) { - postToTransportCallbacks(TransportMessageHandler.MSG_SKIP_TO_TRACK, id); + postToCallback(CallbackMessageHandler.MSG_SKIP_TO_TRACK, id); } private void dispatchPause() { - postToTransportCallbacks(TransportMessageHandler.MSG_PAUSE); + postToCallback(CallbackMessageHandler.MSG_PAUSE); } private void dispatchStop() { - postToTransportCallbacks(TransportMessageHandler.MSG_STOP); + postToCallback(CallbackMessageHandler.MSG_STOP); } private void dispatchNext() { - postToTransportCallbacks(TransportMessageHandler.MSG_NEXT); + postToCallback(CallbackMessageHandler.MSG_NEXT); } private void dispatchPrevious() { - postToTransportCallbacks(TransportMessageHandler.MSG_PREVIOUS); + postToCallback(CallbackMessageHandler.MSG_PREVIOUS); } private void dispatchFastForward() { - postToTransportCallbacks(TransportMessageHandler.MSG_FAST_FORWARD); + postToCallback(CallbackMessageHandler.MSG_FAST_FORWARD); } private void dispatchRewind() { - postToTransportCallbacks(TransportMessageHandler.MSG_REWIND); + postToCallback(CallbackMessageHandler.MSG_REWIND); } private void dispatchSeekTo(long pos) { - postToTransportCallbacks(TransportMessageHandler.MSG_SEEK_TO, pos); + postToCallback(CallbackMessageHandler.MSG_SEEK_TO, pos); } private void dispatchRate(Rating rating) { - postToTransportCallbacks(TransportMessageHandler.MSG_RATE, rating); + postToCallback(CallbackMessageHandler.MSG_RATE, rating); } private void dispatchCustomAction(String action, Bundle args) { - postToTransportCallbacks(TransportMessageHandler.MSG_CUSTOM_ACTION, action, args); - } - - private TransportMessageHandler getTransportControlsHandlerForCallbackLocked( - TransportControlsCallback callback) { - for (int i = mTransportCallbacks.size() - 1; i >= 0; i--) { - TransportMessageHandler handler = mTransportCallbacks.get(i); - if (callback == handler.mCallback) { - return handler; - } - } - return null; - } - - private boolean removeTransportControlsCallbackLocked(TransportControlsCallback callback) { - for (int i = mTransportCallbacks.size() - 1; i >= 0; i--) { - if (callback == mTransportCallbacks.get(i).mCallback) { - mTransportCallbacks.remove(i); - return true; - } - } - return false; - } - - private void postToTransportCallbacks(int what, Object obj) { - synchronized (mLock) { - for (int i = mTransportCallbacks.size() - 1; i >= 0; i--) { - mTransportCallbacks.get(i).post(what, obj); - } - } - } - - private void postToTransportCallbacks(int what, Object obj, Bundle args) { - synchronized (mLock) { - for (int i = mTransportCallbacks.size() - 1; i >= 0; i--) { - mTransportCallbacks.get(i).post(what, obj, args); - } - } - } - - private void postToTransportCallbacks(int what) { - postToTransportCallbacks(what, null); + postToCallback(CallbackMessageHandler.MSG_CUSTOM_ACTION, action, args); } - private CallbackMessageHandler getHandlerForCallbackLocked(Callback cb) { - if (cb == null) { - throw new IllegalArgumentException("Callback cannot be null"); - } - for (int i = mCallbacks.size() - 1; i >= 0; i--) { - CallbackMessageHandler handler = mCallbacks.get(i); - if (cb == handler.mCallback) { - return handler; - } - } - return null; + private void dispatchMediaButton(Intent mediaButtonIntent) { + postToCallback(CallbackMessageHandler.MSG_MEDIA_BUTTON, mediaButtonIntent); } - private boolean removeCallbackLocked(Callback cb) { - if (cb == null) { - throw new IllegalArgumentException("Callback cannot be null"); - } - for (int i = mCallbacks.size() - 1; i >= 0; i--) { - CallbackMessageHandler handler = mCallbacks.get(i); - if (cb == handler.mCallback) { - mCallbacks.remove(i); - return true; - } - } - return false; + private void postToCallback(int what) { + postToCallback(what, null); } private void postCommand(String command, Bundle args, ResultReceiver resultCb) { Command cmd = new Command(command, args, resultCb); - synchronized (mLock) { - for (int i = mCallbacks.size() - 1; i >= 0; i--) { - mCallbacks.get(i).post(CallbackMessageHandler.MSG_COMMAND, cmd); - } - } + postToCallback(CallbackMessageHandler.MSG_COMMAND, cmd); + } + + private void postToCallback(int what, Object obj) { + postToCallback(what, obj, null); } - private void postMediaButton(Intent mediaButtonIntent) { + private void postToCallback(int what, Object obj, Bundle extras) { synchronized (mLock) { - for (int i = mCallbacks.size() - 1; i >= 0; i--) { - mCallbacks.get(i).post(CallbackMessageHandler.MSG_MEDIA_BUTTON, mediaButtonIntent); + if (mCallback != null) { + mCallback.post(what, obj, extras); } } } @@ -791,30 +666,16 @@ public final class MediaSession { } /** - * Receives generic commands or updates from controllers and the system. - * Callbacks may be registered using {@link #addCallback}. + * Receives media buttons, transport controls, and commands from controllers + * and the system. A callback may be set using {@link #setCallback}. */ public abstract static class Callback { + private MediaSession mSession; public Callback() { } /** - * Called when a media button is pressed and this session has the - * highest priority or a controller sends a media button event to the - * session. TODO determine if using Intents identical to the ones - * RemoteControlClient receives is useful - * <p> - * The intent will be of type {@link Intent#ACTION_MEDIA_BUTTON} with a - * KeyEvent in {@link Intent#EXTRA_KEY_EVENT} - * - * @param mediaButtonIntent an intent containing the KeyEvent as an - * extra - */ - public void onMediaButtonEvent(@NonNull Intent mediaButtonIntent) { - } - - /** * Called when a controller has sent a command to this session. * The owner of the session may handle custom commands but is not * required to. @@ -826,13 +687,81 @@ public final class MediaSession { public void onCommand(@NonNull String command, @Nullable Bundle args, @Nullable ResultReceiver cb) { } - } - /** - * Receives transport control commands. Callbacks may be registered using - * {@link #addTransportControlsCallback}. - */ - public static abstract class TransportControlsCallback { + /** + * Called when a media button is pressed and this session has the + * highest priority or a controller sends a media button event to the + * session. The default behavior will call the relevant method if the + * action for it was set. + * <p> + * The intent will be of type {@link Intent#ACTION_MEDIA_BUTTON} with a + * KeyEvent in {@link Intent#EXTRA_KEY_EVENT} + * + * @param mediaButtonIntent an intent containing the KeyEvent as an + * extra + */ + public boolean onMediaButtonEvent(@NonNull Intent mediaButtonIntent) { + if (mSession != null + && Intent.ACTION_MEDIA_BUTTON.equals(mediaButtonIntent.getAction())) { + KeyEvent ke = mediaButtonIntent.getParcelableExtra(Intent.EXTRA_KEY_EVENT); + if (ke != null && ke.getAction() == KeyEvent.ACTION_DOWN) { + PlaybackState state = mSession.mPlaybackState; + long validActions = state == null ? 0 : state.getActions(); + switch (ke.getKeyCode()) { + case KeyEvent.KEYCODE_MEDIA_PLAY: + if ((validActions & PlaybackState.ACTION_PLAY) != 0) { + onPlay(); + } + break; + case KeyEvent.KEYCODE_MEDIA_PAUSE: + if ((validActions & PlaybackState.ACTION_PAUSE) != 0) { + onPause(); + } + break; + case KeyEvent.KEYCODE_MEDIA_NEXT: + if ((validActions & PlaybackState.ACTION_SKIP_TO_NEXT) != 0) { + onSkipToNext(); + } + break; + case KeyEvent.KEYCODE_MEDIA_PREVIOUS: + if ((validActions & PlaybackState.ACTION_SKIP_TO_PREVIOUS) != 0) { + onSkipToPrevious(); + } + break; + case KeyEvent.KEYCODE_MEDIA_STOP: + if ((validActions & PlaybackState.ACTION_STOP) != 0) { + onStop(); + } + break; + case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD: + if ((validActions & PlaybackState.ACTION_FAST_FORWARD) != 0) { + onFastForward(); + } + break; + case KeyEvent.KEYCODE_MEDIA_REWIND: + if ((validActions & PlaybackState.ACTION_REWIND) != 0) { + onRewind(); + } + break; + case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE: + case KeyEvent.KEYCODE_HEADSETHOOK: + boolean isPlaying = state == null ? false + : state.getState() == PlaybackState.STATE_PLAYING; + boolean canPlay = (validActions & (PlaybackState.ACTION_PLAY_PAUSE + | PlaybackState.ACTION_PLAY)) != 0; + boolean canPause = (validActions & (PlaybackState.ACTION_PLAY_PAUSE + | PlaybackState.ACTION_PAUSE)) != 0; + if (isPlaying && canPause) { + onPause(); + } else if (!isPlaying && canPlay) { + onPlay(); + } + break; + } + } + } + return false; + } /** * Override to handle requests to begin playback. @@ -920,6 +849,10 @@ public final class MediaSession { */ public void onCustomAction(@NonNull String action, @Nullable Bundle extras) { } + + private void setSession(MediaSession session) { + mSession = session; + } } /** @@ -946,7 +879,7 @@ public final class MediaSession { MediaSession session = mMediaSession.get(); try { if (session != null) { - session.postMediaButton(mediaButtonIntent); + session.dispatchMediaButton(mediaButtonIntent); } } finally { if (cb != null) { @@ -1232,44 +1165,6 @@ public final class MediaSession { } } - private class CallbackMessageHandler extends Handler { - private static final int MSG_MEDIA_BUTTON = 1; - private static final int MSG_COMMAND = 2; - - private MediaSession.Callback mCallback; - - public CallbackMessageHandler(Looper looper, MediaSession.Callback callback) { - super(looper, null, true); - mCallback = callback; - } - - @Override - public void handleMessage(Message msg) { - synchronized (mLock) { - if (mCallback == null) { - return; - } - switch (msg.what) { - case MSG_MEDIA_BUTTON: - mCallback.onMediaButtonEvent((Intent) msg.obj); - break; - case MSG_COMMAND: - Command cmd = (Command) msg.obj; - mCallback.onCommand(cmd.command, cmd.extras, cmd.stub); - break; - } - } - } - - public void post(int what, Object obj) { - obtainMessage(what, obj).sendToTarget(); - } - - public void post(int what, Object obj, int arg1) { - obtainMessage(what, arg1, 0, obj).sendToTarget(); - } - } - private static final class Command { public final String command; public final Bundle extras; @@ -1282,7 +1177,8 @@ public final class MediaSession { } } - private class TransportMessageHandler extends Handler { + private class CallbackMessageHandler extends Handler { + private static final int MSG_PLAY = 1; private static final int MSG_PLAY_URI = 2; private static final int MSG_PLAY_SEARCH = 3; @@ -1296,12 +1192,14 @@ public final class MediaSession { private static final int MSG_SEEK_TO = 11; private static final int MSG_RATE = 12; private static final int MSG_CUSTOM_ACTION = 13; + private static final int MSG_MEDIA_BUTTON = 14; + private static final int MSG_COMMAND = 15; - private TransportControlsCallback mCallback; + private MediaSession.Callback mCallback; - public TransportMessageHandler(Looper looper, TransportControlsCallback cb) { - super(looper); - mCallback = cb; + public CallbackMessageHandler(Looper looper, MediaSession.Callback callback) { + super(looper, null, true); + mCallback = callback; } public void post(int what, Object obj, Bundle bundle) { @@ -1318,6 +1216,10 @@ public final class MediaSession { post(what, null); } + public void post(int what, Object obj, int arg1) { + obtainMessage(what, arg1, 0, obj).sendToTarget(); + } + @Override public void handleMessage(Message msg) { switch (msg.what) { @@ -1359,6 +1261,13 @@ public final class MediaSession { case MSG_CUSTOM_ACTION: mCallback.onCustomAction((String) msg.obj, msg.getData()); break; + case MSG_MEDIA_BUTTON: + mCallback.onMediaButtonEvent((Intent) msg.obj); + break; + case MSG_COMMAND: + Command cmd = (Command) msg.obj; + mCallback.onCommand(cmd.command, cmd.extras, cmd.stub); + break; } } } diff --git a/media/java/android/media/session/MediaSessionLegacyHelper.java b/media/java/android/media/session/MediaSessionLegacyHelper.java index f075ded..a182982 100644 --- a/media/java/android/media/session/MediaSessionLegacyHelper.java +++ b/media/java/android/media/session/MediaSessionLegacyHelper.java @@ -29,6 +29,9 @@ import android.media.AudioManager; import android.media.MediaMetadata; import android.media.MediaMetadataEditor; import android.media.MediaMetadataRetriever; +import android.media.Rating; +import android.media.RemoteControlClient; +import android.media.RemoteControlClient.MetadataEditor; import android.os.Bundle; import android.os.Handler; import android.os.Looper; @@ -229,8 +232,7 @@ public class MediaSessionLegacyHelper { } } - public void addRccListener(PendingIntent pi, - MediaSession.TransportControlsCallback listener) { + public void addRccListener(PendingIntent pi, MediaSession.Callback listener) { if (pi == null) { Log.w(TAG, "Pending intent was null, can't add rcc listener."); return; @@ -247,10 +249,7 @@ public class MediaSessionLegacyHelper { // This is already the registered listener, ignore return; } - // Otherwise it changed so we need to switch to the new one - holder.mSession.removeTransportControlsCallback(holder.mRccListener); } - holder.mSession.addTransportControlsCallback(listener, mHandler); holder.mRccListener = listener; holder.mFlags |= MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS; holder.mSession.setFlags(holder.mFlags); @@ -266,7 +265,6 @@ public class MediaSessionLegacyHelper { } SessionHolder holder = getHolder(pi, false); if (holder != null && holder.mRccListener != null) { - holder.mSession.removeTransportControlsCallback(holder.mRccListener); holder.mRccListener = null; holder.mFlags &= ~MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS; holder.mSession.setFlags(holder.mFlags); @@ -288,8 +286,7 @@ public class MediaSessionLegacyHelper { return; } if (holder.mMediaButtonListener != null) { - // Already have this listener registered, but update it anyway as - // the extras may have changed. + // Already have this listener registered if (DEBUG) { Log.d(TAG, "addMediaButtonListener already added " + pi); } @@ -300,11 +297,8 @@ public class MediaSessionLegacyHelper { // set this flag holder.mFlags |= MediaSession.FLAG_HANDLES_MEDIA_BUTTONS; holder.mSession.setFlags(holder.mFlags); - holder.mSession.addTransportControlsCallback(holder.mMediaButtonListener, mHandler); - - holder.mMediaButtonReceiver = new MediaButtonReceiver(pi, context); - holder.mSession.addCallback(holder.mMediaButtonReceiver, mHandler); holder.mSession.setMediaButtonReceiver(pi); + holder.update(); if (DEBUG) { Log.d(TAG, "addMediaButtonListener added " + pi); } @@ -316,13 +310,10 @@ public class MediaSessionLegacyHelper { } SessionHolder holder = getHolder(pi, false); if (holder != null && holder.mMediaButtonListener != null) { - holder.mSession.removeTransportControlsCallback(holder.mMediaButtonListener); holder.mFlags &= ~MediaSession.FLAG_HANDLES_MEDIA_BUTTONS; holder.mSession.setFlags(holder.mFlags); holder.mMediaButtonListener = null; - holder.mSession.removeCallback(holder.mMediaButtonReceiver); - holder.mMediaButtonReceiver = null; holder.update(); if (DEBUG) { Log.d(TAG, "removeMediaButtonListener removed " + pi); @@ -387,28 +378,19 @@ public class MediaSessionLegacyHelper { } } - private static final class MediaButtonReceiver extends MediaSession.Callback { + private static final class MediaButtonListener extends MediaSession.Callback { private final PendingIntent mPendingIntent; private final Context mContext; - public MediaButtonReceiver(PendingIntent pi, Context context) { + public MediaButtonListener(PendingIntent pi, Context context) { mPendingIntent = pi; mContext = context; } @Override - public void onMediaButtonEvent(Intent mediaButtonIntent) { + public boolean onMediaButtonEvent(Intent mediaButtonIntent) { MediaSessionLegacyHelper.sendKeyEvent(mPendingIntent, mContext, mediaButtonIntent); - } - } - - private static final class MediaButtonListener extends MediaSession.TransportControlsCallback { - private final PendingIntent mPendingIntent; - private final Context mContext; - - public MediaButtonListener(PendingIntent pi, Context context) { - mPendingIntent = pi; - mContext = context; + return true; } @Override @@ -468,10 +450,11 @@ public class MediaSessionLegacyHelper { public final MediaSession mSession; public final PendingIntent mPi; public MediaButtonListener mMediaButtonListener; - public MediaButtonReceiver mMediaButtonReceiver; - public MediaSession.TransportControlsCallback mRccListener; + public MediaSession.Callback mRccListener; public int mFlags; + public SessionCallback mCb; + public SessionHolder(MediaSession session, PendingIntent pi) { mSession = session; mPi = pi; @@ -479,8 +462,87 @@ public class MediaSessionLegacyHelper { public void update() { if (mMediaButtonListener == null && mRccListener == null) { + mSession.setCallback(null); mSession.release(); + mCb = null; mSessions.remove(mPi); + } else if (mCb == null) { + mCb = new SessionCallback(); + mSession.setCallback(mCb); + } + } + + private class SessionCallback extends MediaSession.Callback { + + @Override + public boolean onMediaButtonEvent(Intent mediaButtonIntent) { + if (mMediaButtonListener != null) { + mMediaButtonListener.onMediaButtonEvent(mediaButtonIntent); + } + return true; + } + + @Override + public void onPlay() { + if (mMediaButtonListener != null) { + mMediaButtonListener.onPlay(); + } + } + + @Override + public void onPause() { + if (mMediaButtonListener != null) { + mMediaButtonListener.onPause(); + } + } + + @Override + public void onSkipToNext() { + if (mMediaButtonListener != null) { + mMediaButtonListener.onSkipToNext(); + } + } + + @Override + public void onSkipToPrevious() { + if (mMediaButtonListener != null) { + mMediaButtonListener.onSkipToPrevious(); + } + } + + @Override + public void onFastForward() { + if (mMediaButtonListener != null) { + mMediaButtonListener.onFastForward(); + } + } + + @Override + public void onRewind() { + if (mMediaButtonListener != null) { + mMediaButtonListener.onRewind(); + } + } + + @Override + public void onStop() { + if (mMediaButtonListener != null) { + mMediaButtonListener.onStop(); + } + } + + @Override + public void onSeekTo(long pos) { + if (mRccListener != null) { + mRccListener.onSeekTo(pos); + } + } + + @Override + public void onSetRating(Rating rating) { + if (mRccListener != null) { + mRccListener.onSetRating(rating); + } } } } diff --git a/media/java/android/media/session/PlaybackState.java b/media/java/android/media/session/PlaybackState.java index 65bd677..2ad8eae 100644 --- a/media/java/android/media/session/PlaybackState.java +++ b/media/java/android/media/session/PlaybackState.java @@ -845,20 +845,23 @@ public final class PlaybackState implements Parcelable { } /** - * Add a custom action to the playback state. Actions can be used to expose additional - * functionality to {@link MediaController MediaControllers} beyond what is offered by the - * standard transport controls. + * Add a custom action to the playback state. Actions can be used to + * expose additional functionality to {@link MediaController + * MediaControllers} beyond what is offered by the standard transport + * controls. * <p> - * e.g. start a radio station based on the current item or skip ahead by 30 seconds. + * e.g. start a radio station based on the current item or skip ahead by + * 30 seconds. * - * @param action An identifier for this action. It will be sent back to the - * {@link MediaSession} through - * {@link - * MediaSession.TransportControlsCallback#onCustomAction(String, Bundle)}. - * @param name The display name for the action. If text is shown with the action or used - * for accessibility, this is what should be used. - * @param icon The resource action of the icon that should be displayed for the action. The - * resource should be in the package of the {@link MediaSession}. + * @param action An identifier for this action. It can be sent back to + * the {@link MediaSession} through + * {@link MediaController.TransportControls#sendCustomAction(String, Bundle)}. + * @param name The display name for the action. If text is shown with + * the action or used for accessibility, this is what should + * be used. + * @param icon The resource action of the icon that should be displayed + * for the action. The resource should be in the package of + * the {@link MediaSession}. * @return this */ public Builder addCustomAction(String action, String name, int icon) { diff --git a/tests/OneMedia/src/com/android/onemedia/PlayerSession.java b/tests/OneMedia/src/com/android/onemedia/PlayerSession.java index feecfde..890d68d 100644 --- a/tests/OneMedia/src/com/android/onemedia/PlayerSession.java +++ b/tests/OneMedia/src/com/android/onemedia/PlayerSession.java @@ -86,10 +86,10 @@ public class PlayerSession { mRouter.setRoutingCallback(new RoutingCallback(), null); mSession = new MediaSession(mContext, "OneMedia"); - mSession.addCallback(mCallback); - mSession.addTransportControlsCallback(new TransportCallback()); + mSession.setCallback(mCallback); mSession.setPlaybackState(mPlaybackState); - mSession.setFlags(MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS); + mSession.setFlags(MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS + | MediaSession.FLAG_HANDLES_MEDIA_BUTTONS); mSession.setMediaRouter(mRouter); mSession.setActive(true); } @@ -230,26 +230,6 @@ public class PlayerSession { private class SessionCb extends MediaSession.Callback { @Override - public void onMediaButtonEvent(Intent mediaRequestIntent) { - if (Intent.ACTION_MEDIA_BUTTON.equals(mediaRequestIntent.getAction())) { - KeyEvent event = (KeyEvent) mediaRequestIntent - .getParcelableExtra(Intent.EXTRA_KEY_EVENT); - switch (event.getKeyCode()) { - case KeyEvent.KEYCODE_MEDIA_PLAY: - Log.d(TAG, "play button received"); - mRenderer.onPlay(); - break; - case KeyEvent.KEYCODE_MEDIA_PAUSE: - Log.d(TAG, "pause button received"); - mRenderer.onPause(); - break; - } - } - } - } - - private class TransportCallback extends MediaSession.TransportControlsCallback { - @Override public void onPlay() { mRenderer.onPlay(); } @@ -315,7 +295,7 @@ public class PlayerSession { updateState(PlaybackState.STATE_NONE); break; } - } + } } } } |