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

Commit 74606dde authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Only filter when remote session has associated notification" into rvc-qpr-dev am: c6095a41

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

Change-Id: Ic6e4a3d164bbe0e4585f8e74f863057034fb76f2
parents 64fda3af c6095a41
Loading
Loading
Loading
Loading
+12 −4
Original line number Original line Diff line number Diff line
@@ -52,9 +52,12 @@ class MediaSessionBasedFilter @Inject constructor(
    private val packageControllers: LinkedHashMap<String, MutableList<MediaController>> =
    private val packageControllers: LinkedHashMap<String, MutableList<MediaController>> =
            LinkedHashMap()
            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.
    // 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 {
    private val sessionListener = object : MediaSessionManager.OnActiveSessionsChangedListener {
        override fun onActiveSessionsChanged(controllers: List<MediaController>) {
        override fun onActiveSessionsChanged(controllers: List<MediaController>) {
@@ -90,6 +93,9 @@ class MediaSessionBasedFilter @Inject constructor(
     */
     */
    override fun onMediaDataLoaded(key: String, oldKey: String?, info: MediaData) {
    override fun onMediaDataLoaded(key: String, oldKey: String?, info: MediaData) {
        backgroundExecutor.execute {
        backgroundExecutor.execute {
            info.token?.let {
                tokensWithNotifications.add(it)
            }
            val isMigration = oldKey != null && key != oldKey
            val isMigration = oldKey != null && key != oldKey
            if (isMigration) {
            if (isMigration) {
                keyedTokens.remove(oldKey)?.let { removed -> keyedTokens.put(key, removed) }
                keyedTokens.remove(oldKey)?.let { removed -> keyedTokens.put(key, removed) }
@@ -99,7 +105,7 @@ class MediaSessionBasedFilter @Inject constructor(
                    tokens ->
                    tokens ->
                    tokens.add(info.token)
                    tokens.add(info.token)
                } ?: run {
                } ?: run {
                    val tokens = mutableListOf(info.token)
                    val tokens = mutableSetOf(info.token)
                    keyedTokens.put(key, tokens)
                    keyedTokens.put(key, tokens)
                }
                }
            }
            }
@@ -110,7 +116,8 @@ class MediaSessionBasedFilter @Inject constructor(
            }
            }
            // Limiting search to only apps with a single remote session.
            // Limiting search to only apps with a single remote session.
            val remote = if (remoteControllers?.size == 1) remoteControllers.firstOrNull() else null
            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.
                // Not filtering in this case. Passing the event along to listeners.
                dispatchMediaDataLoaded(key, oldKey, info)
                dispatchMediaDataLoaded(key, oldKey, info)
            } else {
            } else {
@@ -159,5 +166,6 @@ class MediaSessionBasedFilter @Inject constructor(
                packageControllers.put(controller.packageName, tokens)
                packageControllers.put(controller.packageName, tokens)
            }
            }
        }
        }
        tokensWithNotifications.retainAll(controllers.map { it.sessionToken })
    }
    }
}
}
+40 −1
Original line number Original line Diff line number Diff line
@@ -225,7 +225,7 @@ public class MediaSessionBasedFilterTest : SysuiTestCase() {


    @Test
    @Test
    fun remoteSession_loadedEventNotFiltered() {
    fun remoteSession_loadedEventNotFiltered() {
        // GIVEN a remove session
        // GIVEN a remote session
        whenever(controller1.getPlaybackInfo()).thenReturn(remotePlaybackInfo)
        whenever(controller1.getPlaybackInfo()).thenReturn(remotePlaybackInfo)
        val controllers = listOf(controller1)
        val controllers = listOf(controller1)
        whenever(mediaSessionManager.getActiveSessions(any())).thenReturn(controllers)
        whenever(mediaSessionManager.getActiveSessions(any())).thenReturn(controllers)
@@ -259,6 +259,22 @@ public class MediaSessionBasedFilterTest : SysuiTestCase() {
        verify(mediaListener, never()).onMediaDataLoaded(eq(KEY), eq(null), eq(mediaData2))
        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
    @Test
    fun remoteAndLocalHaveDifferentKeys_localLoadedEventFiltered() {
    fun remoteAndLocalHaveDifferentKeys_localLoadedEventFiltered() {
        // GIVEN remote and local sessions
        // GIVEN remote and local sessions
@@ -284,6 +300,29 @@ public class MediaSessionBasedFilterTest : SysuiTestCase() {
        verify(mediaListener).onMediaDataRemoved(eq(key2))
        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
    @Test
    fun multipleRemoteSessions_loadedEventNotFiltered() {
    fun multipleRemoteSessions_loadedEventNotFiltered() {
        // GIVEN two remote sessions
        // GIVEN two remote sessions