Loading packages/SystemUI/src/com/android/systemui/media/controls/data/repository/MediaFilterRepository.kt +0 −8 Original line number Diff line number Diff line Loading @@ -137,14 +137,6 @@ class MediaFilterRepository @Inject constructor(private val systemClock: SystemC _currentMedia.value = sortedMedia.values.toList() } fun hasActiveMedia(): Boolean { return mutableUserEntries.value.any { it.value.active } } fun hasAnyMedia(): Boolean { return mutableUserEntries.value.entries.isNotEmpty() } 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/MediaDomainModule.kt +2 −1 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.systemui.media.controls.domain import com.android.systemui.CoreStartable import com.android.systemui.Flags import com.android.systemui.dagger.SysUISingleton import com.android.systemui.media.controls.domain.pipeline.LegacyMediaDataManagerImpl import com.android.systemui.media.controls.domain.pipeline.MediaDataManager Loading Loading @@ -54,7 +55,7 @@ interface MediaDomainModule { legacyProvider: Provider<LegacyMediaDataManagerImpl>, newProvider: Provider<MediaCarouselInteractor>, ): MediaDataManager { return if (SceneContainerFlag.isEnabled) { return if (SceneContainerFlag.isEnabled || Flags.mediaControlsInCompose()) { newProvider.get() } else { legacyProvider.get() Loading packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImpl.kt +15 −15 Original line number Diff line number Diff line Loading @@ -49,7 +49,7 @@ constructor( userTracker: UserTracker, private val lockscreenUserManager: NotificationLockscreenUserManager, @Main private val executor: Executor, private val mediaFilterRepository: MediaPipelineRepository, private val mediaPipelineRepository: MediaPipelineRepository, private val mediaLogger: MediaLogger, ) : MediaDataManager.Listener { /** Non-UI listeners to media changes. */ Loading Loading @@ -83,9 +83,9 @@ constructor( immediately: Boolean, ) { if (oldKey != null && oldKey != key) { mediaFilterRepository.removeMediaEntry(oldKey) mediaPipelineRepository.removeMediaEntry(oldKey) } mediaFilterRepository.addMediaEntry(key, data) mediaPipelineRepository.addMediaEntry(key, data) if ( !lockscreenUserManager.isCurrentProfile(data.userId) || Loading @@ -94,7 +94,7 @@ constructor( return } mediaFilterRepository.addCurrentUserMediaEntry(data) mediaPipelineRepository.addCurrentUserMediaEntry(data) mediaLogger.logMediaLoaded(data.instanceId, data.active, "loading media") Loading @@ -103,9 +103,9 @@ constructor( } override fun onMediaDataRemoved(key: String, userInitiated: Boolean) { mediaFilterRepository.removeMediaEntry(key)?.let { mediaData -> mediaPipelineRepository.removeMediaEntry(key)?.let { mediaData -> val instanceId = mediaData.instanceId mediaFilterRepository.removeCurrentUserMediaEntry(instanceId)?.let { mediaPipelineRepository.removeCurrentUserMediaEntry(instanceId)?.let { mediaLogger.logMediaRemoved(instanceId, "removing media card") // Only notify listeners if something actually changed listeners.forEach { it.onMediaDataRemoved(key, userInitiated) } Loading @@ -116,10 +116,10 @@ constructor( @VisibleForTesting internal fun handleProfileChanged() { // TODO(b/317221348) re-add media removed when profile is available. mediaFilterRepository.allMediaEntries.value.forEach { (key, data) -> mediaPipelineRepository.allMediaEntries.value.forEach { (key, data) -> if (!lockscreenUserManager.isProfileAvailable(data.userId)) { // Only remove media when the profile is unavailable. mediaFilterRepository.removeCurrentUserMediaEntry(data.instanceId, data) mediaPipelineRepository.removeCurrentUserMediaEntry(data.instanceId, data) mediaLogger.logMediaRemoved(data.instanceId, "Removing $key after profile change") listeners.forEach { listener -> listener.onMediaDataRemoved(key, false) } } Loading @@ -130,9 +130,9 @@ constructor( internal fun handleUserSwitched() { // If the user changes, remove all current MediaData objects. val listenersCopy = listeners val keyCopy = mediaFilterRepository.currentUserEntries.value.keys.toMutableList() val keyCopy = mediaPipelineRepository.currentUserEntries.value.keys.toMutableList() // Clear the list first and update loading state to remove media from UI. mediaFilterRepository.clearCurrentUserMedia() mediaPipelineRepository.clearCurrentUserMedia() keyCopy.forEach { instanceId -> mediaLogger.logMediaRemoved(instanceId, "Removing media after user change") getKey(instanceId)?.let { Loading @@ -140,9 +140,9 @@ constructor( } } mediaFilterRepository.allMediaEntries.value.forEach { (key, data) -> mediaPipelineRepository.allMediaEntries.value.forEach { (key, data) -> if (lockscreenUserManager.isCurrentProfile(data.userId)) { mediaFilterRepository.addCurrentUserMediaEntry(data) mediaPipelineRepository.addCurrentUserMediaEntry(data) mediaLogger.logMediaLoaded( data.instanceId, data.active, Loading @@ -156,9 +156,9 @@ constructor( /** Invoked when the user has dismissed the media carousel */ fun onSwipeToDismiss() { if (DEBUG) Log.d(TAG, "Media carousel swiped away") val mediaEntries = mediaFilterRepository.allMediaEntries.value.entries val mediaEntries = mediaPipelineRepository.allMediaEntries.value.entries mediaEntries.forEach { (key, data) -> if (mediaFilterRepository.currentUserEntries.value.containsKey(data.instanceId)) { if (mediaPipelineRepository.currentUserEntries.value.containsKey(data.instanceId)) { // Force updates to listeners, needed for re-activated card mediaDataProcessor.setInactive(key, timedOut = true, forceUpdate = true) } Loading @@ -172,7 +172,7 @@ constructor( fun removeListener(listener: MediaDataProcessor.Listener) = _listeners.remove(listener) private fun getKey(instanceId: InstanceId): String? { val allEntries = mediaFilterRepository.allMediaEntries.value val allEntries = mediaPipelineRepository.allMediaEntries.value val filteredEntries = allEntries.filter { (_, data) -> data.instanceId == instanceId } return if (filteredEntries.isNotEmpty()) { filteredEntries.keys.first() Loading packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDataProcessor.kt +1 −1 Original line number Diff line number Diff line Loading @@ -184,7 +184,7 @@ class MediaDataProcessor( } override fun start() { if (!SceneContainerFlag.isEnabled) { if (!SceneContainerFlag.isEnabled && !Flags.mediaControlsInCompose()) { return } Loading packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaCarouselInteractor.kt +23 −10 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import android.media.session.PlaybackState import android.service.notification.StatusBarNotification import com.android.internal.logging.InstanceId import com.android.systemui.CoreStartable import com.android.systemui.Flags import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.media.controls.data.repository.MediaFilterRepository Loading @@ -34,11 +35,12 @@ import com.android.systemui.media.controls.domain.pipeline.MediaDeviceManager import com.android.systemui.media.controls.domain.pipeline.MediaSessionBasedFilter import com.android.systemui.media.controls.domain.pipeline.MediaTimeoutListener import com.android.systemui.media.controls.domain.resume.MediaResumeListener import com.android.systemui.media.controls.shared.model.MediaCommonModel import com.android.systemui.media.remedia.data.repository.MediaPipelineRepository import com.android.systemui.scene.shared.flag.SceneContainerFlag import java.io.PrintWriter import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.map Loading @@ -57,12 +59,12 @@ constructor( private val mediaDeviceManager: MediaDeviceManager, private val mediaDataCombineLatest: MediaDataCombineLatest, private val mediaDataFilter: MediaDataFilterImpl, private val mediaFilterRepository: MediaFilterRepository, private val mediaPipelineRepository: MediaPipelineRepository, ) : MediaDataManager, CoreStartable { /** Are there any media notifications active? */ val hasActiveMedia: StateFlow<Boolean> = mediaFilterRepository.currentUserEntries mediaPipelineRepository.currentUserEntries .map { entries -> entries.any { it.value.active } } .stateIn( scope = applicationScope, Loading @@ -72,7 +74,7 @@ constructor( /** Are there any media entries, including inactive ones? */ val hasAnyMedia: StateFlow<Boolean> = mediaFilterRepository.currentUserEntries mediaPipelineRepository.currentUserEntries .map { entries -> entries.isNotEmpty() } .stateIn( scope = applicationScope, Loading @@ -81,10 +83,16 @@ constructor( ) /** The current list for user media instances */ val currentMedia: StateFlow<List<MediaCommonModel>> = mediaFilterRepository.currentMedia val currentMedia = if (!Flags.mediaControlsInCompose()) { (mediaPipelineRepository as MediaFilterRepository).currentMedia } else { // TODO(b/397989775) remove, not used with media_controls_in_compose MutableStateFlow(mutableListOf()) } override fun start() { if (!SceneContainerFlag.isEnabled) { if (!SceneContainerFlag.isEnabled && !Flags.mediaControlsInCompose()) { return } Loading Loading @@ -182,12 +190,14 @@ constructor( mediaDataFilter.onSwipeToDismiss() } override fun hasActiveMedia() = mediaFilterRepository.hasActiveMedia() override fun hasActiveMedia() = mediaPipelineRepository.hasActiveMedia() override fun hasAnyMedia() = mediaFilterRepository.hasAnyMedia() override fun hasAnyMedia() = mediaPipelineRepository.hasAnyMedia() fun reorderMedia() { mediaFilterRepository.setOrderedMedia() if (!Flags.mediaControlsInCompose()) { (mediaPipelineRepository as MediaFilterRepository).setOrderedMedia() } } /** Add a listener for internal events. */ Loading @@ -201,6 +211,9 @@ constructor( companion object { val unsupported: Nothing get() = error("Code path not supported when ${SceneContainerFlag.DESCRIPTION} is enabled") error( "Code path not supported when ${SceneContainerFlag.DESCRIPTION} or " + "media_controls_in_compose is enabled" ) } } Loading
packages/SystemUI/src/com/android/systemui/media/controls/data/repository/MediaFilterRepository.kt +0 −8 Original line number Diff line number Diff line Loading @@ -137,14 +137,6 @@ class MediaFilterRepository @Inject constructor(private val systemClock: SystemC _currentMedia.value = sortedMedia.values.toList() } fun hasActiveMedia(): Boolean { return mutableUserEntries.value.any { it.value.active } } fun hasAnyMedia(): Boolean { return mutableUserEntries.value.entries.isNotEmpty() } 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/MediaDomainModule.kt +2 −1 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.systemui.media.controls.domain import com.android.systemui.CoreStartable import com.android.systemui.Flags import com.android.systemui.dagger.SysUISingleton import com.android.systemui.media.controls.domain.pipeline.LegacyMediaDataManagerImpl import com.android.systemui.media.controls.domain.pipeline.MediaDataManager Loading Loading @@ -54,7 +55,7 @@ interface MediaDomainModule { legacyProvider: Provider<LegacyMediaDataManagerImpl>, newProvider: Provider<MediaCarouselInteractor>, ): MediaDataManager { return if (SceneContainerFlag.isEnabled) { return if (SceneContainerFlag.isEnabled || Flags.mediaControlsInCompose()) { newProvider.get() } else { legacyProvider.get() Loading
packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImpl.kt +15 −15 Original line number Diff line number Diff line Loading @@ -49,7 +49,7 @@ constructor( userTracker: UserTracker, private val lockscreenUserManager: NotificationLockscreenUserManager, @Main private val executor: Executor, private val mediaFilterRepository: MediaPipelineRepository, private val mediaPipelineRepository: MediaPipelineRepository, private val mediaLogger: MediaLogger, ) : MediaDataManager.Listener { /** Non-UI listeners to media changes. */ Loading Loading @@ -83,9 +83,9 @@ constructor( immediately: Boolean, ) { if (oldKey != null && oldKey != key) { mediaFilterRepository.removeMediaEntry(oldKey) mediaPipelineRepository.removeMediaEntry(oldKey) } mediaFilterRepository.addMediaEntry(key, data) mediaPipelineRepository.addMediaEntry(key, data) if ( !lockscreenUserManager.isCurrentProfile(data.userId) || Loading @@ -94,7 +94,7 @@ constructor( return } mediaFilterRepository.addCurrentUserMediaEntry(data) mediaPipelineRepository.addCurrentUserMediaEntry(data) mediaLogger.logMediaLoaded(data.instanceId, data.active, "loading media") Loading @@ -103,9 +103,9 @@ constructor( } override fun onMediaDataRemoved(key: String, userInitiated: Boolean) { mediaFilterRepository.removeMediaEntry(key)?.let { mediaData -> mediaPipelineRepository.removeMediaEntry(key)?.let { mediaData -> val instanceId = mediaData.instanceId mediaFilterRepository.removeCurrentUserMediaEntry(instanceId)?.let { mediaPipelineRepository.removeCurrentUserMediaEntry(instanceId)?.let { mediaLogger.logMediaRemoved(instanceId, "removing media card") // Only notify listeners if something actually changed listeners.forEach { it.onMediaDataRemoved(key, userInitiated) } Loading @@ -116,10 +116,10 @@ constructor( @VisibleForTesting internal fun handleProfileChanged() { // TODO(b/317221348) re-add media removed when profile is available. mediaFilterRepository.allMediaEntries.value.forEach { (key, data) -> mediaPipelineRepository.allMediaEntries.value.forEach { (key, data) -> if (!lockscreenUserManager.isProfileAvailable(data.userId)) { // Only remove media when the profile is unavailable. mediaFilterRepository.removeCurrentUserMediaEntry(data.instanceId, data) mediaPipelineRepository.removeCurrentUserMediaEntry(data.instanceId, data) mediaLogger.logMediaRemoved(data.instanceId, "Removing $key after profile change") listeners.forEach { listener -> listener.onMediaDataRemoved(key, false) } } Loading @@ -130,9 +130,9 @@ constructor( internal fun handleUserSwitched() { // If the user changes, remove all current MediaData objects. val listenersCopy = listeners val keyCopy = mediaFilterRepository.currentUserEntries.value.keys.toMutableList() val keyCopy = mediaPipelineRepository.currentUserEntries.value.keys.toMutableList() // Clear the list first and update loading state to remove media from UI. mediaFilterRepository.clearCurrentUserMedia() mediaPipelineRepository.clearCurrentUserMedia() keyCopy.forEach { instanceId -> mediaLogger.logMediaRemoved(instanceId, "Removing media after user change") getKey(instanceId)?.let { Loading @@ -140,9 +140,9 @@ constructor( } } mediaFilterRepository.allMediaEntries.value.forEach { (key, data) -> mediaPipelineRepository.allMediaEntries.value.forEach { (key, data) -> if (lockscreenUserManager.isCurrentProfile(data.userId)) { mediaFilterRepository.addCurrentUserMediaEntry(data) mediaPipelineRepository.addCurrentUserMediaEntry(data) mediaLogger.logMediaLoaded( data.instanceId, data.active, Loading @@ -156,9 +156,9 @@ constructor( /** Invoked when the user has dismissed the media carousel */ fun onSwipeToDismiss() { if (DEBUG) Log.d(TAG, "Media carousel swiped away") val mediaEntries = mediaFilterRepository.allMediaEntries.value.entries val mediaEntries = mediaPipelineRepository.allMediaEntries.value.entries mediaEntries.forEach { (key, data) -> if (mediaFilterRepository.currentUserEntries.value.containsKey(data.instanceId)) { if (mediaPipelineRepository.currentUserEntries.value.containsKey(data.instanceId)) { // Force updates to listeners, needed for re-activated card mediaDataProcessor.setInactive(key, timedOut = true, forceUpdate = true) } Loading @@ -172,7 +172,7 @@ constructor( fun removeListener(listener: MediaDataProcessor.Listener) = _listeners.remove(listener) private fun getKey(instanceId: InstanceId): String? { val allEntries = mediaFilterRepository.allMediaEntries.value val allEntries = mediaPipelineRepository.allMediaEntries.value val filteredEntries = allEntries.filter { (_, data) -> data.instanceId == instanceId } return if (filteredEntries.isNotEmpty()) { filteredEntries.keys.first() Loading
packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDataProcessor.kt +1 −1 Original line number Diff line number Diff line Loading @@ -184,7 +184,7 @@ class MediaDataProcessor( } override fun start() { if (!SceneContainerFlag.isEnabled) { if (!SceneContainerFlag.isEnabled && !Flags.mediaControlsInCompose()) { return } Loading
packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaCarouselInteractor.kt +23 −10 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import android.media.session.PlaybackState import android.service.notification.StatusBarNotification import com.android.internal.logging.InstanceId import com.android.systemui.CoreStartable import com.android.systemui.Flags import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.media.controls.data.repository.MediaFilterRepository Loading @@ -34,11 +35,12 @@ import com.android.systemui.media.controls.domain.pipeline.MediaDeviceManager import com.android.systemui.media.controls.domain.pipeline.MediaSessionBasedFilter import com.android.systemui.media.controls.domain.pipeline.MediaTimeoutListener import com.android.systemui.media.controls.domain.resume.MediaResumeListener import com.android.systemui.media.controls.shared.model.MediaCommonModel import com.android.systemui.media.remedia.data.repository.MediaPipelineRepository import com.android.systemui.scene.shared.flag.SceneContainerFlag import java.io.PrintWriter import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.map Loading @@ -57,12 +59,12 @@ constructor( private val mediaDeviceManager: MediaDeviceManager, private val mediaDataCombineLatest: MediaDataCombineLatest, private val mediaDataFilter: MediaDataFilterImpl, private val mediaFilterRepository: MediaFilterRepository, private val mediaPipelineRepository: MediaPipelineRepository, ) : MediaDataManager, CoreStartable { /** Are there any media notifications active? */ val hasActiveMedia: StateFlow<Boolean> = mediaFilterRepository.currentUserEntries mediaPipelineRepository.currentUserEntries .map { entries -> entries.any { it.value.active } } .stateIn( scope = applicationScope, Loading @@ -72,7 +74,7 @@ constructor( /** Are there any media entries, including inactive ones? */ val hasAnyMedia: StateFlow<Boolean> = mediaFilterRepository.currentUserEntries mediaPipelineRepository.currentUserEntries .map { entries -> entries.isNotEmpty() } .stateIn( scope = applicationScope, Loading @@ -81,10 +83,16 @@ constructor( ) /** The current list for user media instances */ val currentMedia: StateFlow<List<MediaCommonModel>> = mediaFilterRepository.currentMedia val currentMedia = if (!Flags.mediaControlsInCompose()) { (mediaPipelineRepository as MediaFilterRepository).currentMedia } else { // TODO(b/397989775) remove, not used with media_controls_in_compose MutableStateFlow(mutableListOf()) } override fun start() { if (!SceneContainerFlag.isEnabled) { if (!SceneContainerFlag.isEnabled && !Flags.mediaControlsInCompose()) { return } Loading Loading @@ -182,12 +190,14 @@ constructor( mediaDataFilter.onSwipeToDismiss() } override fun hasActiveMedia() = mediaFilterRepository.hasActiveMedia() override fun hasActiveMedia() = mediaPipelineRepository.hasActiveMedia() override fun hasAnyMedia() = mediaFilterRepository.hasAnyMedia() override fun hasAnyMedia() = mediaPipelineRepository.hasAnyMedia() fun reorderMedia() { mediaFilterRepository.setOrderedMedia() if (!Flags.mediaControlsInCompose()) { (mediaPipelineRepository as MediaFilterRepository).setOrderedMedia() } } /** Add a listener for internal events. */ Loading @@ -201,6 +211,9 @@ constructor( companion object { val unsupported: Nothing get() = error("Code path not supported when ${SceneContainerFlag.DESCRIPTION} is enabled") error( "Code path not supported when ${SceneContainerFlag.DESCRIPTION} or " + "media_controls_in_compose is enabled" ) } }