summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Caitlin Cassidy <ccassidy@google.com> 2022-05-03 21:27:00 +0000
committer Caitlin Cassidy <ccassidy@google.com> 2022-05-06 14:04:28 +0000
commit3a5d2ebeb9ced1527db2f1645f306957a58522f7 (patch)
tree29d93cadbe079755c73aba89930e2dcbf12eb4c3
parent4c0c32d03c2867b6bbf8a786c61c05a7cbb5c541 (diff)
[Media] Add a MediaController.Callback that will disconnect us when
onSessionDestroyed is triggered. Bug: 225403871 Test: ResumeMediaBrowserTest Change-Id: I2626a6af7d09f12184b2dda88b28838b51a247c6
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/ResumeMediaBrowser.java50
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/ResumeMediaBrowserLogger.kt21
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/ResumeMediaBrowserTest.kt51
3 files changed, 119 insertions, 3 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/media/ResumeMediaBrowser.java b/packages/SystemUI/src/com/android/systemui/media/ResumeMediaBrowser.java
index 4f598ff797d0..40a5653a15a0 100644
--- a/packages/SystemUI/src/com/android/systemui/media/ResumeMediaBrowser.java
+++ b/packages/SystemUI/src/com/android/systemui/media/ResumeMediaBrowser.java
@@ -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();
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/ResumeMediaBrowserLogger.kt b/packages/SystemUI/src/com/android/systemui/media/ResumeMediaBrowserLogger.kt
index ccc5edc1123a..41f735486c7e 100644
--- a/packages/SystemUI/src/com/android/systemui/media/ResumeMediaBrowserLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/ResumeMediaBrowserLogger.kt
@@ -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"
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/ResumeMediaBrowserTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/ResumeMediaBrowserTest.kt
index a07447521ab8..dafaa6b93696 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/ResumeMediaBrowserTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/ResumeMediaBrowserTest.kt
@@ -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,
@@ -137,6 +140,22 @@ public class ResumeMediaBrowserTest : SysuiTestCase() {
}
@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>()
whenever(browserFactory.create(any(), any(), any())).thenReturn(oldBrowser)
@@ -188,6 +207,22 @@ public class ResumeMediaBrowserTest : SysuiTestCase() {
}
@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>()
whenever(browserFactory.create(any(), any(), any())).thenReturn(oldBrowser)
@@ -261,6 +296,22 @@ public class ResumeMediaBrowserTest : SysuiTestCase() {
}
@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>()
whenever(browserFactory.create(any(), any(), any())).thenReturn(oldBrowser)