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

Commit cc56edb2 authored by Caitlin Cassidy's avatar Caitlin Cassidy Committed by Automerger Merge Worker
Browse files

Merge "[Media] Add a MediaController.Callback that will disconnect us when...

Merge "[Media] Add a MediaController.Callback that will disconnect us when onSessionDestroyed is triggered." into tm-dev am: 254bb547 am: ea2abe5a

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/18143686



Change-Id: Ia652cf0e20004ef9b73ab80927ea6207a206da0e
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents 7f5ae374 ea2abe5a
Loading
Loading
Loading
Loading
+47 −3
Original line number Diff line number Diff line
@@ -52,8 +52,10 @@ public class ResumeMediaBrowser {
    private final MediaBrowserFactory mBrowserFactory;
    private final ResumeMediaBrowserLogger mLogger;
    private final ComponentName mComponentName;
    private final MediaController.Callback mMediaControllerCallback = new SessionDestroyCallback();

    private MediaBrowser mMediaBrowser;
    @Nullable private MediaController mMediaController;

    /**
     * Initialize a new media browser
@@ -90,6 +92,7 @@ public class ResumeMediaBrowser {
                mComponentName,
                mConnectionCallback,
                rootHints);
        updateMediaController();
        mLogger.logConnection(mComponentName, "findRecentMedia");
        mMediaBrowser.connect();
    }
@@ -154,7 +157,8 @@ public class ResumeMediaBrowser {
        @Override
        public void onConnected() {
            Log.d(TAG, "Service connected for " + mComponentName);
            if (mMediaBrowser != null && mMediaBrowser.isConnected()) {
            updateMediaController();
            if (isBrowserConnected()) {
                String root = mMediaBrowser.getRoot();
                if (!TextUtils.isEmpty(root)) {
                    if (mCallback != null) {
@@ -207,6 +211,7 @@ public class ResumeMediaBrowser {
            mMediaBrowser.disconnect();
        }
        mMediaBrowser = null;
        updateMediaController();
    }

    /**
@@ -225,7 +230,8 @@ public class ResumeMediaBrowser {
                    @Override
                    public void onConnected() {
                        Log.d(TAG, "Connected for restart " + mMediaBrowser.isConnected());
                        if (mMediaBrowser == null || !mMediaBrowser.isConnected()) {
                        updateMediaController();
                        if (!isBrowserConnected()) {
                            if (mCallback != null) {
                                mCallback.onError();
                            }
@@ -259,6 +265,7 @@ public class ResumeMediaBrowser {
                        disconnect();
                    }
                }, rootHints);
        updateMediaController();
        mLogger.logConnection(mComponentName, "restart");
        mMediaBrowser.connect();
    }
@@ -273,7 +280,7 @@ public class ResumeMediaBrowser {
     * @return the token, or null if the MediaBrowser is null or disconnected
     */
    public MediaSession.Token getToken() {
        if (mMediaBrowser == null || !mMediaBrowser.isConnected()) {
        if (!isBrowserConnected()) {
            return null;
        }
        return mMediaBrowser.getSessionToken();
@@ -305,10 +312,39 @@ public class ResumeMediaBrowser {
                mComponentName,
                mConnectionCallback,
                rootHints);
        updateMediaController();
        mLogger.logConnection(mComponentName, "testConnection");
        mMediaBrowser.connect();
    }

    /** Updates mMediaController based on our current browser values. */
    private void updateMediaController() {
        MediaSession.Token controllerToken =
                mMediaController != null ? mMediaController.getSessionToken() : null;
        MediaSession.Token currentToken = getToken();
        boolean areEqual = (controllerToken == null && currentToken == null)
                || (controllerToken != null && controllerToken.equals(currentToken));
        if (areEqual) {
            return;
        }

        // Whenever the token changes, un-register the callback on the old controller (if we have
        // one) and create a new controller with the callback attached.
        if (mMediaController != null) {
            mMediaController.unregisterCallback(mMediaControllerCallback);
        }
        if (currentToken != null) {
            mMediaController = createMediaController(currentToken);
            mMediaController.registerCallback(mMediaControllerCallback);
        } else {
            mMediaController = null;
        }
    }

    private boolean isBrowserConnected() {
        return mMediaBrowser != null && mMediaBrowser.isConnected();
    }

    /**
     * Interface to handle results from ResumeMediaBrowser
     */
@@ -335,4 +371,12 @@ public class ResumeMediaBrowser {
                ResumeMediaBrowser browser) {
        }
    }

    private class SessionDestroyCallback extends MediaController.Callback {
        @Override
        public void onSessionDestroyed() {
            mLogger.logSessionDestroyed(isBrowserConnected(), mComponentName);
            disconnect();
        }
    }
}
+21 −0
Original line number Diff line number Diff line
@@ -48,6 +48,27 @@ class ResumeMediaBrowserLogger @Inject constructor(
        },
        { "Disconnecting browser for component $str1" }
    )

    /**
     * Logs that we received a [android.media.session.MediaController.Callback.onSessionDestroyed]
     * event.
     *
     * @param isBrowserConnected true if there's a currently connected
     *     [android.media.browse.MediaBrowser] and false otherwise.
     * @param componentName the component name for the [ResumeMediaBrowser] that triggered this log.
     */
    fun logSessionDestroyed(
        isBrowserConnected: Boolean,
        componentName: ComponentName
    ) = buffer.log(
        TAG,
        LogLevel.DEBUG,
        {
            bool1 = isBrowserConnected
            str1 = componentName.toShortString()
        },
        { "Session destroyed. Active browser = $bool1. Browser component = $str1." }
    )
}

