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

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

MediaSession2: Implement update/getPlaylistMetadata()

Bug: 74174649
Test: Run CTS with MediaComponents/runcts.sh
Change-Id: Iec6460a21044d5ad03a777a99ba7c7e153b7af84
parent e0a38c69
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@ oneway interface IMediaSession2 {
    void setRating(IMediaSession2Callback caller, String mediaId, in Bundle rating);

    void setPlaylist(IMediaSession2Callback caller, in List<Bundle> playlist, in Bundle metadata);
    void updatePlaylistMetadata(IMediaSession2Callback caller, in Bundle metadata);

    //////////////////////////////////////////////////////////////////////////////////////////////
    // library service specific
+1 −0
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ import com.android.media.IMediaSession2;
oneway interface IMediaSession2Callback {
    void onPlaybackStateChanged(in Bundle state);
    void onPlaylistChanged(in List<Bundle> playlist, in Bundle metadata);
    void onPlaylistMetadataChanged(in Bundle metadata);
    void onPlaylistParamsChanged(in Bundle params);
    void onPlaybackInfoChanged(in Bundle playbackInfo);

+36 −0
Original line number Diff line number Diff line
@@ -550,6 +550,29 @@ public class MediaController2Impl implements MediaController2Provider {
        }
    }

    @Override
    public MediaMetadata2 getPlaylistMetadata_impl() {
        synchronized (mLock) {
            return mPlaylistMetadata;
        }
    }

    @Override
    public void updatePlaylistMetadata_impl(MediaMetadata2 metadata) {
        final IMediaSession2 binder = getSessionBinderIfAble(
                COMMAND_CODE_PLAYLIST_SET_LIST_METADATA);
        if (binder != null) {
            Bundle metadataBundle = (metadata == null) ? null : metadata.toBundle();
            try {
                binder.updatePlaylistMetadata(mSessionCallbackStub, metadataBundle);
            } 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
    public void prepare_impl() {
        sendTransportControlCommand(MediaSession2.COMMAND_CODE_PLAYBACK_PREPARE);
@@ -731,6 +754,19 @@ public class MediaController2Impl implements MediaController2Provider {
        });
    }

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

    // Should be used without a lock to prevent potential deadlock.
    void onConnectedNotLocked(IMediaSession2 sessionBinder,
            final CommandGroup allowedCommands, final PlaybackState2 state, final PlaybackInfo info,
+14 −0
Original line number Diff line number Diff line
@@ -108,6 +108,20 @@ public class MediaSession2CallbackStub extends IMediaSession2Callback.Stub {
        controller.pushPlaylistChanges(playlist, metadata);
    }

    @Override
    public void onPlaylistMetadataChanged(Bundle metadataBundle) throws RuntimeException {
        final MediaController2Impl controller;
        try {
            controller = getController();
        } catch (IllegalStateException e) {
            Log.w(TAG, "Don't fail silently here. Highly likely a bug");
            return;
        }
        MediaMetadata2 metadata =
                MediaMetadata2.fromBundle(controller.getContext(), metadataBundle);
        controller.pushPlaylistMetadataChanges(metadata);
    }

    @Override
    public void onPlaylistParamsChanged(Bundle paramsBundle) throws RuntimeException {
        final MediaController2Impl controller;
+36 −2
Original line number Diff line number Diff line
@@ -509,6 +509,16 @@ public class MediaSession2Impl implements MediaSession2Provider {
        }
    }

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

    @Override
    public void addPlaylistItem_impl(int index, MediaItem2 item) {
        if (index < 0) {
@@ -558,6 +568,17 @@ public class MediaSession2Impl implements MediaSession2Provider {
        return null;
    }

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

    @Override
    public MediaItem2 getCurrentPlaylistItem_impl() {
        // TODO(jaewan): Implement
@@ -723,6 +744,16 @@ public class MediaSession2Impl implements MediaSession2Provider {
        mSessionStub.notifyPlaylistChangedNotLocked(list, metadata);
    }

    private void notifyPlaylistMetadataChangedOnExecutor(MediaPlaylistAgent playlistAgent,
            MediaMetadata2 metadata) {
        if (playlistAgent != mPlaylistAgent) {
            // Ignore calls from the old agent. Ignore.
            return;
        }
        mCallback.onPlaylistMetadataChanged(mInstance, playlistAgent, metadata);
        mSessionStub.notifyPlaylistMetadataChangedNotLocked(metadata);
    }

    private void notifyPlaybackStateChangedNotLocked(final PlaybackState2 state) {
        ArrayMap<PlayerEventCallback, Executor> callbacks = new ArrayMap<>();
        synchronized (mLock) {
@@ -848,8 +879,11 @@ public class MediaSession2Impl implements MediaSession2Provider {
        @Override
        public void onPlaylistMetadataChanged(MediaPlaylistAgent playlistAgent,
                MediaMetadata2 metadata) {
            super.onPlaylistMetadataChanged(playlistAgent, metadata);
            // TODO(jaewan): Handle this (b/74174649)
            final MediaSession2Impl session = mSession.get();
            if (session == null) {
                return;
            }
            session.notifyPlaylistMetadataChangedOnExecutor(playlistAgent, metadata);
        }

        @Override
Loading