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

Commit 44648206 authored by Jaewan Kim's avatar Jaewan Kim
Browse files

MediaSession2: Implement PlaylistParams replacements

This includes following changes
  - Remove PlaylistParams
  - Implement PlaylistParams replacements. Here's the list.
    - get/setShuffleMode()
    - get/setRepeatMode()
    - Note: Playlist metadata APIs are already submitted (b/74174649)

Bug: 74116823, Bug: 74118768
Test: Run CTS with MediaComponents/runcts.sh
Change-Id: I712a2c3fe959b8496f3d80310579af872419f486
parent 00f7a005
Loading
Loading
Loading
Loading
+3 −2
Original line number Original line Diff line number Diff line
@@ -37,12 +37,13 @@ oneway interface IMediaController2 {
    void onBufferedPositionChanged(long bufferedPositionMs);
    void onBufferedPositionChanged(long bufferedPositionMs);
    void onPlaylistChanged(in List<Bundle> playlist, in Bundle metadata);
    void onPlaylistChanged(in List<Bundle> playlist, in Bundle metadata);
    void onPlaylistMetadataChanged(in Bundle metadata);
    void onPlaylistMetadataChanged(in Bundle metadata);
    void onPlaylistParamsChanged(in Bundle params);
    void onPlaybackInfoChanged(in Bundle playbackInfo);
    void onPlaybackInfoChanged(in Bundle playbackInfo);
    void onRepeatModeChanged(int repeatMode);
    void onShuffleModeChanged(int shuffleMode);


    void onConnected(IMediaSession2 sessionBinder, in Bundle commandGroup,
    void onConnected(IMediaSession2 sessionBinder, in Bundle commandGroup,
            int playerState, long positionEventTimeMs, long positionMs, float playbackSpeed,
            int playerState, long positionEventTimeMs, long positionMs, float playbackSpeed,
            long bufferedPositionMs, in Bundle playbackInfo, in Bundle params,
            long bufferedPositionMs, in Bundle playbackInfo, int repeatMode, int shuffleMode,
            in List<Bundle> playlist, in PendingIntent sessionActivity);
            in List<Bundle> playlist, in PendingIntent sessionActivity);
    void onDisconnected();
    void onDisconnected();


+2 −0
Original line number Original line Diff line number Diff line
@@ -67,6 +67,8 @@ oneway interface IMediaSession2 {
    void skipToPlaylistItem(IMediaController2 caller, in Bundle mediaItem);
    void skipToPlaylistItem(IMediaController2 caller, in Bundle mediaItem);
    void skipToPreviousItem(IMediaController2 caller);
    void skipToPreviousItem(IMediaController2 caller);
    void skipToNextItem(IMediaController2 caller);
    void skipToNextItem(IMediaController2 caller);
    void setRepeatMode(IMediaController2 caller, int repeatMode);
    void setShuffleMode(IMediaController2 caller, int shuffleMode);


    //////////////////////////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////////////////////
    // library service specific
    // library service specific
+72 −31
Original line number Original line Diff line number Diff line
@@ -22,6 +22,8 @@ import static android.media.MediaSession2.COMMAND_CODE_PLAYLIST_REMOVE_ITEM;
import static android.media.MediaSession2.COMMAND_CODE_PLAYLIST_REPLACE_ITEM;
import static android.media.MediaSession2.COMMAND_CODE_PLAYLIST_REPLACE_ITEM;
import static android.media.MediaSession2.COMMAND_CODE_PLAYLIST_SET_LIST;
import static android.media.MediaSession2.COMMAND_CODE_PLAYLIST_SET_LIST;
import static android.media.MediaSession2.COMMAND_CODE_PLAYLIST_SET_LIST_METADATA;
import static android.media.MediaSession2.COMMAND_CODE_PLAYLIST_SET_LIST_METADATA;
import static android.media.MediaSession2.COMMAND_CODE_PLAYLIST_SET_REPEAT_MODE;
import static android.media.MediaSession2.COMMAND_CODE_PLAYLIST_SET_SHUFFLE_MODE;
import static android.media.MediaSession2.COMMAND_CODE_PLAY_FROM_MEDIA_ID;
import static android.media.MediaSession2.COMMAND_CODE_PLAY_FROM_MEDIA_ID;
import static android.media.MediaSession2.COMMAND_CODE_PLAY_FROM_SEARCH;
import static android.media.MediaSession2.COMMAND_CODE_PLAY_FROM_SEARCH;
import static android.media.MediaSession2.COMMAND_CODE_PLAY_FROM_URI;
import static android.media.MediaSession2.COMMAND_CODE_PLAY_FROM_URI;
@@ -40,11 +42,12 @@ import android.media.MediaController2.ControllerCallback;
import android.media.MediaController2.PlaybackInfo;
import android.media.MediaController2.PlaybackInfo;
import android.media.MediaItem2;
import android.media.MediaItem2;
import android.media.MediaMetadata2;
import android.media.MediaMetadata2;
import android.media.MediaPlaylistAgent.RepeatMode;
import android.media.MediaPlaylistAgent.ShuffleMode;
import android.media.MediaSession2;
import android.media.MediaSession2;
import android.media.MediaSession2.Command;
import android.media.MediaSession2.Command;
import android.media.MediaSession2.CommandButton;
import android.media.MediaSession2.CommandButton;
import android.media.MediaSession2.CommandGroup;
import android.media.MediaSession2.CommandGroup;
import android.media.MediaSession2.PlaylistParams;
import android.media.MediaSessionService2;
import android.media.MediaSessionService2;
import android.media.Rating2;
import android.media.Rating2;
import android.media.SessionToken2;
import android.media.SessionToken2;
@@ -87,7 +90,9 @@ public class MediaController2Impl implements MediaController2Provider {
    @GuardedBy("mLock")
    @GuardedBy("mLock")
    private MediaMetadata2 mPlaylistMetadata;
    private MediaMetadata2 mPlaylistMetadata;
    @GuardedBy("mLock")
    @GuardedBy("mLock")
    private PlaylistParams mPlaylistParams;
    private @RepeatMode int mRepeatMode;
    @GuardedBy("mLock")
    private @ShuffleMode int mShuffleMode;
    @GuardedBy("mLock")
    @GuardedBy("mLock")
    private int mPlayerState;
    private int mPlayerState;
    @GuardedBy("mLock")
    @GuardedBy("mLock")
@@ -706,30 +711,49 @@ public class MediaController2Impl implements MediaController2Provider {
    }
    }


    @Override
    @Override
    public PlaylistParams getPlaylistParams_impl() {
    public int getShuffleMode_impl() {
        synchronized (mLock) {
        return mShuffleMode;
            return mPlaylistParams;
    }

    @Override
    public void setShuffleMode_impl(int shuffleMode) {
        final IMediaSession2 binder = getSessionBinderIfAble(
                COMMAND_CODE_PLAYLIST_SET_SHUFFLE_MODE);
        if (binder != null) {
            try {
                binder.setShuffleMode(mControllerStub, shuffleMode);
            } catch (RemoteException e) {
                Log.w(TAG, "Cannot connect to the service or the session is gone", e);
            }
        } else {
            Log.w(TAG, "Session isn't active", new IllegalStateException());
        }
        }
    }
    }


    @Override
    @Override
    public PlaybackInfo getPlaybackInfo_impl() {
    public int getRepeatMode_impl() {
        synchronized (mLock) {
        return mRepeatMode;
            return mPlaybackInfo;
    }

    @Override
    public void setRepeatMode_impl(int repeatMode) {
        final IMediaSession2 binder = getSessionBinderIfAble(COMMAND_CODE_PLAYLIST_SET_REPEAT_MODE);
        if (binder != null) {
            try {
                binder.setRepeatMode(mControllerStub, repeatMode);
            } catch (RemoteException e) {
                Log.w(TAG, "Cannot connect to the service or the session is gone", e);
            }
        } else {
            Log.w(TAG, "Session isn't active", new IllegalStateException());
        }
        }
    }
    }


    // TODO(jaewan): Remove (b/74116823)
    @Override
    @Override
    public void setPlaylistParams_impl(PlaylistParams params) {
    public PlaybackInfo getPlaybackInfo_impl() {
        if (params == null) {
        synchronized (mLock) {
            throw new IllegalArgumentException("params shouldn't be null");
            return mPlaybackInfo;
        }
        }
        /*
        Bundle args = new Bundle();
        args.putBundle(MediaSession2Stub.ARGUMENT_KEY_PLAYLIST_PARAMS, params.toBundle());
        sendTransportControlCommand(MediaSession2.COMMAND_CODE_PLAYBACK_SET_PLAYLIST_PARAMS, args);
        */
    }
    }


    @Override
    @Override
@@ -817,33 +841,34 @@ public class MediaController2Impl implements MediaController2Provider {
        });
        });
    }
    }


    void pushPlaylistParamsChanges(final PlaylistParams params) {
    void pushPlaybackInfoChanges(final PlaybackInfo info) {
        synchronized (mLock) {
        synchronized (mLock) {
            mPlaylistParams = params;
            mPlaybackInfo = info;
        }
        }
        mCallbackExecutor.execute(() -> {
        mCallbackExecutor.execute(() -> {
            if (!mInstance.isConnected()) {
            if (!mInstance.isConnected()) {
                return;
                return;
            }
            }
            mCallback.onPlaylistParamsChanged(mInstance, params);
            mCallback.onPlaybackInfoChanged(mInstance, info);
        });
        });
    }
    }


    void pushPlaybackInfoChanges(final PlaybackInfo info) {
    void pushPlaylistChanges(final List<MediaItem2> playlist, final MediaMetadata2 metadata) {
        synchronized (mLock) {
        synchronized (mLock) {
            mPlaybackInfo = info;
            mPlaylist = playlist;
            mPlaylistMetadata = metadata;
        }
        }
        mCallbackExecutor.execute(() -> {
        mCallbackExecutor.execute(() -> {
            if (!mInstance.isConnected()) {
            if (!mInstance.isConnected()) {
                return;
                return;
            }
            }
            mCallback.onPlaybackInfoChanged(mInstance, info);
            // TODO(jaewan): Fix public API not to take playlistAgent.
            mCallback.onPlaylistChanged(mInstance, null, playlist, metadata);
        });
        });
    }
    }


    void pushPlaylistChanges(final List<MediaItem2> playlist, final MediaMetadata2 metadata) {
    void pushPlaylistMetadataChanges(MediaMetadata2 metadata) {
        synchronized (mLock) {
        synchronized (mLock) {
            mPlaylist = playlist;
            mPlaylistMetadata = metadata;
            mPlaylistMetadata = metadata;
        }
        }
        mCallbackExecutor.execute(() -> {
        mCallbackExecutor.execute(() -> {
@@ -851,20 +876,33 @@ public class MediaController2Impl implements MediaController2Provider {
                return;
                return;
            }
            }
            // TODO(jaewan): Fix public API not to take playlistAgent.
            // TODO(jaewan): Fix public API not to take playlistAgent.
            mCallback.onPlaylistChanged(mInstance, null, playlist, metadata);
            mCallback.onPlaylistMetadataChanged(mInstance, null, metadata);
        });
        });
    }
    }


    public void pushPlaylistMetadataChanges(MediaMetadata2 metadata) {
    void pushShuffleModeChanges(int shuffleMode) {
        synchronized (mLock) {
        synchronized (mLock) {
            mPlaylistMetadata = metadata;
            mShuffleMode = shuffleMode;
        }
        }
        mCallbackExecutor.execute(() -> {
        mCallbackExecutor.execute(() -> {
            if (!mInstance.isConnected()) {
            if (!mInstance.isConnected()) {
                return;
                return;
            }
            }
            // TODO(jaewan): Fix public API not to take playlistAgent.
            // TODO(jaewan): Fix public API not to take playlistAgent.
            mCallback.onPlaylistMetadataChanged(mInstance, null, metadata);
            mCallback.onShuffleModeChanged(mInstance, null, shuffleMode);
        });
    }

    void pushRepeatModeChanges(int repeatMode) {
        synchronized (mLock) {
            mRepeatMode = repeatMode;
        }
        mCallbackExecutor.execute(() -> {
            if (!mInstance.isConnected()) {
                return;
            }
            // TODO(jaewan): Fix public API not to take playlistAgent.
            mCallback.onRepeatModeChanged(mInstance, null, repeatMode);
        });
        });
    }
    }