private const val TAG = "MediaBrowser"
+51 −0
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ import org.mockito.ArgumentCaptor
import org.mockito.Captor
import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.Mockito.reset
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
import org.mockito.Mockito.`when` as whenever
@@ -73,6 +74,7 @@ public class ResumeMediaBrowserTest : SysuiTestCase() {

    @Captor lateinit var connectionCallback: ArgumentCaptor<MediaBrowser.ConnectionCallback>
    @Captor lateinit var subscriptionCallback: ArgumentCaptor<MediaBrowser.SubscriptionCallback>
    @Captor lateinit var mediaControllerCallback: ArgumentCaptor<MediaController.Callback>

    @Before
    fun setUp() {
@@ -82,6 +84,7 @@ public class ResumeMediaBrowserTest : SysuiTestCase() {
                .thenReturn(browser)

        whenever(mediaController.transportControls).thenReturn(transportControls)
        whenever(mediaController.sessionToken).thenReturn(token)

        resumeBrowser = TestableResumeMediaBrowser(
            context,
@@ -136,6 +139,22 @@ public class ResumeMediaBrowserTest : SysuiTestCase() {
        verify(callback).addTrack(eq(description), eq(component), eq(resumeBrowser))
    }

    @Test
    fun testConnection_thenSessionDestroyed_disconnects() {
        // When testConnection is called and we connect successfully
        setupBrowserConnection()
        resumeBrowser.testConnection()
        verify(mediaController).registerCallback(mediaControllerCallback.capture())
        reset(browser)

        // And a sessionDestroyed event is triggered
        mediaControllerCallback.value.onSessionDestroyed()

        // Then we disconnect the browser and unregister the callback
        verify(browser).disconnect()
        verify(mediaController).unregisterCallback(mediaControllerCallback.value)
    }

    @Test
    fun testConnection_calledTwice_oldBrowserDisconnected() {
        val oldBrowser = mock<MediaBrowser>()
@@ -187,6 +206,22 @@ public class ResumeMediaBrowserTest : SysuiTestCase() {
        verify(callback).onConnected()
    }

    @Test
    fun testFindRecentMedia_thenSessionDestroyed_disconnects() {
        // When findRecentMedia is called and we connect successfully
        setupBrowserConnection()
        resumeBrowser.findRecentMedia()
        verify(mediaController).registerCallback(mediaControllerCallback.capture())
        reset(browser)

        // And a sessionDestroyed event is triggered
        mediaControllerCallback.value.onSessionDestroyed()

        // Then we disconnect the browser and unregister the callback
        verify(browser).disconnect()
        verify(mediaController).unregisterCallback(mediaControllerCallback.value)
    }

    @Test
    fun testFindRecentMedia_calledTwice_oldBrowserDisconnected() {
        val oldBrowser = mock<MediaBrowser>()
@@ -260,6 +295,22 @@ public class ResumeMediaBrowserTest : SysuiTestCase() {
        verify(transportControls).play()
    }

    @Test
    fun testRestart_thenSessionDestroyed_disconnects() {
        // When restart is called and we connect successfully
        setupBrowserConnection()
        resumeBrowser.restart()
        verify(mediaController).registerCallback(mediaControllerCallback.capture())
        reset(browser)

        // And a sessionDestroyed event is triggered
        mediaControllerCallback.value.onSessionDestroyed()

        // Then we disconnect the browser and unregister the callback
        verify(browser).disconnect()
        verify(mediaController).unregisterCallback(mediaControllerCallback.value)
    }

    @Test
    fun testRestart_calledTwice_oldBrowserDisconnected() {
        val oldBrowser = mock<MediaBrowser>()