Only filter when remote session has associated notification
Bug: 167706409
Test: manual - Cast from Google Play Books and check that media controls
are available in QS.
Change-Id: Ifc404be2de6f5f87a1d43e3b51d3ca00c73c6e06
(cherry picked from commit 8cc72bdf3a)
Merged-In: Ifc404be2de6f5f87a1d43e3b51d3ca00c73c6e06
This commit is contained in:
@@ -52,9 +52,12 @@ class MediaSessionBasedFilter @Inject constructor(
|
||||
private val packageControllers: LinkedHashMap<String, MutableList<MediaController>> =
|
||||
LinkedHashMap()
|
||||
|
||||
// Keep track of the key used for the session tokens. This information is used to know when
|
||||
// Keep track of the key used for the session tokens. This information is used to know when to
|
||||
// dispatch a removed event so that a media object for a local session will be removed.
|
||||
private val keyedTokens: MutableMap<String, MutableList<MediaSession.Token>> = mutableMapOf()
|
||||
private val keyedTokens: MutableMap<String, MutableSet<MediaSession.Token>> = mutableMapOf()
|
||||
|
||||
// Keep track of which media session tokens have associated notifications.
|
||||
private val tokensWithNotifications: MutableSet<MediaSession.Token> = mutableSetOf()
|
||||
|
||||
private val sessionListener = object : MediaSessionManager.OnActiveSessionsChangedListener {
|
||||
override fun onActiveSessionsChanged(controllers: List<MediaController>) {
|
||||
@@ -90,6 +93,9 @@ class MediaSessionBasedFilter @Inject constructor(
|
||||
*/
|
||||
override fun onMediaDataLoaded(key: String, oldKey: String?, info: MediaData) {
|
||||
backgroundExecutor.execute {
|
||||
info.token?.let {
|
||||
tokensWithNotifications.add(it)
|
||||
}
|
||||
val isMigration = oldKey != null && key != oldKey
|
||||
if (isMigration) {
|
||||
keyedTokens.remove(oldKey)?.let { removed -> keyedTokens.put(key, removed) }
|
||||
@@ -99,7 +105,7 @@ class MediaSessionBasedFilter @Inject constructor(
|
||||
tokens ->
|
||||
tokens.add(info.token)
|
||||
} ?: run {
|
||||
val tokens = mutableListOf(info.token)
|
||||
val tokens = mutableSetOf(info.token)
|
||||
keyedTokens.put(key, tokens)
|
||||
}
|
||||
}
|
||||
@@ -110,7 +116,8 @@ class MediaSessionBasedFilter @Inject constructor(
|
||||
}
|
||||
// Limiting search to only apps with a single remote session.
|
||||
val remote = if (remoteControllers?.size == 1) remoteControllers.firstOrNull() else null
|
||||
if (isMigration || remote == null || remote.sessionToken == info.token) {
|
||||
if (isMigration || remote == null || remote.sessionToken == info.token ||
|
||||
!tokensWithNotifications.contains(remote.sessionToken)) {
|
||||
// Not filtering in this case. Passing the event along to listeners.
|
||||
dispatchMediaDataLoaded(key, oldKey, info)
|
||||
} else {
|
||||
@@ -159,5 +166,6 @@ class MediaSessionBasedFilter @Inject constructor(
|
||||
packageControllers.put(controller.packageName, tokens)
|
||||
}
|
||||
}
|
||||
tokensWithNotifications.retainAll(controllers.map { it.sessionToken })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -225,7 +225,7 @@ public class MediaSessionBasedFilterTest : SysuiTestCase() {
|
||||
|
||||
@Test
|
||||
fun remoteSession_loadedEventNotFiltered() {
|
||||
// GIVEN a remove session
|
||||
// GIVEN a remote session
|
||||
whenever(controller1.getPlaybackInfo()).thenReturn(remotePlaybackInfo)
|
||||
val controllers = listOf(controller1)
|
||||
whenever(mediaSessionManager.getActiveSessions(any())).thenReturn(controllers)
|
||||
@@ -259,6 +259,22 @@ public class MediaSessionBasedFilterTest : SysuiTestCase() {
|
||||
verify(mediaListener, never()).onMediaDataLoaded(eq(KEY), eq(null), eq(mediaData2))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun remoteAndLocalSessions_remoteSessionWithoutNotification() {
|
||||
// GIVEN remote and local sessions
|
||||
whenever(controller2.getPlaybackInfo()).thenReturn(remotePlaybackInfo)
|
||||
val controllers = listOf(controller1, controller2)
|
||||
whenever(mediaSessionManager.getActiveSessions(any())).thenReturn(controllers)
|
||||
sessionListener.onActiveSessionsChanged(controllers)
|
||||
// WHEN a loaded event is received that matches the local session
|
||||
filter.onMediaDataLoaded(KEY, null, mediaData1)
|
||||
bgExecutor.runAllReady()
|
||||
fgExecutor.runAllReady()
|
||||
// THEN the event is not filtered because there isn't a notification for the remote
|
||||
// session.
|
||||
verify(mediaListener).onMediaDataLoaded(eq(KEY), eq(null), eq(mediaData1))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun remoteAndLocalHaveDifferentKeys_localLoadedEventFiltered() {
|
||||
// GIVEN remote and local sessions
|
||||
@@ -284,6 +300,29 @@ public class MediaSessionBasedFilterTest : SysuiTestCase() {
|
||||
verify(mediaListener).onMediaDataRemoved(eq(key2))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun remoteAndLocalHaveDifferentKeys_remoteSessionWithoutNotification() {
|
||||
// GIVEN remote and local sessions
|
||||
val key1 = "KEY_1"
|
||||
val key2 = "KEY_2"
|
||||
whenever(controller2.getPlaybackInfo()).thenReturn(remotePlaybackInfo)
|
||||
val controllers = listOf(controller1, controller2)
|
||||
whenever(mediaSessionManager.getActiveSessions(any())).thenReturn(controllers)
|
||||
sessionListener.onActiveSessionsChanged(controllers)
|
||||
// WHEN a loaded event is received that matches the local session
|
||||
filter.onMediaDataLoaded(key1, null, mediaData1)
|
||||
bgExecutor.runAllReady()
|
||||
fgExecutor.runAllReady()
|
||||
// THEN the event is not filtered
|
||||
verify(mediaListener).onMediaDataLoaded(eq(key1), eq(null), eq(mediaData1))
|
||||
// WHEN a loaded event is received that matches the remote session
|
||||
filter.onMediaDataLoaded(key2, null, mediaData2)
|
||||
bgExecutor.runAllReady()
|
||||
fgExecutor.runAllReady()
|
||||
// THEN the event is not filtered
|
||||
verify(mediaListener).onMediaDataLoaded(eq(key2), eq(null), eq(mediaData2))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun multipleRemoteSessions_loadedEventNotFiltered() {
|
||||
// GIVEN two remote sessions
|
||||
|
||||
Reference in New Issue
Block a user