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

Commit b8b7a230 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Check for flag to trigger resume" into tm-qpr-dev

parents d1c60d2f 84f040a1
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -88,6 +88,8 @@ data class SmartspaceMediaData(
    }
}

/** Key to indicate whether this card should be used to re-show recent media */
const val EXTRA_KEY_TRIGGER_RESUME = "SHOULD_TRIGGER_RESUME"
/** Key for extras [SmartspaceMediaData.cardAction] indicating why the card was sent */
const val EXTRA_KEY_TRIGGER_SOURCE = "MEDIA_RECOMMENDATION_TRIGGER_SOURCE"
/** Value for [EXTRA_KEY_TRIGGER_SOURCE] when the card is sent on headphone connection */
+13 −3
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import com.android.internal.annotations.VisibleForTesting
import com.android.systemui.broadcast.BroadcastSender
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.media.controls.models.player.MediaData
import com.android.systemui.media.controls.models.recommendation.EXTRA_KEY_TRIGGER_RESUME
import com.android.systemui.media.controls.models.recommendation.SmartspaceMediaData
import com.android.systemui.media.controls.util.MediaFlags
import com.android.systemui.media.controls.util.MediaUiEventLogger
@@ -138,14 +139,23 @@ constructor(
        val sorted = userEntries.toSortedMap(compareBy { userEntries.get(it)?.lastActive ?: -1 })
        val timeSinceActive = timeSinceActiveForMostRecentMedia(sorted)
        var smartspaceMaxAgeMillis = SMARTSPACE_MAX_AGE
        data.cardAction?.let {
            val smartspaceMaxAgeSeconds = it.extras.getLong(RESUMABLE_MEDIA_MAX_AGE_SECONDS_KEY, 0)
        data.cardAction?.extras?.let {
            val smartspaceMaxAgeSeconds = it.getLong(RESUMABLE_MEDIA_MAX_AGE_SECONDS_KEY, 0)
            if (smartspaceMaxAgeSeconds > 0) {
                smartspaceMaxAgeMillis = TimeUnit.SECONDS.toMillis(smartspaceMaxAgeSeconds)
            }
        }

        val shouldReactivate = !hasActiveMedia() && hasAnyMedia() && data.isActive
        // Check if smartspace has explicitly specified whether to re-activate resumable media.
        // The default behavior is to trigger if the smartspace data is active.
        val shouldTriggerResume =
            if (data.cardAction?.extras?.containsKey(EXTRA_KEY_TRIGGER_RESUME) == true) {
                data.cardAction.extras.getBoolean(EXTRA_KEY_TRIGGER_RESUME, true)
            } else {
                true
            }
        val shouldReactivate =
            shouldTriggerResume && !hasActiveMedia() && hasAnyMedia() && data.isActive

        if (timeSinceActive < smartspaceMaxAgeMillis) {
            // It could happen there are existing active media resume cards, then we don't need to
+55 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.systemui.media.controls.pipeline

import android.app.smartspace.SmartspaceAction
import android.os.Bundle
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import androidx.test.filters.SmallTest
@@ -25,6 +26,7 @@ import com.android.systemui.SysuiTestCase
import com.android.systemui.broadcast.BroadcastSender
import com.android.systemui.media.controls.MediaTestUtils
import com.android.systemui.media.controls.models.player.MediaData
import com.android.systemui.media.controls.models.recommendation.EXTRA_KEY_TRIGGER_RESUME
import com.android.systemui.media.controls.models.recommendation.SmartspaceMediaData
import com.android.systemui.media.controls.ui.MediaPlayerData
import com.android.systemui.media.controls.util.MediaFlags
@@ -75,6 +77,7 @@ class MediaDataFilterTest : SysuiTestCase() {
    @Mock private lateinit var smartspaceMediaRecommendationItem: SmartspaceAction
    @Mock private lateinit var logger: MediaUiEventLogger
    @Mock private lateinit var mediaFlags: MediaFlags
    @Mock private lateinit var cardAction: SmartspaceAction

    private lateinit var mediaDataFilter: MediaDataFilter
    private lateinit var dataMain: MediaData
@@ -122,6 +125,7 @@ class MediaDataFilterTest : SysuiTestCase() {
        whenever(smartspaceData.headphoneConnectionTimeMillis)
            .thenReturn(clock.currentTimeMillis() - 100)
        whenever(smartspaceData.instanceId).thenReturn(SMARTSPACE_INSTANCE_ID)
        whenever(smartspaceData.cardAction).thenReturn(cardAction)
    }

    private fun setUser(id: Int) {
@@ -574,4 +578,55 @@ class MediaDataFilterTest : SysuiTestCase() {
        verify(mediaDataManager, never())
            .dismissSmartspaceRecommendation(eq(SMARTSPACE_KEY), anyLong())
    }

    @Test
    fun testSmartspaceLoaded_shouldTriggerResume_doesTrigger() {
        // WHEN we have media that was recently played, but not currently active
        val dataCurrent = dataMain.copy(active = false, lastActive = clock.elapsedRealtime())
        mediaDataFilter.onMediaDataLoaded(KEY, null, dataCurrent)
        verify(listener)
            .onMediaDataLoaded(eq(KEY), eq(null), eq(dataCurrent), eq(true), eq(0), eq(false))

        // AND we get a smartspace signal with extra to trigger resume
        val extras = Bundle().apply { putBoolean(EXTRA_KEY_TRIGGER_RESUME, true) }
        whenever(cardAction.extras).thenReturn(extras)
        mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)

        // THEN we should tell listeners to treat the media as active instead
        val dataCurrentAndActive = dataCurrent.copy(active = true)
        verify(listener)
            .onMediaDataLoaded(
                eq(KEY),
                eq(KEY),
                eq(dataCurrentAndActive),
                eq(true),
                eq(100),
                eq(true)
            )
        assertThat(mediaDataFilter.hasActiveMediaOrRecommendation()).isTrue()
        // And send the smartspace data, but not prioritized
        verify(listener)
            .onSmartspaceMediaDataLoaded(eq(SMARTSPACE_KEY), eq(smartspaceData), eq(false))
    }

    @Test
    fun testSmartspaceLoaded_notShouldTriggerResume_doesNotTrigger() {
        // WHEN we have media that was recently played, but not currently active
        val dataCurrent = dataMain.copy(active = false, lastActive = clock.elapsedRealtime())
        mediaDataFilter.onMediaDataLoaded(KEY, null, dataCurrent)
        verify(listener)
            .onMediaDataLoaded(eq(KEY), eq(null), eq(dataCurrent), eq(true), eq(0), eq(false))

        // AND we get a smartspace signal with extra to not trigger resume
        val extras = Bundle().apply { putBoolean(EXTRA_KEY_TRIGGER_RESUME, false) }
        whenever(cardAction.extras).thenReturn(extras)
        mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)

        // THEN listeners are not updated to show media
        verify(listener, never())
            .onMediaDataLoaded(eq(KEY), eq(KEY), any(), eq(true), eq(100), eq(true))
        // But the smartspace update is still propagated
        verify(listener)
            .onSmartspaceMediaDataLoaded(eq(SMARTSPACE_KEY), eq(smartspaceData), eq(false))
    }
}