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

Commit 94b25696 authored by Etienne Ruffieux's avatar Etienne Ruffieux
Browse files

Fix null playstate update from players.

Some players will send a null object as parameter for
playstate change callback, without updating the
MediaSession. These events should still trigger an update
by using the Mediasession metadata if it is different.

Bug: 297191838
Tag: #feature
Test: atest BluetoothInstrumentationTests
Change-Id: Ic5a5b6a68e616af939a4e42d7d64476932dc38d3
parent 7e0b6227
Loading
Loading
Loading
Loading
+14 −8
Original line number Diff line number Diff line
@@ -461,8 +461,11 @@ public class MediaPlayerWrapper {
        @Override
        public void onMetadataChanged(@Nullable MediaMetadata mediaMetadata) {
            if (!isMetadataReady()) {
                Log.v(TAG, "onMetadataChanged(): " + mPackageName
                        + " tried to update with no queue");
                Log.v(
                        TAG,
                        "onMetadataChanged(): "
                                + mPackageName
                                + " tried to update with no metadata");
                return;
            }

@@ -495,13 +498,16 @@ public class MediaPlayerWrapper {
        @Override
        public void onPlaybackStateChanged(@Nullable PlaybackState state) {
            if (!isPlaybackStateReady()) {
                Log.v(TAG, "onPlaybackStateChanged(): " + mPackageName
                        + " tried to update with no queue");
                Log.v(
                        TAG,
                        "onPlaybackStateChanged(): "
                                + mPackageName
                                + " tried to update with no state");
                return;
            }

            mPlaybackStateChangeEventLogger.logv(TAG, "onPlaybackStateChanged(): "
                    + mPackageName + " : " + state.toString());
            mPlaybackStateChangeEventLogger.logv(
                    TAG, "onPlaybackStateChanged(): " + mPackageName + " : " + state);

            if (!playstateEquals(state, getPlaybackState())) {
                e("The callback playback state doesn't match the current state");
@@ -513,8 +519,8 @@ public class MediaPlayerWrapper {
                return;
            }

            // If there is no playstate, ignore the update.
            if (state.getState() == PlaybackState.STATE_NONE) {
            // If state isn't null and there is no playstate, ignore the update.
            if (state != null && state.getState() == PlaybackState.STATE_NONE) {
                Log.v(TAG, "Waiting to send update as controller has no playback state");
                return;
            }
+32 −1
Original line number Diff line number Diff line
@@ -21,7 +21,6 @@ import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.*;

import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
@@ -377,6 +376,38 @@ public class MediaPlayerWrapperTest {
                Util.toMetadata(mMockContext, mTestMetadata.build()));
    }

    @Test
    public void testNullPlayback() {
        // Create the wrapper object and register the looper with the timeout handler
        TestLooperManager looperManager = new TestLooperManager(mThread.getLooper());
        MediaPlayerWrapper wrapper =
                MediaPlayerWrapperFactory.wrap(mMockContext, mMockController, mThread.getLooper());
        wrapper.registerCallback(mTestCbs);

        // Return null when getting the queue
        doReturn(null).when(mMockController).getQueue();

        // Grab the callbacks the wrapper registered with the controller
        verify(mMockController).registerCallback(mControllerCbs.capture(), any());
        MediaController.Callback controllerCallbacks = mControllerCbs.getValue();

        // Update Metadata returned by controller
        mTestState.setState(PlaybackState.STATE_PLAYING, 1000, 1.0f);
        doReturn(mTestState.build()).when(mMockController).getPlaybackState();

        // Call the callback
        controllerCallbacks.onPlaybackStateChanged(null);

        // Assert that the metadata returned by getPlaybackState() is used instead of null

        verify(mTestCbs, times(1)).mediaUpdatedCallback(mMediaUpdateData.capture());
        MediaData data = mMediaUpdateData.getValue();
        Assert.assertEquals(
                "Returned PlaybackState is incorrect",
                data.state.toString(),
                mTestState.build().toString());
    }

    @Test
    public void testNullQueue() {
        // Create the wrapper object and register the looper with the timeout handler