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

Commit de95aaa1 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "MediaSession2: Implement MediaSession2#updatePlayer()" into pi-dev

parents 829d4349 e1cf5e5d
Loading
Loading
Loading
Loading
+106 −52
Original line number Original line Diff line number Diff line
@@ -30,6 +30,7 @@ import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ResolveInfo;
import android.media.AudioAttributes;
import android.media.AudioAttributes;
import android.media.AudioManager;
import android.media.AudioManager;
import android.media.DataSourceDesc;
import android.media.MediaController2;
import android.media.MediaController2;
import android.media.MediaController2.PlaybackInfo;
import android.media.MediaController2.PlaybackInfo;
import android.media.MediaItem2;
import android.media.MediaItem2;
@@ -38,6 +39,7 @@ import android.media.MediaMetadata2;
import android.media.MediaPlayerBase;
import android.media.MediaPlayerBase;
import android.media.MediaPlayerBase.PlayerEventCallback;
import android.media.MediaPlayerBase.PlayerEventCallback;
import android.media.MediaPlaylistAgent;
import android.media.MediaPlaylistAgent;
import android.media.MediaPlaylistAgent.PlaylistEventCallback;
import android.media.MediaSession2;
import android.media.MediaSession2;
import android.media.MediaSession2.Builder;
import android.media.MediaSession2.Builder;
import android.media.MediaSession2.Command;
import android.media.MediaSession2.Command;
@@ -85,6 +87,8 @@ public class MediaSession2Impl implements MediaSession2Provider {
    private final AudioManager mAudioManager;
    private final AudioManager mAudioManager;
    private final ArrayMap<PlayerEventCallback, Executor> mCallbacks = new ArrayMap<>();
    private final ArrayMap<PlayerEventCallback, Executor> mCallbacks = new ArrayMap<>();
    private final PendingIntent mSessionActivity;
    private final PendingIntent mSessionActivity;
    private final PlayerEventCallback mPlayerEventCallback;
    private final PlaylistEventCallback mPlaylistEventCallback;


    // mPlayer is set to null when the session is closed, and we shouldn't throw an exception
    // mPlayer is set to null when the session is closed, and we shouldn't throw an exception
    // nor leave log always for using mPlayer when it's null. Here's the reason.
    // nor leave log always for using mPlayer when it's null. Here's the reason.
@@ -110,8 +114,6 @@ public class MediaSession2Impl implements MediaSession2Provider {
    private VolumeProvider2 mVolumeProvider;
    private VolumeProvider2 mVolumeProvider;
    @GuardedBy("mLock")
    @GuardedBy("mLock")
    private PlaybackInfo mPlaybackInfo;
    private PlaybackInfo mPlaybackInfo;
    @GuardedBy("mLock")
    private MyEventCallback mEventCallback;


    /**
    /**
     * Can be only called by the {@link Builder#build()}.
     * Can be only called by the {@link Builder#build()}.
@@ -140,7 +142,8 @@ public class MediaSession2Impl implements MediaSession2Provider {
        mSessionActivity = sessionActivity;
        mSessionActivity = sessionActivity;
        mSessionStub = new MediaSession2Stub(this);
        mSessionStub = new MediaSession2Stub(this);
        mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
        mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
        mPlaylistAgent = playlistAgent;
        mPlayerEventCallback = new MyPlayerEventCallback(this);
        mPlaylistEventCallback = new MyPlaylistEventCallback(this);


        // Infer type from the id and package name.
        // Infer type from the id and package name.
        String libraryService = getServiceName(context, MediaLibraryService2.SERVICE_INTERFACE, id);
        String libraryService = getServiceName(context, MediaLibraryService2.SERVICE_INTERFACE, id);
@@ -159,7 +162,7 @@ public class MediaSession2Impl implements MediaSession2Provider {
                    mContext.getPackageName(), null, id, mSessionStub).getInstance();
                    mContext.getPackageName(), null, id, mSessionStub).getInstance();
        }
        }


        setPlayer(player, volumeProvider);
        updatePlayer(player, playlistAgent, volumeProvider);


        // Ask server for the sanity check, and starts
        // Ask server for the sanity check, and starts
        // Sanity check for making session ID unique 'per package' cannot be done in here.
        // Sanity check for making session ID unique 'per package' cannot be done in here.
@@ -210,23 +213,43 @@ public class MediaSession2Impl implements MediaSession2Provider {
        if (player == null) {
        if (player == null) {
            throw new IllegalArgumentException("player shouldn't be null");
            throw new IllegalArgumentException("player shouldn't be null");
        }
        }
        mPlaylistAgent = playlistAgent;
        updatePlayer(player, playlistAgent, volumeProvider);
        setPlayer(player, volumeProvider);
    }
    }


    private void setPlayer(MediaPlayerBase player, VolumeProvider2 volumeProvider) {
    private void updatePlayer(MediaPlayerBase player, MediaPlaylistAgent agent,
            VolumeProvider2 volumeProvider) {
        final MediaPlayerBase oldPlayer;
        final MediaPlaylistAgent oldAgent;
        final PlaybackInfo info = createPlaybackInfo(volumeProvider, player.getAudioAttributes());
        final PlaybackInfo info = createPlaybackInfo(volumeProvider, player.getAudioAttributes());
        synchronized (mLock) {
        synchronized (mLock) {
            if (mPlayer != null && mEventCallback != null) {
            oldPlayer = mPlayer;
                // This might not work for a poorly implemented player.
            oldAgent = mPlaylistAgent;
                mPlayer.unregisterPlayerEventCallback(mEventCallback);
            }
            mPlayer = player;
            mPlayer = player;
            mEventCallback = new MyEventCallback(this, player);
            // TODO(jaewan): Replace this with the proper default agent (b/74090741)
            player.registerPlayerEventCallback(mCallbackExecutor, mEventCallback);
            if (agent == null) {
                agent = new MediaPlaylistAgent(mContext) {};
            }
            mPlaylistAgent = agent;
            mVolumeProvider = volumeProvider;
            mVolumeProvider = volumeProvider;
            mPlaybackInfo = info;
            mPlaybackInfo = info;
        }
        }
        if (player != oldPlayer) {
            player.registerPlayerEventCallback(mCallbackExecutor, mPlayerEventCallback);
            if (oldPlayer != null) {
                // Warning: Poorly implement player may ignore this
                oldPlayer.unregisterPlayerEventCallback(mPlayerEventCallback);
            }
        }
        if (agent != oldAgent) {
            agent.registerPlaylistEventCallback(mCallbackExecutor, mPlaylistEventCallback);
            if (oldAgent != null) {
                // Warning: Poorly implement player may ignore this
                oldAgent.unregisterPlaylistEventCallback(mPlaylistEventCallback);
            }
        }
        // TODO(jaewan): Notify controllers about the change in the media player base (b/74370608)
        //               Note that notification will be done indirectly by telling player state,
        //               position, buffered position, etc.
        mSessionStub.notifyPlaybackInfoChanged(info);
        mSessionStub.notifyPlaybackInfoChanged(info);
        notifyPlaybackStateChangedNotLocked(mInstance.getPlaybackState());
        notifyPlaybackStateChangedNotLocked(mInstance.getPlaybackState());
    }
    }
@@ -281,12 +304,19 @@ public class MediaSession2Impl implements MediaSession2Provider {
            // Invalidate previously published session stub.
            // Invalidate previously published session stub.
            mSessionStub.destroyNotLocked();
            mSessionStub.destroyNotLocked();
        }
        }
        final MediaPlayerBase player;
        final MediaPlaylistAgent agent;
        synchronized (mLock) {
        synchronized (mLock) {
            if (mPlayer != null) {
            player = mPlayer;
                // close can be called multiple times
                mPlayer.unregisterPlayerEventCallback(mEventCallback);
            mPlayer = null;
            mPlayer = null;
            agent = mPlaylistAgent;
            mPlaylistAgent = null;
        }
        if (player != null) {
            player.unregisterPlayerEventCallback(mPlayerEventCallback);
        }
        }
        if (agent != null) {
            agent.unregisterPlaylistEventCallback(mPlaylistEventCallback);
        }
        }
    }
    }


@@ -295,6 +325,11 @@ public class MediaSession2Impl implements MediaSession2Provider {
        return getPlayer();
        return getPlayer();
    }
    }


    @Override
    public MediaPlaylistAgent getPlaylistAgent_impl() {
        return mPlaylistAgent;
    }

    @Override
    @Override
    public VolumeProvider2 getVolumeProvider_impl() {
    public VolumeProvider2 getVolumeProvider_impl() {
        return mVolumeProvider;
        return mVolumeProvider;
@@ -728,51 +763,70 @@ public class MediaSession2Impl implements MediaSession2Provider {
        return mSessionActivity;
        return mSessionActivity;
    }
    }


    private static class MyEventCallback extends PlayerEventCallback {
    private static class MyPlayerEventCallback extends PlayerEventCallback {
        private final WeakReference<MediaSession2Impl> mSession;
        private final WeakReference<MediaSession2Impl> mSession;
        private final MediaPlayerBase mPlayer;


        private MyEventCallback(MediaSession2Impl session, MediaPlayerBase player) {
        private MyPlayerEventCallback(MediaSession2Impl session) {
            mSession = new WeakReference<>(session);
            mSession = new WeakReference<>(session);
            mPlayer = player;
        }
        }


        // TODO: Uncomment or remove
        /*
        @Override
        @Override
        public void onPlaybackStateChanged(PlaybackState2 state) {
        public void onCurrentDataSourceChanged(MediaPlayerBase mpb, DataSourceDesc dsd) {
            MediaSession2Impl session = mSession.get();
            super.onCurrentDataSourceChanged(mpb, dsd);
            if (mPlayer != session.mInstance.getPlayer()) {
            // TODO(jaewan): Handle this b/74370608
                Log.w(TAG, "Unexpected playback state change notifications. Ignoring.",
                        new IllegalStateException());
                return;
        }
        }
            if (DEBUG) {

                Log.d(TAG, "onPlaybackStateChanged from player, state=" + state);
        @Override
        public void onMediaPrepared(MediaPlayerBase mpb, DataSourceDesc dsd) {
            super.onMediaPrepared(mpb, dsd);
            // TODO(jaewan): Handle this b/74370608
        }

        @Override
        public void onPlayerStateChanged(MediaPlayerBase mpb, int state) {
            super.onPlayerStateChanged(mpb, state);
            // TODO(jaewan): Handle this b/74370608
        }

        @Override
        public void onBufferingStateChanged(MediaPlayerBase mpb, DataSourceDesc dsd, int state) {
            super.onBufferingStateChanged(mpb, dsd, state);
            // TODO(jaewan): Handle this b/74370608
        }
        }
            session.notifyPlaybackStateChangedNotLocked(state);
    }
    }
        */


        // TODO: Uncomment or remove
    private static class MyPlaylistEventCallback extends PlaylistEventCallback {
        /*
        private final WeakReference<MediaSession2Impl> mSession;

        private MyPlaylistEventCallback(MediaSession2Impl session) {
            mSession = new WeakReference<>(session);
        }

        @Override
        @Override
        public void onError(String mediaId, int what, int extra) {
        public void onPlaylistChanged(MediaPlaylistAgent playlistAgent, List<MediaItem2> list,
            MediaSession2Impl session = mSession.get();
                MediaMetadata2 metadata) {
            if (mPlayer != session.mInstance.getPlayer()) {
            super.onPlaylistChanged(playlistAgent, list, metadata);
                Log.w(TAG, "Unexpected playback state change notifications. Ignoring.",
            // TODO(jaewan): Handle this (b/74326040)
                        new IllegalStateException());
                return;
        }
        }
            if (DEBUG) {

                Log.d(TAG, "onError from player, mediaId=" + mediaId + ", what=" + what
        @Override
                        + ", extra=" + extra);
        public void onPlaylistMetadataChanged(MediaPlaylistAgent playlistAgent,
                MediaMetadata2 metadata) {
            super.onPlaylistMetadataChanged(playlistAgent, metadata);
            // TODO(jaewan): Handle this (b/74174649)
        }
        }
            session.notifyErrorNotLocked(mediaId, what, extra);

        @Override
        public void onShuffleModeChanged(MediaPlaylistAgent playlistAgent, int shuffleMode) {
            super.onShuffleModeChanged(playlistAgent, shuffleMode);
            // TODO(jaewan): Handle this (b/74118768)
        }
        }
        */


        //TODO implement the real PlayerEventCallback methods
        @Override
        public void onRepeatModeChanged(MediaPlaylistAgent playlistAgent, int repeatMode) {
            super.onRepeatModeChanged(playlistAgent, repeatMode);
            // TODO(jaewan): Handle this (b/74118768)
        }
    }
    }


    public static final class CommandImpl implements CommandProvider {
    public static final class CommandImpl implements CommandProvider {