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

Commit 28ebd0a9 authored by Etienne Ruffieux's avatar Etienne Ruffieux Committed by Gerrit Code Review
Browse files

Merge "Fill AVRCP queue Metadata with MediaController Metadata"

parents 24c0c0d2 6c18b5c3
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -131,6 +131,23 @@ public class MediaPlayerWrapper {
    }

    List<Metadata> getCurrentQueue() {
        // MediaSession#QueueItem's MediaDescription doesn't necessarily include media duration,
        // so the playing media info metadata should be obtained by the MediaController.
        // MediaSession doesn't include the Playlist Metadata, only the current song one.
        Metadata mediaPlayingMetadata = getCurrentMetadata();

        // The queue metadata is built with QueueId in place of MediaId, so we can't compare it.
        // MediaDescription is usually compared via its title, artist and album.
        if (mediaPlayingMetadata != null) {
            for (Metadata metadata : mCurrentData.queue) {
                if (metadata.title.equals(mediaPlayingMetadata.title)
                        && metadata.artist.equals(mediaPlayingMetadata.artist)
                        && metadata.album.equals(mediaPlayingMetadata.album)) {
                    // Replace default values by MediaController non default values.
                    metadata.replaceDefaults(mediaPlayingMetadata);
                }
            }
        }
        return mCurrentData.queue;
    }

+47 −0
Original line number Diff line number Diff line
@@ -64,6 +64,14 @@ public class Metadata implements Cloneable {
        if (!Objects.equals(album, m.album)) return false;
        if (!Objects.equals(trackNum, m.trackNum)) return false;
        if (!Objects.equals(numTracks, m.numTracks)) return false;
        if (!Objects.equals(genre, m.genre)) return false;
        if (!Objects.equals(duration, m.duration)) return false;
        // Actual image comparisons have shown to be very expensive. Since it's rare that
        // an application changes the cover artwork between multiple images once it's not
        // null anymore, we just look for changes between "something" and "nothing".
        if ((image == null && m.image != null) || (image != null && m.image == null)) {
            return false;
        }
        return true;
    }

@@ -80,6 +88,45 @@ public class Metadata implements Cloneable {
                + " trackPosition=" + trackNum + "/" + numTracks + " image=" + image + " }";
    }

    /**
     * Replaces default values by {@code filledMetadata} non default values.
     */
    public void replaceDefaults(Metadata filledMetadata) {
        if (filledMetadata == null) {
            return;
        }

        Metadata empty = Util.empty_data();

        if (empty.mediaId.equals(mediaId)) {
            mediaId = filledMetadata.mediaId;
        }
        if (empty.title.equals(title)) {
            title = filledMetadata.title;
        }
        if (empty.artist.equals(artist)) {
            artist = filledMetadata.artist;
        }
        if (empty.album.equals(album)) {
            album = filledMetadata.album;
        }
        if (empty.trackNum.equals(trackNum)) {
            trackNum = filledMetadata.trackNum;
        }
        if (empty.numTracks.equals(numTracks)) {
            numTracks = filledMetadata.numTracks;
        }
        if (empty.genre.equals(genre)) {
            genre = filledMetadata.genre;
        }
        if (empty.duration.equals(duration)) {
            duration = filledMetadata.duration;
        }
        if (image == null) {
            image = filledMetadata.image;
        }
    }

    /**
     * A Builder object to populate a Metadata from various different Media Framework objects
     */
+29 −2
Original line number Diff line number Diff line
@@ -412,17 +412,44 @@ public class MediaPlayerWrapperTest {
                MediaPlayerWrapperFactory.wrap(mMockContext, mMockController, mThread.getLooper());
        wrapper.registerCallback(mTestCbs);

        // Remove the current metadata so it does not override the default duration.
        doReturn(null).when(mMockController).getMetadata();

        // Call getCurrentQueue() multiple times.
        for (int i = 0; i < 3; i++) {
            Assert.assertEquals(wrapper.getCurrentQueue(),
                    Util.toMetadataList(mMockContext, getQueueFromDescriptions(mTestQueue)));
            Assert.assertEquals(
                    Util.toMetadataList(mMockContext, getQueueFromDescriptions(mTestQueue)),
                    wrapper.getCurrentQueue());
        }

        doReturn(mTestMetadata.build()).when(mMockController).getMetadata();

        // Verify that getQueue() was only called twice. Once on creation and once during
        // registration
        verify(mMockController, times(2)).getQueue();
    }

    /*
     * This test checks if the currently playing song queue duration is completed
     * by the MediaController Metadata.
     */
    @Test
    public void testQueueMetadata() {
        MediaPlayerWrapper wrapper =
                MediaPlayerWrapperFactory.wrap(mMockContext, mMockController, mThread.getLooper());

        doReturn(null).when(mMockController).getMetadata();
        Assert.assertFalse(Util.toMetadata(mMockContext, mTestMetadata.build()).duration
                .equals(wrapper.getCurrentQueue().get(0).duration));
        doReturn(mTestMetadata.build()).when(mMockController).getMetadata();
        Assert.assertEquals(Util.toMetadata(mMockContext, mTestMetadata.build()).duration,
                wrapper.getCurrentQueue().get(0).duration);
        // The MediaController Metadata should still not be equal to the queue
        // as the track count is different and should not be overridden.
        Assert.assertFalse(Util.toMetadata(mMockContext, mTestMetadata.build())
                .equals(wrapper.getCurrentQueue().get(0)));
    }

    /*
     * This test sends repeated Playback State updates that only have a short
     * position update change to see if they get debounced.