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

Commit 24140bef authored by Ajay Panicker's avatar Ajay Panicker
Browse files

Send Media Update even if Metadata sync timeout occurs

Trying to send a metadata update after a timeout occurs will allow badly
behaving players to still send updates even if data isn't synced. Note
unsynced data can lead to missing or wrong metadata on some carkits and
this is only done as a last resort.

Bug: 73593104
Test: Open Android Auto and Spotify, see in logs that Spotify now has a
playlist that is missing album info.

Change-Id: I251d7a29d869e775409e15eba45b85831450e819
(cherry picked from commit 34d2984da5845a017dac2f32dd1e20a1a8fbfac8)
parent acb31f36
Loading
Loading
Loading
Loading
+31 −25
Original line number Diff line number Diff line
@@ -278,9 +278,36 @@ class MediaPlayerWrapper {
        d("Controller for " + mPackageName + " was updated.");
    }

    private void sendMediaUpdate() {
        MediaData newData = new MediaData(
                Util.toMetadata(getMetadata()),
                getPlaybackState(),
                Util.toMetadataList(getQueue()));

        if (newData.equals(mCurrentData)) {
            // This may happen if the controller is fully synced by the time the
            // first update is completed
            Log.v(TAG, "Trying to update with last sent metadata");
            return;
        }

        synchronized (mCallbackLock) {
            if (mRegisteredCallback == null) {
                Log.e(TAG, mPackageName
                        + "Trying to send an update with no registered callback");
                return;
            }

            Log.v(TAG, "trySendMediaUpdate(): Metadata has been updated for " + mPackageName);
            mRegisteredCallback.mediaUpdatedCallback(newData);
        }

        mCurrentData = newData;
    }

    class TimeoutHandler extends Handler {
        private static final int MSG_TIMEOUT = 0;
        private static final long CALLBACK_TIMEOUT_MS = 1000;
        private static final long CALLBACK_TIMEOUT_MS = 2000;

        TimeoutHandler(Looper looper) {
            super(looper);
@@ -301,6 +328,8 @@ class MediaPlayerWrapper {
                Log.e(TAG, "  └ QueueItem(" + i + "): " + current_queue.get(i));
            }

            sendMediaUpdate();

            // TODO(apanicke): Add metric collection here.

            if (sTesting) Log.wtfStack(TAG, "Crashing the stack");
@@ -342,30 +371,7 @@ class MediaPlayerWrapper {
                }
            }

            MediaData newData = new MediaData(
                    Util.toMetadata(getMetadata()),
                    getPlaybackState(),
                    Util.toMetadataList(getQueue()));

            if (newData.equals(mCurrentData)) {
                // This may happen if the controller is fully synced by the time the
                // first update is completed
                Log.v(TAG, "Trying to update with last sent metadata");
                return;
            }

            synchronized (mCallbackLock) {
                if (mRegisteredCallback == null) {
                    Log.e(TAG, mPackageName
                            + "Trying to send an update with no registered callback");
                    return;
                }

                Log.v(TAG, "trySendMediaUpdate(): Metadata has been updated for " + mPackageName);
                mRegisteredCallback.mediaUpdatedCallback(newData);
            }

            mCurrentData = newData;
            sendMediaUpdate();
        }

        @Override
+17 −1
Original line number Diff line number Diff line
@@ -562,7 +562,7 @@ public class MediaPlayerWrapperTest {
        verify(mMockController).registerCallback(mControllerCbs.capture(), any());
        MediaController.Callback controllerCallbacks = mControllerCbs.getValue();

        // Update Metdata returned by controller
        // Update Metadata returned by controller
        mTestMetadata.putString(MediaMetadata.METADATA_KEY_TITLE, "Mismatch Title");
        doReturn(mTestMetadata.build()).when(mMockController).getMetadata();
        controllerCallbacks.onMetadataChanged(mTestMetadata.build());
@@ -572,6 +572,22 @@ public class MediaPlayerWrapperTest {

        // Assert that there was a timeout
        verify(mFailHandler).onTerribleFailure(any(), any(), anyBoolean());

        // Assert that the callback was called with the mismatch data
        verify(mTestCbs, times(1)).mediaUpdatedCallback(mMediaUpdateData.capture());
        MediaData data = mMediaUpdateData.getValue();
        Assert.assertEquals(
                "Returned Metadata isn't equal to given Metadata",
                data.metadata,
                Util.toMetadata(mTestMetadata.build()));
        Assert.assertEquals(
                "Returned PlaybackState isn't equal to given PlaybackState",
                data.state.toString(),
                mTestState.build().toString());
        Assert.assertEquals(
                "Returned Queue isn't equal to given Queue",
                data.queue,
                Util.toMetadataList(getQueueFromDescriptions(mTestQueue)));
    }

    /*