Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7027e801 authored by Jaewan Kim's avatar Jaewan Kim
Browse files

MediaSession2: Last changes before API unhide

This CL includes
- Rename SessionToken to SessionToken2
- Add repeat/shuffle mode support in PlaylistParam
- Add Executor params in session builder
- Add more APIs for MediaPlayerBase

Test: Run all MediaComponents tests once
Change-Id: I7b74897c4bec377107eb040f950679d59e61f2bf
parent bbcbbe4f
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -21,7 +21,7 @@ import android.media.IMediaSession2;
import android.media.MediaBrowser2;
import android.media.MediaBrowser2.BrowserCallback;
import android.media.MediaSession2.CommandButton;
import android.media.SessionToken;
import android.media.SessionToken2;
import android.media.update.MediaBrowser2Provider;
import android.os.Bundle;
import android.os.RemoteException;
@@ -37,7 +37,7 @@ public class MediaBrowser2Impl extends MediaController2Impl implements MediaBrow
    private final MediaBrowser2 mInstance;
    private final MediaBrowser2.BrowserCallback mCallback;

    public MediaBrowser2Impl(MediaBrowser2 instance, Context context, SessionToken token,
    public MediaBrowser2Impl(MediaBrowser2 instance, Context context, SessionToken2 token,
            BrowserCallback callback, Executor executor) {
        super(instance, context, token, callback, executor);
        mInstance = instance;
+7 −9
Original line number Diff line number Diff line
@@ -31,17 +31,15 @@ import android.media.MediaSession2.CommandButton;
import android.media.MediaSession2.CommandGroup;
import android.media.MediaController2;
import android.media.MediaController2.ControllerCallback;
import android.media.MediaPlayerBase;
import android.media.MediaSession2.PlaylistParam;
import android.media.MediaSessionService2;
import android.media.PlaybackState2;
import android.media.Rating2;
import android.media.SessionToken;
import android.media.SessionToken2;
import android.media.session.PlaybackState;
import android.media.update.MediaController2Provider;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ResultReceiver;
@@ -70,7 +68,7 @@ public class MediaController2Impl implements MediaController2Provider {

    private final Context mContext;
    private final MediaSession2CallbackStub mSessionCallbackStub;
    private final SessionToken mToken;
    private final SessionToken2 mToken;
    private final ControllerCallback mCallback;
    private final Executor mCallbackExecutor;
    private final IBinder.DeathRecipient mDeathRecipient;
@@ -92,7 +90,7 @@ public class MediaController2Impl implements MediaController2Provider {

    // TODO(jaewan): Require session activeness changed listener, because controller can be
    //               available when the session's player is null.
    public MediaController2Impl(MediaController2 instance, Context context, SessionToken token,
    public MediaController2Impl(MediaController2 instance, Context context, SessionToken2 token,
            ControllerCallback callback, Executor executor) {
        mInstance = instance;

@@ -213,7 +211,7 @@ public class MediaController2Impl implements MediaController2Provider {
    }

    @Override
    public SessionToken getSessionToken_impl() {
    public SessionToken2 getSessionToken_impl() {
        return mToken;
    }

@@ -405,7 +403,7 @@ public class MediaController2Impl implements MediaController2Provider {
        }
    }

    private void pushPlaybackStateChanges(final PlaybackState state) {
    private void pushPlaybackStateChanges(final PlaybackState2 state) {
        synchronized (mLock) {
            for (int i = 0; i < mPlaybackListeners.size(); i++) {
                mPlaybackListeners.get(i).postPlaybackChange(state);
@@ -500,9 +498,9 @@ public class MediaController2Impl implements MediaController2Provider {
        }

        @Override
        public void onPlaybackStateChanged(PlaybackState state) throws RuntimeException {
        public void onPlaybackStateChanged(Bundle state) throws RuntimeException {
            final MediaController2Impl controller = getController();
            controller.pushPlaybackStateChanges(state);
            controller.pushPlaybackStateChanges(PlaybackState2.fromBundle(state));
        }

        @Override
+5 −3
Original line number Diff line number Diff line
@@ -31,6 +31,8 @@ import android.media.VolumeProvider;
import android.media.update.MediaLibraryService2Provider;
import android.os.Bundle;

import java.util.concurrent.Executor;

public class MediaLibraryService2Impl extends MediaSessionService2Impl implements
        MediaLibraryService2Provider {
    private final MediaSessionService2 mInstance;
@@ -66,11 +68,11 @@ public class MediaLibraryService2Impl extends MediaSessionService2Impl implement
        private final MediaLibrarySessionCallback mCallback;

        public MediaLibrarySessionImpl(MediaLibrarySession instance, Context context,
                MediaPlayerBase player, String id,
                MediaPlayerBase player, String id, Executor callbackExecutor,
                MediaLibrarySessionCallback callback, VolumeProvider volumeProvider, int ratingType,
                PendingIntent sessionActivity) {
            super(instance, context, player, id, callback, volumeProvider, ratingType,
                    sessionActivity);
            super(instance, context, player, id, callbackExecutor, callback, volumeProvider,
                    ratingType, sessionActivity);
            mInstance = instance;
            mCallback = callback;
        }
+19 −13
Original line number Diff line number Diff line
@@ -33,7 +33,8 @@ import android.media.MediaSession2.CommandGroup;
import android.media.MediaSession2.ControllerInfo;
import android.media.MediaSession2.PlaylistParam;
import android.media.MediaSession2.SessionCallback;
import android.media.SessionToken;
import android.media.PlaybackState2;
import android.media.SessionToken2;
import android.media.VolumeProvider;
import android.media.session.MediaSessionManager;
import android.media.session.PlaybackState;
@@ -47,6 +48,7 @@ import android.util.Log;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;

public class MediaSession2Impl implements MediaSession2Provider {
    private static final String TAG = "MediaSession2";
@@ -57,8 +59,9 @@ public class MediaSession2Impl implements MediaSession2Provider {
    private final Context mContext;
    private final String mId;
    private final Handler mHandler;
    private final Executor mCallbackExecutor;
    private final MediaSession2Stub mSessionStub;
    private final SessionToken mSessionToken;
    private final SessionToken2 mSessionToken;

    private MediaPlayerBase mPlayer;

@@ -79,8 +82,8 @@ public class MediaSession2Impl implements MediaSession2Provider {
     * @param sessionActivity
     */
    public MediaSession2Impl(MediaSession2 instance, Context context, MediaPlayerBase player,
            String id, SessionCallback callback, VolumeProvider volumeProvider, int ratingType,
            PendingIntent sessionActivity) {
            String id, Executor callbackExecutor, SessionCallback callback,
            VolumeProvider volumeProvider, int ratingType, PendingIntent sessionActivity) {
        mInstance = instance;
        // TODO(jaewan): Keep other params.

@@ -89,6 +92,7 @@ public class MediaSession2Impl implements MediaSession2Provider {
        mContext = context;
        mId = id;
        mHandler = new Handler(Looper.myLooper());
        mCallbackExecutor = callbackExecutor;
        mSessionStub = new MediaSession2Stub(this, callback);
        // Ask server to create session token for following reasons.
        //   1. Make session ID unique per package.
@@ -128,13 +132,14 @@ public class MediaSession2Impl implements MediaSession2Provider {
            // Player didn't changed. No-op.
            return;
        }
        mHandler.removeCallbacksAndMessages(null);
        // TODO(jaewan): Find equivalent for the executor
        //mHandler.removeCallbacksAndMessages(null);
        if (mPlayer != null && mListener != null) {
            // This might not work for a poorly implemented player.
            mPlayer.removePlaybackListener(mListener);
        }
        mListener = new MyPlaybackListener(this, player);
        player.addPlaybackListener(mListener, mHandler);
        player.addPlaybackListener(mCallbackExecutor, mListener);
        notifyPlaybackStateChanged(player.getPlaybackState());
        mPlayer = player;
    }
@@ -159,7 +164,7 @@ public class MediaSession2Impl implements MediaSession2Provider {

    // TODO(jaewan): Change this to @NonNull
    @Override
    public SessionToken getToken_impl() {
    public SessionToken2 getToken_impl() {
        return mSessionToken;
    }

@@ -300,12 +305,14 @@ public class MediaSession2Impl implements MediaSession2Provider {
    //               1. Allow calls from random threads for all methods.
    //               2. Allow calls from random threads for all methods, except for the
    //                  {@link #setPlayer()}.
    // TODO(jaewan): Should we pend command instead of exception?
    private void ensureCallingThread() {
        // TODO(jaewan): Uncomment or remove
        /*
        if (mHandler.getLooper() != Looper.myLooper()) {
            throw new IllegalStateException("Run this on the given thread");
        }*/
    }
    }


    private void ensurePlayer() {
        // TODO(jaewan): Should we pend command instead? Follow the decision from MP2.
@@ -319,7 +326,7 @@ public class MediaSession2Impl implements MediaSession2Provider {
        return mHandler;
    }

    private void notifyPlaybackStateChanged(PlaybackState state) {
    private void notifyPlaybackStateChanged(PlaybackState2 state) {
        // Notify to listeners added directly to this session
        for (int i = 0; i < mListeners.size(); i++) {
            mListeners.get(i).postPlaybackChange(state);
@@ -350,10 +357,9 @@ public class MediaSession2Impl implements MediaSession2Provider {
        }

        @Override
        public void onPlaybackChanged(PlaybackState state) {
        public void onPlaybackChanged(PlaybackState2 state) {
            MediaSession2Impl session = mSession.get();
            if (session == null || session.getHandler().getLooper() != Looper.myLooper()
                    || mPlayer != session.mInstance.getPlayer()) {
            if (mPlayer != session.mInstance.getPlayer()) {
                Log.w(TAG, "Unexpected playback state change notifications. Ignoring.",
                        new IllegalStateException());
                return;
+5 −4
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import android.media.MediaSession2.CommandButton;
import android.media.MediaSession2.CommandGroup;
import android.media.MediaSession2.ControllerInfo;
import android.media.MediaSession2.SessionCallback;
import android.media.PlaybackState2;
import android.media.session.PlaybackState;
import android.os.Binder;
import android.os.Bundle;
@@ -152,10 +153,10 @@ public class MediaSession2Stub extends IMediaSession2.Stub {

    @Deprecated
    @Override
    public PlaybackState getPlaybackState() throws RemoteException {
    public Bundle getPlaybackState() throws RemoteException {
        MediaSession2Impl session = getSession();
        // TODO(jaewan): Check if mPlayer.getPlaybackState() is safe here.
        return session.getInstance().getPlayer().getPlaybackState();
        return session.getInstance().getPlayer().getPlaybackState().toBundle();
    }

    @Deprecated
@@ -216,13 +217,13 @@ public class MediaSession2Stub extends IMediaSession2.Stub {
    }

    // Should be used without a lock to prevent potential deadlock.
    public void notifyPlaybackStateChangedNotLocked(PlaybackState state) {
    public void notifyPlaybackStateChangedNotLocked(PlaybackState2 state) {
        final List<ControllerInfo> list = getControllersWithFlag(CALLBACK_FLAG_PLAYBACK);
        for (int i = 0; i < list.size(); i++) {
            IMediaSession2Callback callbackBinder =
                    ControllerInfoImpl.from(list.get(i)).getControllerBinder();
            try {
                callbackBinder.onPlaybackStateChanged(state);
                callbackBinder.onPlaybackStateChanged(state.toBundle());
            } catch (RemoteException e) {
                Log.w(TAG, "Controller is gone", e);
                // TODO(jaewan): What to do when the controller is gone?
Loading