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

Commit 0d758934 authored by Michael Mikhail's avatar Michael Mikhail Committed by Android (Google) Code Review
Browse files

Merge "Handle reordering when recommendation clicked." into main

parents 74a64c1f d74e08af
Loading
Loading
Loading
Loading
+30 −0
Original line number Diff line number Diff line
@@ -267,6 +267,35 @@ class MediaFilterRepositoryTest : SysuiTestCase() {
                .inOrder()
        }

    @Test
    fun loadMediaFromRec() =
        testScope.runTest {
            val isMediaFromRec by collectLastValue(underTest.isMediaFromRec)
            val instanceId1 = InstanceId.fakeInstanceId(123)
            val instanceId2 = InstanceId.fakeInstanceId(456)
            val data =
                MediaData(
                    active = true,
                    instanceId = instanceId1,
                    packageName = PACKAGE_NAME,
                    isPlaying = true
                )
            val newData = MediaData(active = true, instanceId = instanceId2)

            assertThat(isMediaFromRec).isFalse()

            underTest.setMediaFromRecPackageName(PACKAGE_NAME)
            underTest.addSelectedUserMediaEntry(data)
            underTest.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(instanceId1))

            assertThat(isMediaFromRec).isTrue()

            underTest.addSelectedUserMediaEntry(newData)
            underTest.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(instanceId2))

            assertThat(isMediaFromRec).isFalse()
        }

    private fun createMediaData(
        app: String,
        playing: Boolean,
@@ -288,5 +317,6 @@ class MediaFilterRepositoryTest : SysuiTestCase() {
        private const val REMOTE = MediaData.PLAYBACK_CAST_LOCAL
        private const val KEY = "KEY"
        private const val KEY_MEDIA_SMARTSPACE = "MEDIA_SMARTSPACE_ID"
        private const val PACKAGE_NAME = "com.android.example"
    }
}
+27 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.R
import android.graphics.drawable.Icon
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.internal.logging.InstanceId
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.flags.Flags
@@ -29,7 +30,9 @@ import com.android.systemui.media.controls.MediaTestHelper
import com.android.systemui.media.controls.data.repository.MediaFilterRepository
import com.android.systemui.media.controls.data.repository.mediaFilterRepository
import com.android.systemui.media.controls.domain.pipeline.interactor.MediaCarouselInteractor
import com.android.systemui.media.controls.domain.pipeline.interactor.MediaRecommendationsInteractor
import com.android.systemui.media.controls.domain.pipeline.interactor.mediaCarouselInteractor
import com.android.systemui.media.controls.domain.pipeline.interactor.mediaRecommendationsInteractor
import com.android.systemui.media.controls.shared.model.MediaCommonModel
import com.android.systemui.media.controls.shared.model.MediaData
import com.android.systemui.media.controls.shared.model.MediaDataLoadingModel
@@ -50,6 +53,8 @@ class MediaCarouselInteractorTest : SysuiTestCase() {
    private val testScope = kosmos.testScope

    private val mediaFilterRepository: MediaFilterRepository = kosmos.mediaFilterRepository
    private val mediaRecommendationsInteractor: MediaRecommendationsInteractor =
        kosmos.mediaRecommendationsInteractor

    private val underTest: MediaCarouselInteractor = kosmos.mediaCarouselInteractor

@@ -226,7 +231,29 @@ class MediaCarouselInteractorTest : SysuiTestCase() {
    fun hasActiveMediaOrRecommendation_nothingSet_returnsFalse() =
        testScope.runTest { assertThat(underTest.hasActiveMediaOrRecommendation.value).isFalse() }

    @Test
    fun loadMediaFromRec() =
        testScope.runTest {
            val isMediaFromRec by collectLastValue(underTest.isMediaFromRec)
            val instanceId = InstanceId.fakeInstanceId(123)
            val data = MediaData(active = true, instanceId = instanceId, packageName = PACKAGE_NAME)

            assertThat(isMediaFromRec).isFalse()

            mediaRecommendationsInteractor.switchToMediaControl(PACKAGE_NAME)
            mediaFilterRepository.addSelectedUserMediaEntry(data)
            mediaFilterRepository.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(instanceId))

            assertThat(isMediaFromRec).isFalse()

            mediaFilterRepository.addSelectedUserMediaEntry(data.copy(isPlaying = true))
            mediaFilterRepository.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(instanceId))

            assertThat(isMediaFromRec).isTrue()
        }

    companion object {
        private const val KEY_MEDIA_SMARTSPACE = "MEDIA_SMARTSPACE_ID"
        private const val PACKAGE_NAME = "com.android.example"
    }
}
+33 −2
Original line number Diff line number Diff line
@@ -31,9 +31,11 @@ import com.android.systemui.kosmos.testScope
import com.android.systemui.media.controls.MediaTestHelper
import com.android.systemui.media.controls.domain.pipeline.MediaDataFilterImpl
import com.android.systemui.media.controls.domain.pipeline.interactor.mediaCarouselInteractor
import com.android.systemui.media.controls.domain.pipeline.interactor.mediaRecommendationsInteractor
import com.android.systemui.media.controls.domain.pipeline.mediaDataFilter
import com.android.systemui.media.controls.shared.model.MediaData
import com.android.systemui.media.controls.shared.model.SmartspaceMediaData
import com.android.systemui.statusbar.notification.collection.provider.visualStabilityProvider
import com.android.systemui.statusbar.notificationLockscreenUserManager
import com.android.systemui.testKosmos
import com.android.systemui.util.mockito.any
@@ -119,7 +121,35 @@ class MediaCarouselViewModelTest : SysuiTestCase() {
            assertThat(recsCard.key).isEqualTo(KEY_MEDIA_SMARTSPACE)
        }

    private fun loadMediaControl(key: String, instanceId: InstanceId) {
    @Test
    fun recommendationClicked_switchToPlayer() =
        testScope.runTest {
            val sortedMedia by collectLastValue(underTest.mediaItems)
            kosmos.visualStabilityProvider.isReorderingAllowed = false
            kosmos.fakeFeatureFlagsClassic.set(Flags.MEDIA_RETAIN_RECOMMENDATIONS, false)
            val instanceId = InstanceId.fakeInstanceId(123)

            loadMediaRecommendations()
            kosmos.mediaRecommendationsInteractor.switchToMediaControl(PACKAGE_NAME)

            var recsCard = sortedMedia?.get(0) as MediaCommonViewModel.MediaRecommendations
            assertThat(sortedMedia).hasSize(1)
            assertThat(recsCard.key).isEqualTo(KEY_MEDIA_SMARTSPACE)

            loadMediaControl(KEY, instanceId, false)

            recsCard = sortedMedia?.get(0) as MediaCommonViewModel.MediaRecommendations
            assertThat(sortedMedia).hasSize(1)
            assertThat(recsCard.key).isEqualTo(KEY_MEDIA_SMARTSPACE)

            loadMediaControl(KEY, instanceId, true)

            val mediaControl = sortedMedia?.get(0) as MediaCommonViewModel.MediaControl
            assertThat(sortedMedia).hasSize(2)
            assertThat(mediaControl.instanceId).isEqualTo(instanceId)
        }

    private fun loadMediaControl(key: String, instanceId: InstanceId, isPlaying: Boolean = true) {
        whenever(notificationLockscreenUserManager.isCurrentProfile(USER_ID)).thenReturn(true)
        whenever(notificationLockscreenUserManager.isProfileAvailable(USER_ID)).thenReturn(true)
        val mediaData =
@@ -127,7 +157,8 @@ class MediaCarouselViewModelTest : SysuiTestCase() {
                userId = USER_ID,
                packageName = PACKAGE_NAME,
                notificationKey = key,
                instanceId = instanceId
                instanceId = instanceId,
                isPlaying = isPlaying,
            )

        mediaDataFilter.onMediaDataLoaded(key, key, mediaData)
+19 −0
Original line number Diff line number Diff line
@@ -72,6 +72,11 @@ class MediaFilterRepository @Inject constructor(private val systemClock: SystemC
    val sortedMedia: StateFlow<Map<MediaSortKeyModel, MediaCommonModel>> =
        _sortedMedia.asStateFlow()

    private val _isMediaFromRec: MutableStateFlow<Boolean> = MutableStateFlow(false)
    val isMediaFromRec: StateFlow<Boolean> = _isMediaFromRec.asStateFlow()

    private var mediaFromRecPackageName: String? = null

    fun addMediaEntry(key: String, data: MediaData) {
        val entries = LinkedHashMap<String, MediaData>(_allUserEntries.value)
        entries[key] = data
@@ -161,6 +166,12 @@ class MediaFilterRepository @Inject constructor(private val systemClock: SystemC
                )

            if (mediaDataLoadingModel is MediaDataLoadingModel.Loaded) {
                val isMediaFromRec = isMediaFromRec(it)

                _isMediaFromRec.value = isMediaFromRec
                if (isMediaFromRec) {
                    mediaFromRecPackageName = null
                }
                sortedMap[sortKey] =
                    MediaCommonModel.MediaControl(mediaDataLoadingModel, canBeRemoved(it))
            }
@@ -195,7 +206,15 @@ class MediaFilterRepository @Inject constructor(private val systemClock: SystemC
        _sortedMedia.value = sortedMap
    }

    fun setMediaFromRecPackageName(packageName: String) {
        mediaFromRecPackageName = packageName
    }

    private fun canBeRemoved(data: MediaData): Boolean {
        return data.isPlaying?.let { !it } ?: data.isClearable && !data.active
    }

    private fun isMediaFromRec(data: MediaData): Boolean {
        return data.isPlaying == true && mediaFromRecPackageName == data.packageName
    }
}
+3 −0
Original line number Diff line number Diff line
@@ -133,6 +133,9 @@ constructor(
                initialValue = emptyList(),
            )

    /** Whether the current change in media was done by clicking on a recommendation */
    val isMediaFromRec: StateFlow<Boolean> = mediaFilterRepository.isMediaFromRec

    override fun start() {
        if (!mediaFlags.isMediaControlsRefactorEnabled()) {
            return
Loading