Loading packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/data/repository/MediaFilterRepositoryTest.kt +30 −0 Original line number Diff line number Diff line Loading @@ -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, Loading @@ -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" } } packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/interactor/MediaCarouselInteractorTest.kt +27 −0 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading @@ -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 Loading Loading @@ -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" } } packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModelTest.kt +33 −2 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 = Loading @@ -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) Loading packages/SystemUI/src/com/android/systemui/media/controls/data/repository/MediaFilterRepository.kt +19 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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)) } Loading Loading @@ -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 } } packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaCarouselInteractor.kt +3 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/data/repository/MediaFilterRepositoryTest.kt +30 −0 Original line number Diff line number Diff line Loading @@ -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, Loading @@ -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" } }
packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/interactor/MediaCarouselInteractorTest.kt +27 −0 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading @@ -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 Loading Loading @@ -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" } }
packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModelTest.kt +33 −2 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 = Loading @@ -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) Loading
packages/SystemUI/src/com/android/systemui/media/controls/data/repository/MediaFilterRepository.kt +19 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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)) } Loading Loading @@ -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 } }
packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaCarouselInteractor.kt +3 −0 Original line number Diff line number Diff line Loading @@ -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