@@ -877,7 +915,9 @@ public class MediaController2Impl implements MediaController2Provider {
            final float playbackSpeed,
            final float playbackSpeed,
            final long bufferedPositionMs,
            final long bufferedPositionMs,
            final PlaybackInfo info,
            final PlaybackInfo info,
            final PlaylistParams params, final List<MediaItem2> playlist,
            final int repeatMode,
            final int shuffleMode,
            final List<MediaItem2> playlist,
            final PendingIntent sessionActivity) {
            final PendingIntent sessionActivity) {
        if (DEBUG) {
        if (DEBUG) {
            Log.d(TAG, "onConnectedNotLocked sessionBinder=" + sessionBinder
            Log.d(TAG, "onConnectedNotLocked sessionBinder=" + sessionBinder
@@ -907,7 +947,8 @@ public class MediaController2Impl implements MediaController2Provider {
                mPlaybackSpeed = playbackSpeed;
                mPlaybackSpeed = playbackSpeed;
                mBufferedPositionMs = bufferedPositionMs;
                mBufferedPositionMs = bufferedPositionMs;
                mPlaybackInfo = info;
                mPlaybackInfo = info;
                mPlaylistParams = params;
                mRepeatMode = repeatMode;
                mShuffleMode = shuffleMode;
                mPlaylist = playlist;
                mPlaylist = playlist;
                mSessionActivity = sessionActivity;
                mSessionActivity = sessionActivity;
                mSessionBinder = sessionBinder;
                mSessionBinder = sessionBinder;
+16 −11
Original line number Original line Diff line number Diff line
@@ -24,7 +24,6 @@ import android.media.MediaMetadata2;
import android.media.MediaSession2.Command;
import android.media.MediaSession2.Command;
import android.media.MediaSession2.CommandButton;
import android.media.MediaSession2.CommandButton;
import android.media.MediaSession2.CommandGroup;
import android.media.MediaSession2.CommandGroup;
import android.media.MediaSession2.PlaylistParams;
import android.os.Bundle;
import android.os.Bundle;
import android.os.ResultReceiver;
import android.os.ResultReceiver;
import android.text.TextUtils;
import android.text.TextUtils;
@@ -169,7 +168,7 @@ public class MediaController2Stub extends IMediaController2.Stub {
    }
    }


    @Override
    @Override
    public void onPlaylistParamsChanged(Bundle paramsBundle) throws RuntimeException {
    public void onRepeatModeChanged(int repeatMode) {
        final MediaController2Impl controller;
        final MediaController2Impl controller;
        try {
        try {
            controller = getController();
            controller = getController();
@@ -177,12 +176,7 @@ public class MediaController2Stub extends IMediaController2.Stub {
            Log.w(TAG, "Don't fail silently here. Highly likely a bug");
            Log.w(TAG, "Don't fail silently here. Highly likely a bug");
            return;
            return;
        }
        }
        PlaylistParams params = PlaylistParams.fromBundle(controller.getContext(), paramsBundle);
        controller.pushRepeatModeChanges(repeatMode);
        if (params == null) {
            Log.w(TAG, "onPlaylistParamsChanged(): Ignoring null playlistParams");
            return;
        }
        controller.pushPlaylistParamsChanges(params);
    }
    }


    @Override
    @Override
@@ -207,10 +201,22 @@ public class MediaController2Stub extends IMediaController2.Stub {
                PlaybackInfoImpl.fromBundle(controller.getContext(), playbackInfo));
                PlaybackInfoImpl.fromBundle(controller.getContext(), playbackInfo));
    }
    }


    @Override
    public void onShuffleModeChanged(int shuffleMode) {
        final MediaController2Impl controller;
        try {
            controller = getController();
        } catch (IllegalStateException e) {
            Log.w(TAG, "Don't fail silently here. Highly likely a bug");
            return;
        }
        controller.pushShuffleModeChanges(shuffleMode);
    }

    @Override
    @Override
    public void onConnected(IMediaSession2 sessionBinder, Bundle commandGroup,
    public void onConnected(IMediaSession2 sessionBinder, Bundle commandGroup,
            int playerState, long positionEventTimeMs, long positionMs, float playbackSpeed,
            int playerState, long positionEventTimeMs, long positionMs, float playbackSpeed,
            long bufferedPositionMs, Bundle playbackInfo, Bundle playlistParams,
            long bufferedPositionMs, Bundle playbackInfo, int shuffleMode, int repeatMode,
            List<Bundle> itemBundleList, PendingIntent sessionActivity) {
            List<Bundle> itemBundleList, PendingIntent sessionActivity) {
        final MediaController2Impl controller = mController.get();
        final MediaController2Impl controller = mController.get();
        if (controller == null) {
        if (controller == null) {
@@ -233,8 +239,7 @@ public class MediaController2Stub extends IMediaController2.Stub {
        controller.onConnectedNotLocked(sessionBinder,
        controller.onConnectedNotLocked(sessionBinder,
                CommandGroup.fromBundle(context, commandGroup),
                CommandGroup.fromBundle(context, commandGroup),
                playerState, positionEventTimeMs, positionMs, playbackSpeed, bufferedPositionMs,
                playerState, positionEventTimeMs, positionMs, playbackSpeed, bufferedPositionMs,
                PlaybackInfoImpl.fromBundle(context, playbackInfo),
                PlaybackInfoImpl.fromBundle(context, playbackInfo), repeatMode, shuffleMode,
                PlaylistParams.fromBundle(context, playlistParams),
                itemList, sessionActivity);
                itemList, sessionActivity);
    }
    }


+77 −116
Original line number Original line Diff line number Diff line
@@ -47,9 +47,6 @@ import android.media.MediaSession2.Command;
import android.media.MediaSession2.CommandButton;
import android.media.MediaSession2.CommandButton;
import android.media.MediaSession2.CommandGroup;
import android.media.MediaSession2.CommandGroup;
import android.media.MediaSession2.ControllerInfo;
import android.media.MediaSession2.ControllerInfo;
import android.media.MediaSession2.PlaylistParams;
import android.media.MediaSession2.PlaylistParams.RepeatMode;
import android.media.MediaSession2.PlaylistParams.ShuffleMode;
import android.media.MediaSession2.SessionCallback;
import android.media.MediaSession2.SessionCallback;
import android.media.MediaSessionService2;
import android.media.MediaSessionService2;
import android.media.SessionToken2;
import android.media.SessionToken2;
@@ -254,6 +251,7 @@ public class MediaSession2Impl implements MediaSession2Provider {
            mSessionStub.notifyPlaybackInfoChanged(info);
            mSessionStub.notifyPlaybackInfoChanged(info);
            notifyPlayerUpdatedNotLocked(oldPlayer);
            notifyPlayerUpdatedNotLocked(oldPlayer);
        }
        }
        // TODO(jaewan): Repeat the same thing for the playlist agent.
    }
    }


    private PlaybackInfo createPlaybackInfo(VolumeProvider2 volumeProvider, AudioAttributes attrs) {
    private PlaybackInfo createPlaybackInfo(VolumeProvider2 volumeProvider, AudioAttributes attrs) {
@@ -430,41 +428,6 @@ public class MediaSession2Impl implements MediaSession2Provider {
        mSessionStub.notifyCustomLayoutNotLocked(controller, layout);
        mSessionStub.notifyCustomLayoutNotLocked(controller, layout);
    }
    }


    @Override
    public void setPlaylistParams_impl(PlaylistParams params) {
        if (params == null) {
            throw new IllegalArgumentException("params shouldn't be null");
        }
        ensureCallingThread();
        // TODO: Uncomment or remove
        /*
        final MediaPlayerBase player = mPlayer;
        if (player != null) {
            // TODO implement
            //player.setPlaylistParams(params);
            mSessionStub.notifyPlaylistParamsChanged(params);
        }
        */
    }

    @Override
    public PlaylistParams getPlaylistParams_impl() {
        // TODO: Uncomment or remove
        /*
        final MediaPlayerBase player = mPlayer;
        if (player != null) {
            // TODO(jaewan): Is it safe to be called on any thread?
            //               Otherwise MediaSession2 should cache parameter of setPlaylistParams.
            // TODO implement
            //return player.getPlaylistParams();
            return null;
        } else if (DEBUG) {
            Log.d(TAG, "API calls after the close()", new IllegalStateException());
        }
        */
        return null;
    }

    //////////////////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////////////
    // TODO(jaewan): Implement follows
    // TODO(jaewan): Implement follows
    //////////////////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////////////
@@ -597,6 +560,48 @@ public class MediaSession2Impl implements MediaSession2Provider {
        return null;
        return null;
    }
    }


    @Override
    public int getRepeatMode_impl() {
        final MediaPlaylistAgent agent = mPlaylistAgent;
        if (agent != null) {
            return agent.getRepeatMode();
        } else if (DEBUG) {
            Log.d(TAG, "API calls after the close()", new IllegalStateException());
        }
        return MediaPlaylistAgent.REPEAT_MODE_NONE;
    }

    @Override
    public void setRepeatMode_impl(int repeatMode) {
        final MediaPlaylistAgent agent = mPlaylistAgent;
        if (agent != null) {
            agent.setRepeatMode(repeatMode);
        } else if (DEBUG) {
            Log.d(TAG, "API calls after the close()", new IllegalStateException());
        }
    }

    @Override
    public int getShuffleMode_impl() {
        final MediaPlaylistAgent agent = mPlaylistAgent;
        if (agent != null) {
            return agent.getShuffleMode();
        } else if (DEBUG) {
            Log.d(TAG, "API calls after the close()", new IllegalStateException());
        }
        return MediaPlaylistAgent.SHUFFLE_MODE_NONE;
    }

    @Override
    public void setShuffleMode_impl(int shuffleMode) {
        final MediaPlaylistAgent agent = mPlaylistAgent;
        if (agent != null) {
            agent.setShuffleMode(shuffleMode);
        } else if (DEBUG) {
            Log.d(TAG, "API calls after the close()", new IllegalStateException());
        }
    }

    @Override
    @Override
    public void prepare_impl() {
    public void prepare_impl() {
        ensureCallingThread();
        ensureCallingThread();
@@ -681,7 +686,7 @@ public class MediaSession2Impl implements MediaSession2Provider {
    private void notifyPlaylistChangedOnExecutor(MediaPlaylistAgent playlistAgent,
    private void notifyPlaylistChangedOnExecutor(MediaPlaylistAgent playlistAgent,
            List<MediaItem2> list, MediaMetadata2 metadata) {
            List<MediaItem2> list, MediaMetadata2 metadata) {
        if (playlistAgent != mPlaylistAgent) {
        if (playlistAgent != mPlaylistAgent) {
            // Ignore calls from the old agent. Ignore.
            // Ignore calls from the old agent.
            return;
            return;
        }
        }
        mCallback.onPlaylistChanged(mInstance, playlistAgent, list, metadata);
        mCallback.onPlaylistChanged(mInstance, playlistAgent, list, metadata);
@@ -691,13 +696,33 @@ public class MediaSession2Impl implements MediaSession2Provider {
    private void notifyPlaylistMetadataChangedOnExecutor(MediaPlaylistAgent playlistAgent,
    private void notifyPlaylistMetadataChangedOnExecutor(MediaPlaylistAgent playlistAgent,
            MediaMetadata2 metadata) {
            MediaMetadata2 metadata) {
        if (playlistAgent != mPlaylistAgent) {
        if (playlistAgent != mPlaylistAgent) {
            // Ignore calls from the old agent. Ignore.
            // Ignore calls from the old agent.
            return;
            return;
        }
        }
        mCallback.onPlaylistMetadataChanged(mInstance, playlistAgent, metadata);
        mCallback.onPlaylistMetadataChanged(mInstance, playlistAgent, metadata);
        mSessionStub.notifyPlaylistMetadataChangedNotLocked(metadata);
        mSessionStub.notifyPlaylistMetadataChangedNotLocked(metadata);
    }
    }


    private void notifyRepeatModeChangedOnExecutor(MediaPlaylistAgent playlistAgent,
            int repeatMode) {
        if (playlistAgent != mPlaylistAgent) {
            // Ignore calls from the old agent.
            return;
        }
        mCallback.onRepeatModeChanged(mInstance, playlistAgent, repeatMode);
        mSessionStub.notifyRepeatModeChangedNotLocked(repeatMode);
    }

    private void notifyShuffleModeChangedOnExecutor(MediaPlaylistAgent playlistAgent,
            int shuffleMode) {
        if (playlistAgent != mPlaylistAgent) {
            // Ignore calls from the old agent.
            return;
        }
        mCallback.onShuffleModeChanged(mInstance, playlistAgent, shuffleMode);
        mSessionStub.notifyShuffleModeChangedNotLocked(shuffleMode);
    }

    private void notifyPlayerUpdatedNotLocked(MediaPlayerBase oldPlayer) {
    private void notifyPlayerUpdatedNotLocked(MediaPlayerBase oldPlayer) {
        final MediaPlayerBase player = mPlayer;
        final MediaPlayerBase player = mPlayer;
        // TODO(jaewan): (Can be post-P) Find better way for player.getPlayerState() //
        // TODO(jaewan): (Can be post-P) Find better way for player.getPlayerState() //
@@ -892,15 +917,21 @@ public class MediaSession2Impl implements MediaSession2Provider {
        }
        }


        @Override
        @Override
        public void onShuffleModeChanged(MediaPlaylistAgent playlistAgent, int shuffleMode) {
        public void onRepeatModeChanged(MediaPlaylistAgent playlistAgent, int repeatMode) {
            super.onShuffleModeChanged(playlistAgent, shuffleMode);
            final MediaSession2Impl session = mSession.get();
            // TODO(jaewan): Handle this (b/74118768)
            if (session == null) {
                return;
            }
            session.notifyRepeatModeChangedOnExecutor(playlistAgent, repeatMode);
        }
        }


        @Override
        @Override
        public void onRepeatModeChanged(MediaPlaylistAgent playlistAgent, int repeatMode) {
        public void onShuffleModeChanged(MediaPlaylistAgent playlistAgent, int shuffleMode) {
            super.onRepeatModeChanged(playlistAgent, repeatMode);
            final MediaSession2Impl session = mSession.get();
            // TODO(jaewan): Handle this (b/74118768)
            if (session == null) {
                return;
            }
            session.notifyShuffleModeChangedOnExecutor(playlistAgent, shuffleMode);
        }
        }
    }
    }


@@ -1245,76 +1276,6 @@ public class MediaSession2Impl implements MediaSession2Provider {
        }
        }
    }
    }


    public static class PlaylistParamsImpl implements PlaylistParamsProvider {
        /**
         * Keys used for converting a PlaylistParams object to a bundle object and vice versa.
         */
        private static final String KEY_REPEAT_MODE =
                "android.media.session2.playlistparams2.repeat_mode";
        private static final String KEY_SHUFFLE_MODE =
                "android.media.session2.playlistparams2.shuffle_mode";
        private static final String KEY_MEDIA_METADATA2_BUNDLE =
                "android.media.session2.playlistparams2.metadata2_bundle";

        private Context mContext;
        private PlaylistParams mInstance;
        private @RepeatMode int mRepeatMode;
        private @ShuffleMode int mShuffleMode;
        private MediaMetadata2 mPlaylistMetadata;

        public PlaylistParamsImpl(Context context, PlaylistParams instance,
                @RepeatMode int repeatMode, @ShuffleMode int shuffleMode,
                MediaMetadata2 playlistMetadata) {
            // TODO(jaewan): Sanity check
            mContext = context;
            mInstance = instance;
            mRepeatMode = repeatMode;
            mShuffleMode = shuffleMode;
            mPlaylistMetadata = playlistMetadata;
        }

        public @RepeatMode int getRepeatMode_impl() {
            return mRepeatMode;
        }

        public @ShuffleMode int getShuffleMode_impl() {
            return mShuffleMode;
        }

        public MediaMetadata2 getPlaylistMetadata_impl() {
            return mPlaylistMetadata;
        }

        @Override
        public Bundle toBundle_impl() {
            Bundle bundle = new Bundle();
            bundle.putInt(KEY_REPEAT_MODE, mRepeatMode);
            bundle.putInt(KEY_SHUFFLE_MODE, mShuffleMode);
            if (mPlaylistMetadata != null) {
                bundle.putBundle(KEY_MEDIA_METADATA2_BUNDLE, mPlaylistMetadata.toBundle());
            }
            return bundle;
        }

        public static PlaylistParams fromBundle(Context context, Bundle bundle) {
            if (bundle == null) {
                return null;
            }
            if (!bundle.containsKey(KEY_REPEAT_MODE) || !bundle.containsKey(KEY_SHUFFLE_MODE)) {
                return null;
            }

            Bundle metadataBundle = bundle.getBundle(KEY_MEDIA_METADATA2_BUNDLE);
            MediaMetadata2 metadata = metadataBundle == null
                    ? null : MediaMetadata2.fromBundle(context, metadataBundle);

            return new PlaylistParams(context,
                    bundle.getInt(KEY_REPEAT_MODE),
                    bundle.getInt(KEY_SHUFFLE_MODE),
                    metadata);
        }
    }

    public static class CommandButtonImpl implements CommandButtonProvider {
    public static class CommandButtonImpl implements CommandButtonProvider {
        private static final String KEY_COMMAND
        private static final String KEY_COMMAND
                = "android.media.media_session2.command_button.command";
                = "android.media.media_session2.command_button.command";
Loading