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

Commit 1125a000 authored by Automerger Merge Worker's avatar Automerger Merge Worker Committed by Android (Google) Code Review
Browse files

Merge "Merge "Fix resumable session players" into tm-qpr-dev am: 9b204ac5...

Merge "Merge "Fix resumable session players" into tm-qpr-dev am: 9b204ac5 am: 46555d7f" into udc-dev
parents 0b2aa295 5bcbf73f
Loading
Loading
Loading
Loading
+12 −7
Original line number Diff line number Diff line
@@ -1346,13 +1346,9 @@ class MediaDataManager(
    fun onNotificationRemoved(key: String) {
        Assert.isMainThread()
        val removed = mediaEntries.remove(key) ?: return
        val isEligibleForResume =
            removed.isLocalSession() ||
                (mediaFlags.isRemoteResumeAllowed() &&
                    removed.playbackLocation != MediaData.PLAYBACK_CAST_REMOTE)
        if (keyguardUpdateMonitor.isUserInLockdown(removed.userId)) {
            logger.logMediaRemoved(removed.appUid, removed.packageName, removed.instanceId)
        } else if (useMediaResumption && removed.resumeAction != null && isEligibleForResume) {
        } else if (isAbleToResume(removed)) {
            convertToResumePlayer(key, removed)
        } else if (mediaFlags.isRetainingPlayersEnabled()) {
            handlePossibleRemoval(key, removed, notificationRemoved = true)
@@ -1372,6 +1368,14 @@ class MediaDataManager(
        handlePossibleRemoval(key, updated)
    }

    private fun isAbleToResume(data: MediaData): Boolean {
        val isEligibleForResume =
            data.isLocalSession() ||
                (mediaFlags.isRemoteResumeAllowed() &&
                    data.playbackLocation != MediaData.PLAYBACK_CAST_REMOTE)
        return useMediaResumption && data.resumeAction != null && isEligibleForResume
    }

    /**
     * Convert to resume state if the player is no longer valid and active, then notify listeners
     * that the data was updated. Does not convert to resume state if the player is still valid, or
@@ -1394,8 +1398,9 @@ class MediaDataManager(
            if (DEBUG) Log.d(TAG, "Session destroyed but using notification actions $key")
            mediaEntries.put(key, removed)
            notifyMediaDataLoaded(key, key, removed)
        } else if (removed.active) {
            // This player was still active - it didn't last long enough to time out: remove
        } else if (removed.active && !isAbleToResume(removed)) {
            // This player was still active - it didn't last long enough to time out,
            // and its app doesn't normally support resume: remove
            if (DEBUG) Log.d(TAG, "Removing still-active player $key")
            notifyMediaDataRemoved(key)
            logger.logMediaRemoved(removed.appUid, removed.packageName, removed.instanceId)
+35 −1
Original line number Diff line number Diff line
@@ -2031,7 +2031,7 @@ class MediaDataManagerTest : SysuiTestCase() {
    }

    @Test
    fun testRetain_sessionPlayer_destroyedWhileActive_fullyRemoved() {
    fun testRetain_sessionPlayer_destroyedWhileActive_noResume_fullyRemoved() {
        whenever(mediaFlags.isRetainingPlayersEnabled()).thenReturn(true)
        whenever(mediaFlags.areMediaSessionActionsEnabled(any(), any())).thenReturn(true)
        addPlaybackStateAction()
@@ -2050,6 +2050,40 @@ class MediaDataManagerTest : SysuiTestCase() {
            .onMediaDataLoaded(eq(PACKAGE_NAME), any(), any(), anyBoolean(), anyInt(), anyBoolean())
    }

    @Test
    fun testRetain_sessionPlayer_canResume_destroyedWhileActive_setToResume() {
        whenever(mediaFlags.isRetainingPlayersEnabled()).thenReturn(true)
        whenever(mediaFlags.areMediaSessionActionsEnabled(any(), any())).thenReturn(true)
        addPlaybackStateAction()

        // When a media control using session actions and that does allow resumption is added,
        addNotificationAndLoad()
        val dataResumable = mediaDataCaptor.value.copy(resumeAction = Runnable {})
        mediaDataManager.onMediaDataLoaded(KEY, null, dataResumable)

        // And then the session is destroyed without timing out first
        sessionCallbackCaptor.value.invoke(KEY)

        // It is converted to a resume player
        verify(listener)
            .onMediaDataLoaded(
                eq(PACKAGE_NAME),
                eq(KEY),
                capture(mediaDataCaptor),
                eq(true),
                eq(0),
                eq(false)
            )
        assertThat(mediaDataCaptor.value.resumption).isTrue()
        assertThat(mediaDataCaptor.value.active).isFalse()
        verify(logger)
            .logActiveConvertedToResume(
                anyInt(),
                eq(PACKAGE_NAME),
                eq(mediaDataCaptor.value.instanceId)
            )
    }

    @Test
    fun testSessionDestroyed_noNotificationKey_stillRemoved() {
        whenever(mediaFlags.isRetainingPlayersEnabled()).thenReturn(true)