Loading packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/data/repository/MediaFilterRepositoryTest.kt +17 −0 Original line number Diff line number Diff line Loading @@ -56,11 +56,15 @@ class MediaFilterRepositoryTest : SysuiTestCase() { underTest.addSelectedUserMediaEntry(userMedia) assertThat(selectedUserEntries?.get(instanceId)).isEqualTo(userMedia) assertThat(underTest.hasActiveMedia()).isTrue() assertThat(underTest.hasAnyMedia()).isTrue() underTest.addSelectedUserMediaEntry(userMedia.copy(active = false)) assertThat(selectedUserEntries?.get(instanceId)).isNotEqualTo(userMedia) assertThat(selectedUserEntries?.get(instanceId)?.active).isFalse() assertThat(underTest.hasActiveMedia()).isFalse() assertThat(underTest.hasAnyMedia()).isTrue() } @Test Loading @@ -74,8 +78,12 @@ class MediaFilterRepositoryTest : SysuiTestCase() { underTest.addSelectedUserMediaEntry(userMedia) assertThat(selectedUserEntries?.get(instanceId)).isEqualTo(userMedia) assertThat(underTest.hasActiveMedia()).isTrue() assertThat(underTest.hasAnyMedia()).isTrue() assertThat(underTest.removeSelectedUserMediaEntry(instanceId, userMedia)).isTrue() assertThat(underTest.hasActiveMedia()).isFalse() assertThat(underTest.hasAnyMedia()).isFalse() } @Test Loading Loading @@ -145,6 +153,7 @@ class MediaFilterRepositoryTest : SysuiTestCase() { assertThat(smartspaceMediaData).isNotEqualTo(mediaRecommendation) assertThat(smartspaceMediaData?.isActive).isFalse() assertThat(underTest.isRecommendationActive()).isFalse() } @Test Loading Loading @@ -349,6 +358,14 @@ class MediaFilterRepositoryTest : SysuiTestCase() { .inOrder() } @Test fun hasAnyMedia_noMediaSet_returnsFalse() = testScope.runTest { assertThat(underTest.hasAnyMedia()).isFalse() } @Test fun hasActiveMedia_noMediaSet_returnsFalse() = testScope.runTest { assertThat(underTest.hasActiveMedia()).isFalse() } private fun createMediaData( app: String, playing: Boolean, Loading packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/interactor/MediaCarouselInteractorTest.kt +11 −14 Original line number Diff line number Diff line Loading @@ -76,22 +76,20 @@ class MediaCarouselInteractorTest : SysuiTestCase() { testScope.runTest { val hasActiveMediaOrRecommendation by collectLastValue(underTest.hasActiveMediaOrRecommendation) val hasActiveMedia by collectLastValue(underTest.hasActiveMedia) val hasAnyMedia by collectLastValue(underTest.hasAnyMedia) val userMedia = MediaData(active = true) mediaFilterRepository.addSelectedUserMediaEntry(userMedia) assertThat(hasActiveMediaOrRecommendation).isTrue() assertThat(hasActiveMedia).isTrue() assertThat(hasAnyMedia).isTrue() assertThat(underTest.hasActiveMedia()).isTrue() assertThat(underTest.hasAnyMedia()).isTrue() mediaFilterRepository.addSelectedUserMediaEntry(userMedia.copy(active = false)) assertThat(hasActiveMediaOrRecommendation).isFalse() assertThat(hasActiveMedia).isFalse() assertThat(hasAnyMedia).isTrue() assertThat(underTest.hasActiveMedia()).isFalse() assertThat(underTest.hasAnyMedia()).isTrue() } @Test Loading @@ -99,8 +97,6 @@ class MediaCarouselInteractorTest : SysuiTestCase() { testScope.runTest { val hasActiveMediaOrRecommendation by collectLastValue(underTest.hasActiveMediaOrRecommendation) val hasActiveMedia by collectLastValue(underTest.hasActiveMedia) val hasAnyMedia by collectLastValue(underTest.hasAnyMedia) val userMedia = MediaData(active = false) val instanceId = userMedia.instanceId Loading @@ -109,8 +105,8 @@ class MediaCarouselInteractorTest : SysuiTestCase() { mediaFilterRepository.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(instanceId)) assertThat(hasActiveMediaOrRecommendation).isFalse() assertThat(hasActiveMedia).isFalse() assertThat(hasAnyMedia).isTrue() assertThat(underTest.hasActiveMedia()).isFalse() assertThat(underTest.hasAnyMedia()).isTrue() assertThat(mediaFilterRepository.removeSelectedUserMediaEntry(instanceId, userMedia)) .isTrue() Loading @@ -119,8 +115,8 @@ class MediaCarouselInteractorTest : SysuiTestCase() { ) assertThat(hasActiveMediaOrRecommendation).isFalse() assertThat(hasActiveMedia).isFalse() assertThat(hasAnyMedia).isFalse() assertThat(underTest.hasActiveMedia()).isFalse() assertThat(underTest.hasAnyMedia()).isFalse() } @Test Loading @@ -147,6 +143,7 @@ class MediaCarouselInteractorTest : SysuiTestCase() { mediaFilterRepository.addSelectedUserMediaEntry(userMedia) mediaFilterRepository.addMediaDataLoadingState(mediaLoadingModel) mediaFilterRepository.setOrderedMedia() assertThat(hasActiveMediaOrRecommendation).isTrue() assertThat(hasAnyMediaOrRecommendation).isTrue() Loading Loading @@ -202,7 +199,7 @@ class MediaCarouselInteractorTest : SysuiTestCase() { @Test fun hasAnyMedia_noMediaSet_returnsFalse() = testScope.runTest { assertThat(underTest.hasAnyMedia.value).isFalse() } testScope.runTest { assertThat(underTest.hasAnyMedia()).isFalse() } @Test fun hasAnyMediaOrRecommendation_noMediaSet_returnsFalse() = Loading @@ -210,7 +207,7 @@ class MediaCarouselInteractorTest : SysuiTestCase() { @Test fun hasActiveMedia_noMediaSet_returnsFalse() = testScope.runTest { assertThat(underTest.hasActiveMedia.value).isFalse() } testScope.runTest { assertThat(underTest.hasActiveMedia()).isFalse() } @Test fun hasActiveMediaOrRecommendation_nothingSet_returnsFalse() = Loading packages/SystemUI/src/com/android/systemui/media/controls/data/repository/MediaFilterRepository.kt +14 −2 Original line number Diff line number Diff line Loading @@ -218,9 +218,9 @@ constructor( mediaFromRecPackageName = null _currentMedia.value = sortedMap.values.toList() } } else if (sortedMap.size > sortedMedia.size) { } else if (sortedMap.size > sortedMedia.size && it.active) { _currentMedia.value = sortedMap.values.toList() } else if (sortedMap.size == sortedMedia.size) { } else { // When loading an update for an existing media control. val currentList = mutableListOf<MediaCommonModel>().apply { addAll(_currentMedia.value) } Loading Loading @@ -296,6 +296,18 @@ constructor( mediaFromRecPackageName = packageName } fun hasActiveMedia(): Boolean { return _selectedUserEntries.value.any { it.value.active } } fun hasAnyMedia(): Boolean { return _selectedUserEntries.value.entries.isNotEmpty() } fun isRecommendationActive(): Boolean { return _smartspaceMediaData.value.isActive } private fun canBeRemoved(data: MediaData): Boolean { return data.isPlaying?.let { !it } ?: data.isClearable && !data.active } Loading packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaCarouselInteractor.kt +3 −26 Original line number Diff line number Diff line Loading @@ -25,7 +25,6 @@ import com.android.internal.logging.InstanceId import com.android.systemui.CoreStartable import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.media.controls.data.repository.MediaDataRepository import com.android.systemui.media.controls.data.repository.MediaFilterRepository import com.android.systemui.media.controls.domain.pipeline.MediaDataCombineLatest import com.android.systemui.media.controls.domain.pipeline.MediaDataFilterImpl Loading @@ -45,7 +44,6 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.mapLatest import kotlinx.coroutines.flow.stateIn /** Encapsulates business logic for media pipeline. */ Loading @@ -55,7 +53,6 @@ class MediaCarouselInteractor @Inject constructor( @Application applicationScope: CoroutineScope, private val mediaDataRepository: MediaDataRepository, private val mediaDataProcessor: MediaDataProcessor, private val mediaTimeoutListener: MediaTimeoutListener, private val mediaResumeListener: MediaResumeListener, Loading Loading @@ -103,26 +100,6 @@ constructor( initialValue = false, ) /** Are there any media notifications active, excluding the recommendations? */ val hasActiveMedia: StateFlow<Boolean> = mediaFilterRepository.selectedUserEntries .mapLatest { entries -> entries.any { it.value.active } } .stateIn( scope = applicationScope, started = SharingStarted.WhileSubscribed(), initialValue = false, ) /** Are there any media notifications, excluding the recommendations? */ val hasAnyMedia: StateFlow<Boolean> = mediaFilterRepository.selectedUserEntries .mapLatest { entries -> entries.isNotEmpty() } .stateIn( scope = applicationScope, started = SharingStarted.WhileSubscribed(), initialValue = false, ) /** The current list for user media instances */ val currentMedia: StateFlow<List<MediaCommonModel>> = mediaFilterRepository.currentMedia Loading Loading @@ -235,11 +212,11 @@ constructor( override fun hasAnyMediaOrRecommendation() = hasAnyMediaOrRecommendation.value override fun hasActiveMedia() = hasActiveMedia.value override fun hasActiveMedia() = mediaFilterRepository.hasActiveMedia() override fun hasAnyMedia() = hasAnyMedia.value override fun hasAnyMedia() = mediaFilterRepository.hasAnyMedia() override fun isRecommendationActive() = mediaDataRepository.smartspaceMediaData.value.isActive override fun isRecommendationActive() = mediaFilterRepository.isRecommendationActive() fun reorderMedia() { mediaFilterRepository.setOrderedMedia() Loading packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModel.kt +1 −0 Original line number Diff line number Diff line Loading @@ -201,6 +201,7 @@ constructor( ) { if (immediatelyRemove || isReorderingAllowed()) { interactor.dismissSmartspaceRecommendation(commonModel.recsLoadingModel.key, 0L) mediaRecs = null if (!immediatelyRemove) { // Although it wasn't requested, we were able to process the removal // immediately since reordering is allowed. So, notify hosts to update Loading Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/data/repository/MediaFilterRepositoryTest.kt +17 −0 Original line number Diff line number Diff line Loading @@ -56,11 +56,15 @@ class MediaFilterRepositoryTest : SysuiTestCase() { underTest.addSelectedUserMediaEntry(userMedia) assertThat(selectedUserEntries?.get(instanceId)).isEqualTo(userMedia) assertThat(underTest.hasActiveMedia()).isTrue() assertThat(underTest.hasAnyMedia()).isTrue() underTest.addSelectedUserMediaEntry(userMedia.copy(active = false)) assertThat(selectedUserEntries?.get(instanceId)).isNotEqualTo(userMedia) assertThat(selectedUserEntries?.get(instanceId)?.active).isFalse() assertThat(underTest.hasActiveMedia()).isFalse() assertThat(underTest.hasAnyMedia()).isTrue() } @Test Loading @@ -74,8 +78,12 @@ class MediaFilterRepositoryTest : SysuiTestCase() { underTest.addSelectedUserMediaEntry(userMedia) assertThat(selectedUserEntries?.get(instanceId)).isEqualTo(userMedia) assertThat(underTest.hasActiveMedia()).isTrue() assertThat(underTest.hasAnyMedia()).isTrue() assertThat(underTest.removeSelectedUserMediaEntry(instanceId, userMedia)).isTrue() assertThat(underTest.hasActiveMedia()).isFalse() assertThat(underTest.hasAnyMedia()).isFalse() } @Test Loading Loading @@ -145,6 +153,7 @@ class MediaFilterRepositoryTest : SysuiTestCase() { assertThat(smartspaceMediaData).isNotEqualTo(mediaRecommendation) assertThat(smartspaceMediaData?.isActive).isFalse() assertThat(underTest.isRecommendationActive()).isFalse() } @Test Loading Loading @@ -349,6 +358,14 @@ class MediaFilterRepositoryTest : SysuiTestCase() { .inOrder() } @Test fun hasAnyMedia_noMediaSet_returnsFalse() = testScope.runTest { assertThat(underTest.hasAnyMedia()).isFalse() } @Test fun hasActiveMedia_noMediaSet_returnsFalse() = testScope.runTest { assertThat(underTest.hasActiveMedia()).isFalse() } private fun createMediaData( app: String, playing: Boolean, Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/interactor/MediaCarouselInteractorTest.kt +11 −14 Original line number Diff line number Diff line Loading @@ -76,22 +76,20 @@ class MediaCarouselInteractorTest : SysuiTestCase() { testScope.runTest { val hasActiveMediaOrRecommendation by collectLastValue(underTest.hasActiveMediaOrRecommendation) val hasActiveMedia by collectLastValue(underTest.hasActiveMedia) val hasAnyMedia by collectLastValue(underTest.hasAnyMedia) val userMedia = MediaData(active = true) mediaFilterRepository.addSelectedUserMediaEntry(userMedia) assertThat(hasActiveMediaOrRecommendation).isTrue() assertThat(hasActiveMedia).isTrue() assertThat(hasAnyMedia).isTrue() assertThat(underTest.hasActiveMedia()).isTrue() assertThat(underTest.hasAnyMedia()).isTrue() mediaFilterRepository.addSelectedUserMediaEntry(userMedia.copy(active = false)) assertThat(hasActiveMediaOrRecommendation).isFalse() assertThat(hasActiveMedia).isFalse() assertThat(hasAnyMedia).isTrue() assertThat(underTest.hasActiveMedia()).isFalse() assertThat(underTest.hasAnyMedia()).isTrue() } @Test Loading @@ -99,8 +97,6 @@ class MediaCarouselInteractorTest : SysuiTestCase() { testScope.runTest { val hasActiveMediaOrRecommendation by collectLastValue(underTest.hasActiveMediaOrRecommendation) val hasActiveMedia by collectLastValue(underTest.hasActiveMedia) val hasAnyMedia by collectLastValue(underTest.hasAnyMedia) val userMedia = MediaData(active = false) val instanceId = userMedia.instanceId Loading @@ -109,8 +105,8 @@ class MediaCarouselInteractorTest : SysuiTestCase() { mediaFilterRepository.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(instanceId)) assertThat(hasActiveMediaOrRecommendation).isFalse() assertThat(hasActiveMedia).isFalse() assertThat(hasAnyMedia).isTrue() assertThat(underTest.hasActiveMedia()).isFalse() assertThat(underTest.hasAnyMedia()).isTrue() assertThat(mediaFilterRepository.removeSelectedUserMediaEntry(instanceId, userMedia)) .isTrue() Loading @@ -119,8 +115,8 @@ class MediaCarouselInteractorTest : SysuiTestCase() { ) assertThat(hasActiveMediaOrRecommendation).isFalse() assertThat(hasActiveMedia).isFalse() assertThat(hasAnyMedia).isFalse() assertThat(underTest.hasActiveMedia()).isFalse() assertThat(underTest.hasAnyMedia()).isFalse() } @Test Loading @@ -147,6 +143,7 @@ class MediaCarouselInteractorTest : SysuiTestCase() { mediaFilterRepository.addSelectedUserMediaEntry(userMedia) mediaFilterRepository.addMediaDataLoadingState(mediaLoadingModel) mediaFilterRepository.setOrderedMedia() assertThat(hasActiveMediaOrRecommendation).isTrue() assertThat(hasAnyMediaOrRecommendation).isTrue() Loading Loading @@ -202,7 +199,7 @@ class MediaCarouselInteractorTest : SysuiTestCase() { @Test fun hasAnyMedia_noMediaSet_returnsFalse() = testScope.runTest { assertThat(underTest.hasAnyMedia.value).isFalse() } testScope.runTest { assertThat(underTest.hasAnyMedia()).isFalse() } @Test fun hasAnyMediaOrRecommendation_noMediaSet_returnsFalse() = Loading @@ -210,7 +207,7 @@ class MediaCarouselInteractorTest : SysuiTestCase() { @Test fun hasActiveMedia_noMediaSet_returnsFalse() = testScope.runTest { assertThat(underTest.hasActiveMedia.value).isFalse() } testScope.runTest { assertThat(underTest.hasActiveMedia()).isFalse() } @Test fun hasActiveMediaOrRecommendation_nothingSet_returnsFalse() = Loading
packages/SystemUI/src/com/android/systemui/media/controls/data/repository/MediaFilterRepository.kt +14 −2 Original line number Diff line number Diff line Loading @@ -218,9 +218,9 @@ constructor( mediaFromRecPackageName = null _currentMedia.value = sortedMap.values.toList() } } else if (sortedMap.size > sortedMedia.size) { } else if (sortedMap.size > sortedMedia.size && it.active) { _currentMedia.value = sortedMap.values.toList() } else if (sortedMap.size == sortedMedia.size) { } else { // When loading an update for an existing media control. val currentList = mutableListOf<MediaCommonModel>().apply { addAll(_currentMedia.value) } Loading Loading @@ -296,6 +296,18 @@ constructor( mediaFromRecPackageName = packageName } fun hasActiveMedia(): Boolean { return _selectedUserEntries.value.any { it.value.active } } fun hasAnyMedia(): Boolean { return _selectedUserEntries.value.entries.isNotEmpty() } fun isRecommendationActive(): Boolean { return _smartspaceMediaData.value.isActive } private fun canBeRemoved(data: MediaData): Boolean { return data.isPlaying?.let { !it } ?: data.isClearable && !data.active } Loading
packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaCarouselInteractor.kt +3 −26 Original line number Diff line number Diff line Loading @@ -25,7 +25,6 @@ import com.android.internal.logging.InstanceId import com.android.systemui.CoreStartable import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.media.controls.data.repository.MediaDataRepository import com.android.systemui.media.controls.data.repository.MediaFilterRepository import com.android.systemui.media.controls.domain.pipeline.MediaDataCombineLatest import com.android.systemui.media.controls.domain.pipeline.MediaDataFilterImpl Loading @@ -45,7 +44,6 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.mapLatest import kotlinx.coroutines.flow.stateIn /** Encapsulates business logic for media pipeline. */ Loading @@ -55,7 +53,6 @@ class MediaCarouselInteractor @Inject constructor( @Application applicationScope: CoroutineScope, private val mediaDataRepository: MediaDataRepository, private val mediaDataProcessor: MediaDataProcessor, private val mediaTimeoutListener: MediaTimeoutListener, private val mediaResumeListener: MediaResumeListener, Loading Loading @@ -103,26 +100,6 @@ constructor( initialValue = false, ) /** Are there any media notifications active, excluding the recommendations? */ val hasActiveMedia: StateFlow<Boolean> = mediaFilterRepository.selectedUserEntries .mapLatest { entries -> entries.any { it.value.active } } .stateIn( scope = applicationScope, started = SharingStarted.WhileSubscribed(), initialValue = false, ) /** Are there any media notifications, excluding the recommendations? */ val hasAnyMedia: StateFlow<Boolean> = mediaFilterRepository.selectedUserEntries .mapLatest { entries -> entries.isNotEmpty() } .stateIn( scope = applicationScope, started = SharingStarted.WhileSubscribed(), initialValue = false, ) /** The current list for user media instances */ val currentMedia: StateFlow<List<MediaCommonModel>> = mediaFilterRepository.currentMedia Loading Loading @@ -235,11 +212,11 @@ constructor( override fun hasAnyMediaOrRecommendation() = hasAnyMediaOrRecommendation.value override fun hasActiveMedia() = hasActiveMedia.value override fun hasActiveMedia() = mediaFilterRepository.hasActiveMedia() override fun hasAnyMedia() = hasAnyMedia.value override fun hasAnyMedia() = mediaFilterRepository.hasAnyMedia() override fun isRecommendationActive() = mediaDataRepository.smartspaceMediaData.value.isActive override fun isRecommendationActive() = mediaFilterRepository.isRecommendationActive() fun reorderMedia() { mediaFilterRepository.setOrderedMedia() Loading
packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModel.kt +1 −0 Original line number Diff line number Diff line Loading @@ -201,6 +201,7 @@ constructor( ) { if (immediatelyRemove || isReorderingAllowed()) { interactor.dismissSmartspaceRecommendation(commonModel.recsLoadingModel.key, 0L) mediaRecs = null if (!immediatelyRemove) { // Although it wasn't requested, we were able to process the removal // immediately since reordering is allowed. So, notify hosts to update Loading