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

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

Merge changes I08cd6219,I8b9a8fce into main

* changes:
  Add media carousel view model
  Setting up environment for media carousel view model
parents 07fc72c0 e359b8ec
Loading
Loading
Loading
Loading
+15 −43
Original line number Diff line number Diff line
@@ -147,37 +147,6 @@ class MediaFilterRepositoryTest : SysuiTestCase() {
            assertThat(smartspaceMediaData?.isActive).isFalse()
        }

    @Test
    fun addMediaDataLoadingState() =
        testScope.runTest {
            val mediaDataLoadedStates by collectLastValue(underTest.mediaDataLoadedStates)
            val instanceId = InstanceId.fakeInstanceId(123)
            val mediaLoadedStates = mutableListOf(MediaDataLoadingModel.Loaded(instanceId))

            underTest.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(instanceId))

            assertThat(mediaDataLoadedStates).isEqualTo(mediaLoadedStates)

            mediaLoadedStates.remove(MediaDataLoadingModel.Loaded(instanceId))

            underTest.addMediaDataLoadingState(MediaDataLoadingModel.Removed(instanceId))

            assertThat(mediaDataLoadedStates).isEqualTo(mediaLoadedStates)
        }

    @Test
    fun setRecommendationsLoadingState() =
        testScope.runTest {
            val recommendationsLoadingState by
                collectLastValue(underTest.recommendationsLoadingState)
            val recommendationsLoadingModel =
                SmartspaceMediaLoadingModel.Loaded(KEY_MEDIA_SMARTSPACE)

            underTest.setRecommendationsLoadingState(recommendationsLoadingModel)

            assertThat(recommendationsLoadingState).isEqualTo(recommendationsLoadingModel)
        }

    @Test
    fun addMediaControlPlayingThenRemote() =
        testScope.runTest {
@@ -195,9 +164,10 @@ class MediaFilterRepositoryTest : SysuiTestCase() {
            assertThat(sortedMedia?.size).isEqualTo(2)
            assertThat(sortedMedia?.values)
                .containsExactly(
                    MediaCommonModel.MediaControl(playingInstanceId),
                    MediaCommonModel.MediaControl(remoteInstanceId)
                    MediaCommonModel.MediaControl(MediaDataLoadingModel.Loaded(playingInstanceId)),
                    MediaCommonModel.MediaControl(MediaDataLoadingModel.Loaded(remoteInstanceId))
                )
                .inOrder()
        }

    @Test
@@ -217,8 +187,8 @@ class MediaFilterRepositoryTest : SysuiTestCase() {
            assertThat(sortedMedia?.size).isEqualTo(2)
            assertThat(sortedMedia?.values)
                .containsExactly(
                    MediaCommonModel.MediaControl(playingInstanceId1),
                    MediaCommonModel.MediaControl(playingInstanceId2)
                    MediaCommonModel.MediaControl(MediaDataLoadingModel.Loaded(playingInstanceId1)),
                    MediaCommonModel.MediaControl(MediaDataLoadingModel.Loaded(playingInstanceId2))
                )
                .inOrder()

@@ -233,8 +203,8 @@ class MediaFilterRepositoryTest : SysuiTestCase() {
            assertThat(sortedMedia?.size).isEqualTo(2)
            assertThat(sortedMedia?.values)
                .containsExactly(
                    MediaCommonModel.MediaControl(playingInstanceId2),
                    MediaCommonModel.MediaControl(playingInstanceId1)
                    MediaCommonModel.MediaControl(MediaDataLoadingModel.Loaded(playingInstanceId2)),
                    MediaCommonModel.MediaControl(MediaDataLoadingModel.Loaded(playingInstanceId1))
                )
                .inOrder()
        }
@@ -285,12 +255,14 @@ class MediaFilterRepositoryTest : SysuiTestCase() {
            assertThat(sortedMedia?.size).isEqualTo(6)
            assertThat(sortedMedia?.values)
                .containsExactly(
                    MediaCommonModel.MediaControl(instanceId1),
                    MediaCommonModel.MediaControl(instanceId2),
                    MediaCommonModel.MediaRecommendations(KEY_MEDIA_SMARTSPACE),
                    MediaCommonModel.MediaControl(instanceId4),
                    MediaCommonModel.MediaControl(instanceId3),
                    MediaCommonModel.MediaControl(instanceId5),
                    MediaCommonModel.MediaControl(MediaDataLoadingModel.Loaded(instanceId1)),
                    MediaCommonModel.MediaControl(MediaDataLoadingModel.Loaded(instanceId2)),
                    MediaCommonModel.MediaRecommendations(
                        SmartspaceMediaLoadingModel.Loaded(KEY_MEDIA_SMARTSPACE, true)
                    ),
                    MediaCommonModel.MediaControl(MediaDataLoadingModel.Loaded(instanceId4)),
                    MediaCommonModel.MediaControl(MediaDataLoadingModel.Loaded(instanceId3)),
                    MediaCommonModel.MediaControl(MediaDataLoadingModel.Loaded(instanceId5)),
                )
                .inOrder()
        }
+7 −92
Original line number Diff line number Diff line
@@ -20,7 +20,6 @@ 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,18 +28,14 @@ import com.android.systemui.kosmos.testScope
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.MediaDataFilterImpl
import com.android.systemui.media.controls.domain.pipeline.interactor.MediaCarouselInteractor
import com.android.systemui.media.controls.domain.pipeline.interactor.mediaCarouselInteractor
import com.android.systemui.media.controls.domain.pipeline.mediaDataFilter
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
import com.android.systemui.media.controls.shared.model.SmartspaceMediaData
import com.android.systemui.media.controls.shared.model.SmartspaceMediaLoadingModel
import com.android.systemui.statusbar.notificationLockscreenUserManager
import com.android.systemui.testKosmos
import com.android.systemui.util.mockito.whenever
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.test.runTest
import org.junit.Before
@@ -54,8 +49,6 @@ class MediaCarouselInteractorTest : SysuiTestCase() {
    private val kosmos = testKosmos()
    private val testScope = kosmos.testScope

    private val mediaDataFilter: MediaDataFilterImpl = kosmos.mediaDataFilter
    private val notificationLockscreenUserManager = kosmos.notificationLockscreenUserManager
    private val mediaFilterRepository: MediaFilterRepository = kosmos.mediaFilterRepository

    private val underTest: MediaCarouselInteractor = kosmos.mediaCarouselInteractor
@@ -95,7 +88,6 @@ class MediaCarouselInteractorTest : SysuiTestCase() {
                collectLastValue(underTest.hasActiveMediaOrRecommendation)
            val hasActiveMedia by collectLastValue(underTest.hasActiveMedia)
            val hasAnyMedia by collectLastValue(underTest.hasAnyMedia)
            val sortedMedia by collectLastValue(underTest.sortedMedia)

            val userMedia = MediaData(active = false)
            val instanceId = userMedia.instanceId
@@ -106,7 +98,6 @@ class MediaCarouselInteractorTest : SysuiTestCase() {
            assertThat(hasActiveMediaOrRecommendation).isFalse()
            assertThat(hasActiveMedia).isFalse()
            assertThat(hasAnyMedia).isTrue()
            assertThat(sortedMedia).containsExactly(MediaCommonModel.MediaControl(instanceId))

            assertThat(mediaFilterRepository.removeSelectedUserMediaEntry(instanceId, userMedia))
                .isTrue()
@@ -117,7 +108,6 @@ class MediaCarouselInteractorTest : SysuiTestCase() {
            assertThat(hasActiveMediaOrRecommendation).isFalse()
            assertThat(hasActiveMedia).isFalse()
            assertThat(hasAnyMedia).isFalse()
            assertThat(sortedMedia).isEmpty()
        }

    @Test
@@ -138,28 +128,26 @@ class MediaCarouselInteractorTest : SysuiTestCase() {
                    recommendations = MediaTestHelper.getValidRecommendationList(icon),
                )
            val userMedia = MediaData(active = false)
            val recsLoadingModel = SmartspaceMediaLoadingModel.Loaded(KEY_MEDIA_SMARTSPACE, true)
            val mediaLoadingModel = MediaDataLoadingModel.Loaded(userMedia.instanceId)

            mediaFilterRepository.setRecommendation(userMediaRecommendation)
            mediaFilterRepository.setRecommendationsLoadingState(
                SmartspaceMediaLoadingModel.Loaded(KEY_MEDIA_SMARTSPACE, true)
            )
            mediaFilterRepository.setRecommendationsLoadingState(recsLoadingModel)

            assertThat(hasActiveMediaOrRecommendation).isTrue()
            assertThat(hasAnyMediaOrRecommendation).isTrue()
            assertThat(sortedMedia)
                .containsExactly(MediaCommonModel.MediaRecommendations(KEY_MEDIA_SMARTSPACE))
                .containsExactly(MediaCommonModel.MediaRecommendations(recsLoadingModel))

            mediaFilterRepository.addSelectedUserMediaEntry(userMedia)
            mediaFilterRepository.addMediaDataLoadingState(
                MediaDataLoadingModel.Loaded(userMedia.instanceId)
            )
            mediaFilterRepository.addMediaDataLoadingState(mediaLoadingModel)

            assertThat(hasActiveMediaOrRecommendation).isTrue()
            assertThat(hasAnyMediaOrRecommendation).isTrue()
            assertThat(sortedMedia)
                .containsExactly(
                    MediaCommonModel.MediaRecommendations(KEY_MEDIA_SMARTSPACE),
                    MediaCommonModel.MediaControl(userMedia.instanceId)
                    MediaCommonModel.MediaRecommendations(recsLoadingModel),
                    MediaCommonModel.MediaControl(mediaLoadingModel, true)
                )
                .inOrder()
        }
@@ -238,80 +226,7 @@ class MediaCarouselInteractorTest : SysuiTestCase() {
    fun hasActiveMediaOrRecommendation_nothingSet_returnsFalse() =
        testScope.runTest { assertThat(underTest.hasActiveMediaOrRecommendation.value).isFalse() }

    @Test
    fun onMediaDataUpdated_updatesLoadingState() =
        testScope.runTest {
            whenever(notificationLockscreenUserManager.isCurrentProfile(USER_ID)).thenReturn(true)
            whenever(notificationLockscreenUserManager.isProfileAvailable(USER_ID)).thenReturn(true)
            val mediaDataLoadedStates by collectLastValue(underTest.mediaDataLoadedStates)
            val instanceId = InstanceId.fakeInstanceId(123)
            val mediaLoadedStates: MutableList<MediaDataLoadingModel> = mutableListOf()

            mediaLoadedStates.add(MediaDataLoadingModel.Loaded(instanceId))
            mediaDataFilter.onMediaDataLoaded(
                KEY,
                KEY,
                MediaData(userId = USER_ID, instanceId = instanceId)
            )

            assertThat(mediaDataLoadedStates).isEqualTo(mediaLoadedStates)

            val newInstanceId = InstanceId.fakeInstanceId(321)

            mediaLoadedStates.add(MediaDataLoadingModel.Loaded(newInstanceId))
            mediaDataFilter.onMediaDataLoaded(
                KEY_2,
                KEY_2,
                MediaData(userId = USER_ID, instanceId = newInstanceId)
            )

            assertThat(mediaDataLoadedStates).isEqualTo(mediaLoadedStates)

            mediaLoadedStates.remove(MediaDataLoadingModel.Loaded(instanceId))

            mediaDataFilter.onMediaDataRemoved(KEY)

            assertThat(mediaDataLoadedStates).isEqualTo(mediaLoadedStates)

            mediaLoadedStates.remove(MediaDataLoadingModel.Loaded(newInstanceId))

            mediaDataFilter.onMediaDataRemoved(KEY_2)

            assertThat(mediaDataLoadedStates).isEqualTo(mediaLoadedStates)
        }

    @Test
    fun onMediaRecommendationsUpdated_updatesLoadingState() =
        testScope.runTest {
            whenever(notificationLockscreenUserManager.isCurrentProfile(USER_ID)).thenReturn(true)
            whenever(notificationLockscreenUserManager.isProfileAvailable(USER_ID)).thenReturn(true)
            val recommendationsLoadingState by
                collectLastValue(underTest.recommendationsLoadingState)
            val icon = Icon.createWithResource(context, R.drawable.ic_media_play)
            val mediaRecommendations =
                SmartspaceMediaData(
                    targetId = KEY_MEDIA_SMARTSPACE,
                    isActive = true,
                    recommendations = MediaTestHelper.getValidRecommendationList(icon),
                )
            var recommendationsLoadingModel: SmartspaceMediaLoadingModel =
                SmartspaceMediaLoadingModel.Loaded(KEY_MEDIA_SMARTSPACE, isPrioritized = true)

            mediaDataFilter.onSmartspaceMediaDataLoaded(KEY_MEDIA_SMARTSPACE, mediaRecommendations)

            assertThat(recommendationsLoadingState).isEqualTo(recommendationsLoadingModel)

            recommendationsLoadingModel = SmartspaceMediaLoadingModel.Removed(KEY_MEDIA_SMARTSPACE)

            mediaDataFilter.onSmartspaceMediaDataRemoved(KEY_MEDIA_SMARTSPACE)

            assertThat(recommendationsLoadingState).isEqualTo(recommendationsLoadingModel)
        }

    companion object {
        private const val KEY = "key"
        private const val KEY_2 = "key2"
        private const val USER_ID = 0
        private const val KEY_MEDIA_SMARTSPACE = "MEDIA_SMARTSPACE_ID"
    }
}
+147 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui.media.controls.ui.viewmodel

import android.R
import android.content.packageManager
import android.content.pm.ApplicationInfo
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
import com.android.systemui.flags.fakeFeatureFlagsClassic
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.mediaDataFilter
import com.android.systemui.media.controls.shared.model.MediaData
import com.android.systemui.media.controls.shared.model.SmartspaceMediaData
import com.android.systemui.statusbar.notificationLockscreenUserManager
import com.android.systemui.testKosmos
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.eq
import com.android.systemui.util.mockito.whenever
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers
import org.mockito.Mockito

@SmallTest
@RunWith(AndroidJUnit4::class)
class MediaCarouselViewModelTest : SysuiTestCase() {

    private val kosmos = testKosmos()
    private val testScope = kosmos.testScope

    private val mediaDataFilter: MediaDataFilterImpl = kosmos.mediaDataFilter
    private val notificationLockscreenUserManager = kosmos.notificationLockscreenUserManager
    private val packageManager = kosmos.packageManager
    private val icon = Icon.createWithResource(context, R.drawable.ic_media_play)
    private val drawable = context.getDrawable(R.drawable.ic_media_play)
    private val smartspaceMediaData: SmartspaceMediaData =
        SmartspaceMediaData(
            targetId = KEY_MEDIA_SMARTSPACE,
            isActive = true,
            packageName = PACKAGE_NAME,
            recommendations = MediaTestHelper.getValidRecommendationList(icon),
        )

    private val underTest: MediaCarouselViewModel = kosmos.mediaCarouselViewModel

    @Before
    fun setUp() {
        kosmos.mediaCarouselInteractor.start()

        whenever(packageManager.getApplicationIcon(Mockito.anyString())).thenReturn(drawable)
        whenever(packageManager.getApplicationIcon(any(ApplicationInfo::class.java)))
            .thenReturn(drawable)
        whenever(packageManager.getApplicationInfo(eq(PACKAGE_NAME), ArgumentMatchers.anyInt()))
            .thenReturn(ApplicationInfo())
        whenever(packageManager.getApplicationLabel(any())).thenReturn(PACKAGE_NAME)

        context.setMockPackageManager(packageManager)
    }

    @Test
    fun loadMediaControls_mediaItemsAreUpdated() =
        testScope.runTest {
            val sortedMedia by collectLastValue(underTest.mediaItems)
            val instanceId1 = InstanceId.fakeInstanceId(123)
            val instanceId2 = InstanceId.fakeInstanceId(456)

            loadMediaControl(KEY, instanceId1)
            loadMediaControl(KEY_2, instanceId2)

            val firstMediaControl = sortedMedia?.get(0) as MediaCommonViewModel.MediaControl
            val secondMediaControl = sortedMedia?.get(1) as MediaCommonViewModel.MediaControl
            assertThat(firstMediaControl.instanceId).isEqualTo(instanceId2)
            assertThat(secondMediaControl.instanceId).isEqualTo(instanceId1)
        }

    @Test
    fun loadMediaControlsAndRecommendations_mediaItemsAreUpdated() =
        testScope.runTest {
            val sortedMedia by collectLastValue(underTest.mediaItems)
            kosmos.fakeFeatureFlagsClassic.set(Flags.MEDIA_RETAIN_RECOMMENDATIONS, false)
            val instanceId1 = InstanceId.fakeInstanceId(123)
            val instanceId2 = InstanceId.fakeInstanceId(456)

            loadMediaControl(KEY, instanceId1)
            loadMediaControl(KEY_2, instanceId2)
            loadMediaRecommendations()

            val firstMediaControl = sortedMedia?.get(0) as MediaCommonViewModel.MediaControl
            val secondMediaControl = sortedMedia?.get(1) as MediaCommonViewModel.MediaControl
            val recsCard = sortedMedia?.get(2) as MediaCommonViewModel.MediaRecommendations
            assertThat(firstMediaControl.instanceId).isEqualTo(instanceId2)
            assertThat(secondMediaControl.instanceId).isEqualTo(instanceId1)
            assertThat(recsCard.key).isEqualTo(KEY_MEDIA_SMARTSPACE)
        }

    private fun loadMediaControl(key: String, instanceId: InstanceId) {
        whenever(notificationLockscreenUserManager.isCurrentProfile(USER_ID)).thenReturn(true)
        whenever(notificationLockscreenUserManager.isProfileAvailable(USER_ID)).thenReturn(true)
        val mediaData =
            MediaData(
                userId = USER_ID,
                packageName = PACKAGE_NAME,
                notificationKey = key,
                instanceId = instanceId
            )

        mediaDataFilter.onMediaDataLoaded(key, key, mediaData)
    }

    private fun loadMediaRecommendations(key: String = KEY_MEDIA_SMARTSPACE) {
        mediaDataFilter.onSmartspaceMediaDataLoaded(key, smartspaceMediaData)
    }

    companion object {
        private const val USER_ID = 0
        private const val KEY = "key"
        private const val KEY_2 = "key2"
        private const val PACKAGE_NAME = "com.example.app"
        private const val KEY_MEDIA_SMARTSPACE = "MEDIA_SMARTSPACE_ID"
    }
}
+22 −73
Original line number Diff line number Diff line
@@ -52,16 +52,6 @@ class MediaFilterRepository @Inject constructor(private val systemClock: SystemC
        MutableStateFlow(LinkedHashMap())
    val allUserEntries: StateFlow<Map<String, MediaData>> = _allUserEntries.asStateFlow()

    private val _mediaDataLoadedStates: MutableStateFlow<List<MediaDataLoadingModel>> =
        MutableStateFlow(mutableListOf())
    val mediaDataLoadedStates: StateFlow<List<MediaDataLoadingModel>> =
        _mediaDataLoadedStates.asStateFlow()

    private val _recommendationsLoadingState: MutableStateFlow<SmartspaceMediaLoadingModel> =
        MutableStateFlow(SmartspaceMediaLoadingModel.Unknown)
    val recommendationsLoadingState: StateFlow<SmartspaceMediaLoadingModel> =
        _recommendationsLoadingState.asStateFlow()

    private val comparator =
        compareByDescending<MediaSortKeyModel> {
                it.isPlaying == true && it.playbackLocation == MediaData.PLAYBACK_LOCAL
@@ -148,46 +138,15 @@ class MediaFilterRepository @Inject constructor(private val systemClock: SystemC
    }

    fun addMediaDataLoadingState(mediaDataLoadingModel: MediaDataLoadingModel) {
        // Filter out previous loading state that has same [InstanceId].
        val loadedStates =
            _mediaDataLoadedStates.value.filter { loadedModel ->
                loadedModel !is MediaDataLoadingModel.Loaded ||
                    !loadedModel.equalInstanceIds(mediaDataLoadingModel)
            }

        _mediaDataLoadedStates.value =
            loadedStates +
                if (mediaDataLoadingModel is MediaDataLoadingModel.Loaded) {
                    listOf(mediaDataLoadingModel)
                } else {
                    emptyList()
                }

        addMediaLoadingToSortedMap(mediaDataLoadingModel)
    }

    fun setRecommendationsLoadingState(smartspaceMediaLoadingModel: SmartspaceMediaLoadingModel) {
        _recommendationsLoadingState.value = smartspaceMediaLoadingModel

        addRecsLoadingToSortedMap(smartspaceMediaLoadingModel)
    }

    private fun addMediaLoadingToSortedMap(mediaDataLoadingModel: MediaDataLoadingModel) {
        val instanceId =
            when (mediaDataLoadingModel) {
                is MediaDataLoadingModel.Loaded -> mediaDataLoadingModel.instanceId
                is MediaDataLoadingModel.Removed -> mediaDataLoadingModel.instanceId
                MediaDataLoadingModel.Unknown -> null
            }
        val sortedMap = TreeMap<MediaSortKeyModel, MediaCommonModel>(comparator)
        sortedMap.putAll(
            _sortedMedia.value.filter { (_, commonModel) ->
                commonModel !is MediaCommonModel.MediaControl ||
                    commonModel.instanceId != instanceId
                    commonModel.mediaLoadedModel.instanceId != mediaDataLoadingModel.instanceId
            }
        )

        _selectedUserEntries.value[instanceId]?.let {
        _selectedUserEntries.value[mediaDataLoadingModel.instanceId]?.let {
            val sortKey =
                MediaSortKeyModel(
                    isPrioritizedRec = false,
@@ -202,40 +161,27 @@ class MediaFilterRepository @Inject constructor(private val systemClock: SystemC
                )

            if (mediaDataLoadingModel is MediaDataLoadingModel.Loaded) {
                sortedMap[sortKey] = MediaCommonModel.MediaControl(it.instanceId)
                sortedMap[sortKey] =
                    MediaCommonModel.MediaControl(mediaDataLoadingModel, canBeRemoved(it))
            }
        }

        _sortedMedia.value = sortedMap
    }

    private fun addRecsLoadingToSortedMap(
        smartspaceMediaLoadingModel: SmartspaceMediaLoadingModel
    ) {
        val isPrioritized: Boolean
        val key: String?
    fun setRecommendationsLoadingState(smartspaceMediaLoadingModel: SmartspaceMediaLoadingModel) {
        val isPrioritized =
            when (smartspaceMediaLoadingModel) {
            is SmartspaceMediaLoadingModel.Loaded -> {
                isPrioritized = smartspaceMediaLoadingModel.isPrioritized
                key = smartspaceMediaLoadingModel.key
            }
            is SmartspaceMediaLoadingModel.Removed -> {
                isPrioritized = false
                key = smartspaceMediaLoadingModel.key
            }
            SmartspaceMediaLoadingModel.Unknown -> {
                isPrioritized = false
                key = null
            }
                is SmartspaceMediaLoadingModel.Loaded -> smartspaceMediaLoadingModel.isPrioritized
                else -> false
            }
        val sortedMap = TreeMap<MediaSortKeyModel, MediaCommonModel>(comparator)
        sortedMap.putAll(
            _sortedMedia.value.filter { (_, commonModel) ->
                commonModel !is MediaCommonModel.MediaRecommendations || commonModel.key != key
                commonModel !is MediaCommonModel.MediaRecommendations
            }
        )

        key?.let {
        val sortKey =
            MediaSortKeyModel(
                isPrioritizedRec = isPrioritized,
@@ -243,10 +189,13 @@ class MediaFilterRepository @Inject constructor(private val systemClock: SystemC
                active = _smartspaceMediaData.value.isActive,
            )
        if (smartspaceMediaLoadingModel is SmartspaceMediaLoadingModel.Loaded) {
                sortedMap[sortKey] = MediaCommonModel.MediaRecommendations(key)
            }
            sortedMap[sortKey] = MediaCommonModel.MediaRecommendations(smartspaceMediaLoadingModel)
        }

        _sortedMedia.value = sortedMap
    }

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

File changed.

Preview size limit exceeded, changes collapsed.

Loading