Loading packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/LegacyMediaDataManagerImpl.kt +58 −59 Original line number Diff line number Diff line Loading @@ -111,7 +111,7 @@ private val ART_URIS = arrayOf( MediaMetadata.METADATA_KEY_ALBUM_ART_URI, MediaMetadata.METADATA_KEY_ART_URI, MediaMetadata.METADATA_KEY_DISPLAY_ICON_URI MediaMetadata.METADATA_KEY_DISPLAY_ICON_URI, ) private const val TAG = "MediaDataManager" Loading @@ -136,7 +136,7 @@ private val LOADING = active = true, resumeAction = null, instanceId = InstanceId.fakeInstanceId(-1), appUid = Process.INVALID_UID appUid = Process.INVALID_UID, ) internal val EMPTY_SMARTSPACE_MEDIA_DATA = Loading @@ -163,7 +163,7 @@ private fun allowMediaRecommendations(context: Context): Boolean { Settings.Secure.getInt( context.contentResolver, Settings.Secure.MEDIA_CONTROLS_RECOMMENDATION, 1 1, ) return Utils.useQsMediaPlayer(context) && flag > 0 } Loading Loading @@ -217,7 +217,7 @@ class LegacyMediaDataManagerImpl( private val themeText = com.android.settingslib.Utils.getColorAttr( context, com.android.internal.R.attr.textColorPrimary com.android.internal.R.attr.textColorPrimary, ) .defaultColor Loading Loading @@ -387,7 +387,7 @@ class LegacyMediaDataManagerImpl( uiExecutor, SmartspaceSession.OnTargetsAvailableListener { targets -> smartspaceMediaDataProvider.onTargetsAvailable(targets) } }, ) } smartspaceSession?.let { it.requestSmartspaceUpdate() } Loading @@ -398,12 +398,12 @@ class LegacyMediaDataManagerImpl( if (!allowMediaRecommendations) { dismissSmartspaceRecommendation( key = smartspaceMediaData.targetId, delay = 0L delay = 0L, ) } } }, Settings.Secure.MEDIA_CONTROLS_RECOMMENDATION Settings.Secure.MEDIA_CONTROLS_RECOMMENDATION, ) } Loading Loading @@ -461,7 +461,7 @@ class LegacyMediaDataManagerImpl( token: MediaSession.Token, appName: String, appIntent: PendingIntent, packageName: String packageName: String, ) { // Resume controls don't have a notification key, so store by package name instead if (!mediaEntries.containsKey(packageName)) { Loading Loading @@ -497,7 +497,7 @@ class LegacyMediaDataManagerImpl( token, appName, appIntent, packageName packageName, ) } } else { Loading @@ -509,7 +509,7 @@ class LegacyMediaDataManagerImpl( token, appName, appIntent, packageName packageName, ) } } Loading Loading @@ -609,14 +609,14 @@ class LegacyMediaDataManagerImpl( result.appUid, sbn.packageName, instanceId, result.playbackLocation result.playbackLocation, ) } else if (result.playbackLocation != currentEntry?.playbackLocation) { logger.logPlaybackLocationChange( result.appUid, sbn.packageName, instanceId, result.playbackLocation result.playbackLocation, ) } Loading Loading @@ -722,16 +722,17 @@ class LegacyMediaDataManagerImpl( /** Called when the player's [PlaybackState] has been updated with new actions and/or state */ private fun updateState(key: String, state: PlaybackState) { mediaEntries.get(key)?.let { backgroundExecutor.execute { val token = it.token if (token == null) { if (DEBUG) Log.d(TAG, "State updated, but token was null") return return@execute } val actions = createActionsFromState( it.packageName, mediaControllerFactory.create(it.token), UserHandle(it.userId) UserHandle(it.userId), ) // Control buttons Loading @@ -745,7 +746,8 @@ class LegacyMediaDataManagerImpl( it.copy(isPlaying = isPlayingState(state.state)) } if (DEBUG) Log.d(TAG, "State updated outside of notification") onMediaDataLoaded(key, key, data) foregroundExecutor.execute { onMediaDataLoaded(key, key, data) } } } } Loading Loading @@ -773,7 +775,7 @@ class LegacyMediaDataManagerImpl( } foregroundExecutor.executeDelayed( { removeEntry(key = key, userInitiated = userInitiated) }, delay delay, ) return existed } Loading @@ -793,12 +795,12 @@ class LegacyMediaDataManagerImpl( smartspaceMediaData = EMPTY_SMARTSPACE_MEDIA_DATA.copy( targetId = smartspaceMediaData.targetId, instanceId = smartspaceMediaData.instanceId instanceId = smartspaceMediaData.instanceId, ) } foregroundExecutor.executeDelayed( { notifySmartspaceMediaDataRemoved(smartspaceMediaData.targetId, immediately = true) }, delay delay, ) } Loading Loading @@ -826,7 +828,7 @@ class LegacyMediaDataManagerImpl( token: MediaSession.Token, appName: String, appIntent: PendingIntent, packageName: String packageName: String, ) = withContext(backgroundDispatcher) { val lastActive = systemClock.elapsedRealtime() Loading @@ -843,7 +845,7 @@ class LegacyMediaDataManagerImpl( token, appName, appIntent, packageName packageName, ) if (result == null || desc.title.isNullOrBlank()) { Log.d(TAG, "No MediaData result for resumption") Loading Loading @@ -882,7 +884,7 @@ class LegacyMediaDataManagerImpl( appUid = result.appUid, isExplicit = result.isExplicit, resumeProgress = result.resumeProgress, ) ), ) } } Loading @@ -895,7 +897,7 @@ class LegacyMediaDataManagerImpl( token: MediaSession.Token, appName: String, appIntent: PendingIntent, packageName: String packageName: String, ) { if (desc.title.isNullOrBlank()) { Log.e(TAG, "Description incomplete") Loading Loading @@ -966,7 +968,7 @@ class LegacyMediaDataManagerImpl( appUid = appUid, isExplicit = isExplicit, resumeProgress = progress, ) ), ) } } Loading @@ -981,7 +983,7 @@ class LegacyMediaDataManagerImpl( val token = sbn.notification.extras.getParcelable( Notification.EXTRA_MEDIA_SESSION, MediaSession.Token::class.java MediaSession.Token::class.java, ) if (token == null) { return Loading @@ -993,7 +995,7 @@ class LegacyMediaDataManagerImpl( val appInfo = notif.extras.getParcelable( Notification.EXTRA_BUILDER_APPLICATION_INFO, ApplicationInfo::class.java ApplicationInfo::class.java, ) ?: getAppInfoFromPackage(sbn.packageName) // App name Loading Loading @@ -1057,7 +1059,7 @@ class LegacyMediaDataManagerImpl( val deviceIntent = extras.getParcelable( Notification.EXTRA_MEDIA_REMOTE_INTENT, PendingIntent::class.java PendingIntent::class.java, ) Log.d(TAG, "$key is RCN for $deviceName") Loading @@ -1073,7 +1075,7 @@ class LegacyMediaDataManagerImpl( deviceDrawable, deviceName, deviceIntent, showBroadcastButton = false showBroadcastButton = false, ) } } Loading Loading @@ -1160,7 +1162,7 @@ class LegacyMediaDataManagerImpl( mediaData.copy( resumeAction = oldResumeAction, hasCheckedForResume = oldHasCheckedForResume, active = oldActive active = oldActive, ) onMediaDataLoaded(key, oldKey, mediaData) } Loading @@ -1169,7 +1171,7 @@ class LegacyMediaDataManagerImpl( private fun logSingleVsMultipleMediaAdded( appUid: Int, packageName: String, instanceId: InstanceId instanceId: InstanceId, ) { if (mediaEntries.size == 1) { logger.logSingleMediaPlayerInCarousel(appUid, packageName, instanceId) Loading Loading @@ -1207,7 +1209,7 @@ class LegacyMediaDataManagerImpl( private fun createActionsFromState( packageName: String, controller: MediaController, user: UserHandle user: UserHandle, ): MediaButton? { if (!mediaFlags.areMediaSessionActionsEnabled(packageName, user)) { return null Loading Loading @@ -1245,7 +1247,7 @@ class LegacyMediaDataManagerImpl( packageName, ContentProvider.getUriWithoutUserId(uri), Intent.FLAG_GRANT_READ_URI_PERMISSION, ContentProvider.getUserIdFromUri(uri, userId) ContentProvider.getUserIdFromUri(uri, userId), ) return loadBitmapFromUri(uri) } catch (e: SecurityException) { Loading Loading @@ -1282,7 +1284,7 @@ class LegacyMediaDataManagerImpl( val scale = MediaDataUtils.getScaleFactor( APair(width, height), APair(artworkWidth, artworkHeight) APair(artworkWidth, artworkHeight), ) // Downscale if needed Loading @@ -1307,7 +1309,7 @@ class LegacyMediaDataManagerImpl( .loadDrawable(context), action, context.getString(R.string.controls_media_resume), context.getDrawable(R.drawable.ic_media_play_container) context.getDrawable(R.drawable.ic_media_play_container), ) } Loading Loading @@ -1371,10 +1373,7 @@ class LegacyMediaDataManagerImpl( // There should NOT be more than 1 Smartspace media update. When it happens, it // indicates a bad state or an error. Reset the status accordingly. Log.wtf(TAG, "More than 1 Smartspace Media Update. Resetting the status...") notifySmartspaceMediaDataRemoved( smartspaceMediaData.targetId, immediately = false, ) notifySmartspaceMediaDataRemoved(smartspaceMediaData.targetId, immediately = false) smartspaceMediaData = EMPTY_SMARTSPACE_MEDIA_DATA } } Loading Loading @@ -1420,7 +1419,7 @@ class LegacyMediaDataManagerImpl( private fun handlePossibleRemoval( key: String, removed: MediaData, notificationRemoved: Boolean = false notificationRemoved: Boolean = false, ) { val hasSession = removed.token != null if (hasSession && removed.semanticActions != null) { Loading @@ -1445,7 +1444,7 @@ class LegacyMediaDataManagerImpl( Log.d( TAG, "Notification ($notificationRemoved) and/or session " + "($hasSession) gone for inactive player $key" "($hasSession) gone for inactive player $key", ) } convertToResumePlayer(key, removed) Loading packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaActions.kt +18 −16 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.systemui.media.controls.domain.pipeline import android.annotation.WorkerThread import android.app.ActivityOptions import android.app.BroadcastOptions import android.app.Notification Loading Loading @@ -50,6 +51,7 @@ private const val TAG = "MediaActions" * @return a Pair consisting of a list of media actions, and a list of ints representing which of * those actions should be shown in the compact player */ @WorkerThread fun createActionsFromState( context: Context, packageName: String, Loading @@ -69,7 +71,7 @@ fun createActionsFromState( context.getString(R.string.controls_media_button_connecting), context.getDrawable(R.drawable.ic_media_connecting_container), // Specify a rebind id to prevent the spinner from restarting on later binds. com.android.internal.R.drawable.progress_small_material com.android.internal.R.drawable.progress_small_material, ) } else if (isPlayingState(state.state)) { getStandardAction(context, controller, state.actions, PlaybackState.ACTION_PAUSE) Loading Loading @@ -128,7 +130,7 @@ fun createActionsFromState( nextCustomAction(), nextCustomAction(), reserveNext, reservePrev reservePrev, ) } Loading @@ -146,7 +148,7 @@ private fun getStandardAction( context: Context, controller: MediaController, stateActions: Long, @PlaybackState.Actions action: Long @PlaybackState.Actions action: Long, ): MediaAction? { if (!includesAction(stateActions, action)) { return null Loading @@ -158,7 +160,7 @@ private fun getStandardAction( context.getDrawable(R.drawable.ic_media_play), { controller.transportControls.play() }, context.getString(R.string.controls_media_button_play), context.getDrawable(R.drawable.ic_media_play_container) context.getDrawable(R.drawable.ic_media_play_container), ) } PlaybackState.ACTION_PAUSE -> { Loading @@ -166,7 +168,7 @@ private fun getStandardAction( context.getDrawable(R.drawable.ic_media_pause), { controller.transportControls.pause() }, context.getString(R.string.controls_media_button_pause), context.getDrawable(R.drawable.ic_media_pause_container) context.getDrawable(R.drawable.ic_media_pause_container), ) } PlaybackState.ACTION_SKIP_TO_PREVIOUS -> { Loading @@ -174,7 +176,7 @@ private fun getStandardAction( MediaControlDrawables.getPrevIcon(context), { controller.transportControls.skipToPrevious() }, context.getString(R.string.controls_media_button_prev), null null, ) } PlaybackState.ACTION_SKIP_TO_NEXT -> { Loading @@ -182,7 +184,7 @@ private fun getStandardAction( MediaControlDrawables.getNextIcon(context), { controller.transportControls.skipToNext() }, context.getString(R.string.controls_media_button_next), null null, ) } else -> null Loading @@ -194,13 +196,13 @@ private fun getCustomAction( context: Context, packageName: String, controller: MediaController, customAction: PlaybackState.CustomAction customAction: PlaybackState.CustomAction, ): MediaAction { return MediaAction( Icon.createWithResource(packageName, customAction.icon).loadDrawable(context), { controller.transportControls.sendCustomAction(customAction, customAction.extras) }, customAction.name, null null, ) } Loading @@ -218,7 +220,7 @@ private fun includesAction(stateActions: Long, @PlaybackState.Actions action: Lo /** Generate action buttons based on notification actions */ fun createActionsFromNotification( context: Context, sbn: StatusBarNotification sbn: StatusBarNotification, ): Pair<List<MediaNotificationAction>, List<Int>> { val notif = sbn.notification val actionIcons: MutableList<MediaNotificationAction> = ArrayList() Loading @@ -229,7 +231,7 @@ fun createActionsFromNotification( if (actionsToShowCollapsed.size > MAX_COMPACT_ACTIONS) { Log.e( TAG, "Too many compact actions for ${sbn.key}, limiting to first $MAX_COMPACT_ACTIONS" "Too many compact actions for ${sbn.key}, limiting to first $MAX_COMPACT_ACTIONS", ) actionsToShowCollapsed = actionsToShowCollapsed.subList(0, MAX_COMPACT_ACTIONS) } Loading @@ -239,7 +241,7 @@ fun createActionsFromNotification( Log.w( TAG, "Too many notification actions for ${sbn.key}, " + "limiting to first $MAX_NOTIFICATION_ACTIONS" "limiting to first $MAX_NOTIFICATION_ACTIONS", ) } Loading @@ -253,7 +255,7 @@ fun createActionsFromNotification( val themeText = com.android.settingslib.Utils.getColorAttr( context, com.android.internal.R.attr.textColorPrimary com.android.internal.R.attr.textColorPrimary, ) .defaultColor Loading @@ -271,7 +273,7 @@ fun createActionsFromNotification( action.isAuthenticationRequired, action.actionIntent, mediaActionIcon, action.title action.title, ) actionIcons.add(mediaAction) } Loading @@ -288,7 +290,7 @@ fun createActionsFromNotification( */ fun getNotificationActions( actions: List<MediaNotificationAction>, activityStarter: ActivityStarter activityStarter: ActivityStarter, ): List<MediaAction> { return actions.map { action -> val runnable = Loading @@ -303,7 +305,7 @@ fun getNotificationActions( activityStarter.dismissKeyguardThenExecute( { sendPendingIntent(action.actionIntent) }, {}, true true, ) else -> sendPendingIntent(actionIntent) } Loading packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDataProcessor.kt +60 −53 File changed.Preview size limit exceeded, changes collapsed. Show changes packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/LegacyMediaDataManagerImplTest.kt +12 −6 Original line number Diff line number Diff line Loading @@ -1890,7 +1890,7 @@ class LegacyMediaDataManagerImplTest(flags: FlagsParameterization) : SysuiTestCa // Callback gets an updated state val state = PlaybackState.Builder().setState(PlaybackState.STATE_PLAYING, 0L, 1f).build() stateCallbackCaptor.value.invoke(KEY, state) onStateUpdated(KEY, state) // Listener is notified of updated state verify(listener) Loading @@ -1911,7 +1911,7 @@ class LegacyMediaDataManagerImplTest(flags: FlagsParameterization) : SysuiTestCa // No media added with this key stateCallbackCaptor.value.invoke(KEY, state) onStateUpdated(KEY, state) verify(listener, never()) .onMediaDataLoaded(eq(KEY), any(), any(), anyBoolean(), anyInt(), anyBoolean()) } Loading @@ -1928,7 +1928,7 @@ class LegacyMediaDataManagerImplTest(flags: FlagsParameterization) : SysuiTestCa val state = PlaybackState.Builder().build() // Then no changes are made stateCallbackCaptor.value.invoke(KEY, state) onStateUpdated(KEY, state) verify(listener, never()) .onMediaDataLoaded(eq(KEY), any(), any(), anyBoolean(), anyInt(), anyBoolean()) } Loading @@ -1939,7 +1939,7 @@ class LegacyMediaDataManagerImplTest(flags: FlagsParameterization) : SysuiTestCa whenever(controller.playbackState).thenReturn(state) addNotificationAndLoad() stateCallbackCaptor.value.invoke(KEY, state) onStateUpdated(KEY, state) verify(listener) .onMediaDataLoaded( Loading Loading @@ -1983,7 +1983,7 @@ class LegacyMediaDataManagerImplTest(flags: FlagsParameterization) : SysuiTestCa backgroundExecutor.runAllReady() foregroundExecutor.runAllReady() stateCallbackCaptor.value.invoke(PACKAGE_NAME, state) onStateUpdated(PACKAGE_NAME, state) verify(listener) .onMediaDataLoaded( Loading @@ -2008,7 +2008,7 @@ class LegacyMediaDataManagerImplTest(flags: FlagsParameterization) : SysuiTestCa .build() addNotificationAndLoad() stateCallbackCaptor.value.invoke(KEY, state) onStateUpdated(KEY, state) verify(listener) .onMediaDataLoaded( Loading Loading @@ -2518,4 +2518,10 @@ class LegacyMediaDataManagerImplTest(flags: FlagsParameterization) : SysuiTestCa eq(false), ) } private fun onStateUpdated(key: String, state: PlaybackState) { stateCallbackCaptor.value.invoke(key, state) backgroundExecutor.runAllReady() foregroundExecutor.runAllReady() } } packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataProcessorTest.kt +13 −6 Original line number Diff line number Diff line Loading @@ -1967,7 +1967,7 @@ class MediaDataProcessorTest(flags: FlagsParameterization) : SysuiTestCase() { // Callback gets an updated state val state = PlaybackState.Builder().setState(PlaybackState.STATE_PLAYING, 0L, 1f).build() stateCallbackCaptor.value.invoke(KEY, state) testScope.onStateUpdated(KEY, state) // Listener is notified of updated state verify(listener) Loading @@ -1988,7 +1988,7 @@ class MediaDataProcessorTest(flags: FlagsParameterization) : SysuiTestCase() { // No media added with this key stateCallbackCaptor.value.invoke(KEY, state) testScope.onStateUpdated(KEY, state) verify(listener, never()) .onMediaDataLoaded(eq(KEY), any(), any(), anyBoolean(), anyInt(), anyBoolean()) } Loading @@ -2005,7 +2005,7 @@ class MediaDataProcessorTest(flags: FlagsParameterization) : SysuiTestCase() { val state = PlaybackState.Builder().build() // Then no changes are made stateCallbackCaptor.value.invoke(KEY, state) testScope.onStateUpdated(KEY, state) verify(listener, never()) .onMediaDataLoaded(eq(KEY), any(), any(), anyBoolean(), anyInt(), anyBoolean()) } Loading @@ -2016,7 +2016,7 @@ class MediaDataProcessorTest(flags: FlagsParameterization) : SysuiTestCase() { whenever(controller.playbackState).thenReturn(state) addNotificationAndLoad() stateCallbackCaptor.value.invoke(KEY, state) testScope.onStateUpdated(KEY, state) verify(listener) .onMediaDataLoaded( Loading Loading @@ -2059,7 +2059,7 @@ class MediaDataProcessorTest(flags: FlagsParameterization) : SysuiTestCase() { backgroundExecutor.runAllReady() foregroundExecutor.runAllReady() stateCallbackCaptor.value.invoke(PACKAGE_NAME, state) testScope.onStateUpdated(PACKAGE_NAME, state) verify(listener) .onMediaDataLoaded( Loading @@ -2084,7 +2084,7 @@ class MediaDataProcessorTest(flags: FlagsParameterization) : SysuiTestCase() { .build() addNotificationAndLoad() stateCallbackCaptor.value.invoke(KEY, state) testScope.onStateUpdated(KEY, state) verify(listener) .onMediaDataLoaded( Loading Loading @@ -2603,4 +2603,11 @@ class MediaDataProcessorTest(flags: FlagsParameterization) : SysuiTestCase() { eq(false), ) } /** Helper function to update state and run executors */ private fun TestScope.onStateUpdated(key: String, state: PlaybackState) { stateCallbackCaptor.value.invoke(key, state) runCurrent() advanceUntilIdle() } } Loading
packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/LegacyMediaDataManagerImpl.kt +58 −59 Original line number Diff line number Diff line Loading @@ -111,7 +111,7 @@ private val ART_URIS = arrayOf( MediaMetadata.METADATA_KEY_ALBUM_ART_URI, MediaMetadata.METADATA_KEY_ART_URI, MediaMetadata.METADATA_KEY_DISPLAY_ICON_URI MediaMetadata.METADATA_KEY_DISPLAY_ICON_URI, ) private const val TAG = "MediaDataManager" Loading @@ -136,7 +136,7 @@ private val LOADING = active = true, resumeAction = null, instanceId = InstanceId.fakeInstanceId(-1), appUid = Process.INVALID_UID appUid = Process.INVALID_UID, ) internal val EMPTY_SMARTSPACE_MEDIA_DATA = Loading @@ -163,7 +163,7 @@ private fun allowMediaRecommendations(context: Context): Boolean { Settings.Secure.getInt( context.contentResolver, Settings.Secure.MEDIA_CONTROLS_RECOMMENDATION, 1 1, ) return Utils.useQsMediaPlayer(context) && flag > 0 } Loading Loading @@ -217,7 +217,7 @@ class LegacyMediaDataManagerImpl( private val themeText = com.android.settingslib.Utils.getColorAttr( context, com.android.internal.R.attr.textColorPrimary com.android.internal.R.attr.textColorPrimary, ) .defaultColor Loading Loading @@ -387,7 +387,7 @@ class LegacyMediaDataManagerImpl( uiExecutor, SmartspaceSession.OnTargetsAvailableListener { targets -> smartspaceMediaDataProvider.onTargetsAvailable(targets) } }, ) } smartspaceSession?.let { it.requestSmartspaceUpdate() } Loading @@ -398,12 +398,12 @@ class LegacyMediaDataManagerImpl( if (!allowMediaRecommendations) { dismissSmartspaceRecommendation( key = smartspaceMediaData.targetId, delay = 0L delay = 0L, ) } } }, Settings.Secure.MEDIA_CONTROLS_RECOMMENDATION Settings.Secure.MEDIA_CONTROLS_RECOMMENDATION, ) } Loading Loading @@ -461,7 +461,7 @@ class LegacyMediaDataManagerImpl( token: MediaSession.Token, appName: String, appIntent: PendingIntent, packageName: String packageName: String, ) { // Resume controls don't have a notification key, so store by package name instead if (!mediaEntries.containsKey(packageName)) { Loading Loading @@ -497,7 +497,7 @@ class LegacyMediaDataManagerImpl( token, appName, appIntent, packageName packageName, ) } } else { Loading @@ -509,7 +509,7 @@ class LegacyMediaDataManagerImpl( token, appName, appIntent, packageName packageName, ) } } Loading Loading @@ -609,14 +609,14 @@ class LegacyMediaDataManagerImpl( result.appUid, sbn.packageName, instanceId, result.playbackLocation result.playbackLocation, ) } else if (result.playbackLocation != currentEntry?.playbackLocation) { logger.logPlaybackLocationChange( result.appUid, sbn.packageName, instanceId, result.playbackLocation result.playbackLocation, ) } Loading Loading @@ -722,16 +722,17 @@ class LegacyMediaDataManagerImpl( /** Called when the player's [PlaybackState] has been updated with new actions and/or state */ private fun updateState(key: String, state: PlaybackState) { mediaEntries.get(key)?.let { backgroundExecutor.execute { val token = it.token if (token == null) { if (DEBUG) Log.d(TAG, "State updated, but token was null") return return@execute } val actions = createActionsFromState( it.packageName, mediaControllerFactory.create(it.token), UserHandle(it.userId) UserHandle(it.userId), ) // Control buttons Loading @@ -745,7 +746,8 @@ class LegacyMediaDataManagerImpl( it.copy(isPlaying = isPlayingState(state.state)) } if (DEBUG) Log.d(TAG, "State updated outside of notification") onMediaDataLoaded(key, key, data) foregroundExecutor.execute { onMediaDataLoaded(key, key, data) } } } } Loading Loading @@ -773,7 +775,7 @@ class LegacyMediaDataManagerImpl( } foregroundExecutor.executeDelayed( { removeEntry(key = key, userInitiated = userInitiated) }, delay delay, ) return existed } Loading @@ -793,12 +795,12 @@ class LegacyMediaDataManagerImpl( smartspaceMediaData = EMPTY_SMARTSPACE_MEDIA_DATA.copy( targetId = smartspaceMediaData.targetId, instanceId = smartspaceMediaData.instanceId instanceId = smartspaceMediaData.instanceId, ) } foregroundExecutor.executeDelayed( { notifySmartspaceMediaDataRemoved(smartspaceMediaData.targetId, immediately = true) }, delay delay, ) } Loading Loading @@ -826,7 +828,7 @@ class LegacyMediaDataManagerImpl( token: MediaSession.Token, appName: String, appIntent: PendingIntent, packageName: String packageName: String, ) = withContext(backgroundDispatcher) { val lastActive = systemClock.elapsedRealtime() Loading @@ -843,7 +845,7 @@ class LegacyMediaDataManagerImpl( token, appName, appIntent, packageName packageName, ) if (result == null || desc.title.isNullOrBlank()) { Log.d(TAG, "No MediaData result for resumption") Loading Loading @@ -882,7 +884,7 @@ class LegacyMediaDataManagerImpl( appUid = result.appUid, isExplicit = result.isExplicit, resumeProgress = result.resumeProgress, ) ), ) } } Loading @@ -895,7 +897,7 @@ class LegacyMediaDataManagerImpl( token: MediaSession.Token, appName: String, appIntent: PendingIntent, packageName: String packageName: String, ) { if (desc.title.isNullOrBlank()) { Log.e(TAG, "Description incomplete") Loading Loading @@ -966,7 +968,7 @@ class LegacyMediaDataManagerImpl( appUid = appUid, isExplicit = isExplicit, resumeProgress = progress, ) ), ) } } Loading @@ -981,7 +983,7 @@ class LegacyMediaDataManagerImpl( val token = sbn.notification.extras.getParcelable( Notification.EXTRA_MEDIA_SESSION, MediaSession.Token::class.java MediaSession.Token::class.java, ) if (token == null) { return Loading @@ -993,7 +995,7 @@ class LegacyMediaDataManagerImpl( val appInfo = notif.extras.getParcelable( Notification.EXTRA_BUILDER_APPLICATION_INFO, ApplicationInfo::class.java ApplicationInfo::class.java, ) ?: getAppInfoFromPackage(sbn.packageName) // App name Loading Loading @@ -1057,7 +1059,7 @@ class LegacyMediaDataManagerImpl( val deviceIntent = extras.getParcelable( Notification.EXTRA_MEDIA_REMOTE_INTENT, PendingIntent::class.java PendingIntent::class.java, ) Log.d(TAG, "$key is RCN for $deviceName") Loading @@ -1073,7 +1075,7 @@ class LegacyMediaDataManagerImpl( deviceDrawable, deviceName, deviceIntent, showBroadcastButton = false showBroadcastButton = false, ) } } Loading Loading @@ -1160,7 +1162,7 @@ class LegacyMediaDataManagerImpl( mediaData.copy( resumeAction = oldResumeAction, hasCheckedForResume = oldHasCheckedForResume, active = oldActive active = oldActive, ) onMediaDataLoaded(key, oldKey, mediaData) } Loading @@ -1169,7 +1171,7 @@ class LegacyMediaDataManagerImpl( private fun logSingleVsMultipleMediaAdded( appUid: Int, packageName: String, instanceId: InstanceId instanceId: InstanceId, ) { if (mediaEntries.size == 1) { logger.logSingleMediaPlayerInCarousel(appUid, packageName, instanceId) Loading Loading @@ -1207,7 +1209,7 @@ class LegacyMediaDataManagerImpl( private fun createActionsFromState( packageName: String, controller: MediaController, user: UserHandle user: UserHandle, ): MediaButton? { if (!mediaFlags.areMediaSessionActionsEnabled(packageName, user)) { return null Loading Loading @@ -1245,7 +1247,7 @@ class LegacyMediaDataManagerImpl( packageName, ContentProvider.getUriWithoutUserId(uri), Intent.FLAG_GRANT_READ_URI_PERMISSION, ContentProvider.getUserIdFromUri(uri, userId) ContentProvider.getUserIdFromUri(uri, userId), ) return loadBitmapFromUri(uri) } catch (e: SecurityException) { Loading Loading @@ -1282,7 +1284,7 @@ class LegacyMediaDataManagerImpl( val scale = MediaDataUtils.getScaleFactor( APair(width, height), APair(artworkWidth, artworkHeight) APair(artworkWidth, artworkHeight), ) // Downscale if needed Loading @@ -1307,7 +1309,7 @@ class LegacyMediaDataManagerImpl( .loadDrawable(context), action, context.getString(R.string.controls_media_resume), context.getDrawable(R.drawable.ic_media_play_container) context.getDrawable(R.drawable.ic_media_play_container), ) } Loading Loading @@ -1371,10 +1373,7 @@ class LegacyMediaDataManagerImpl( // There should NOT be more than 1 Smartspace media update. When it happens, it // indicates a bad state or an error. Reset the status accordingly. Log.wtf(TAG, "More than 1 Smartspace Media Update. Resetting the status...") notifySmartspaceMediaDataRemoved( smartspaceMediaData.targetId, immediately = false, ) notifySmartspaceMediaDataRemoved(smartspaceMediaData.targetId, immediately = false) smartspaceMediaData = EMPTY_SMARTSPACE_MEDIA_DATA } } Loading Loading @@ -1420,7 +1419,7 @@ class LegacyMediaDataManagerImpl( private fun handlePossibleRemoval( key: String, removed: MediaData, notificationRemoved: Boolean = false notificationRemoved: Boolean = false, ) { val hasSession = removed.token != null if (hasSession && removed.semanticActions != null) { Loading @@ -1445,7 +1444,7 @@ class LegacyMediaDataManagerImpl( Log.d( TAG, "Notification ($notificationRemoved) and/or session " + "($hasSession) gone for inactive player $key" "($hasSession) gone for inactive player $key", ) } convertToResumePlayer(key, removed) Loading
packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaActions.kt +18 −16 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.systemui.media.controls.domain.pipeline import android.annotation.WorkerThread import android.app.ActivityOptions import android.app.BroadcastOptions import android.app.Notification Loading Loading @@ -50,6 +51,7 @@ private const val TAG = "MediaActions" * @return a Pair consisting of a list of media actions, and a list of ints representing which of * those actions should be shown in the compact player */ @WorkerThread fun createActionsFromState( context: Context, packageName: String, Loading @@ -69,7 +71,7 @@ fun createActionsFromState( context.getString(R.string.controls_media_button_connecting), context.getDrawable(R.drawable.ic_media_connecting_container), // Specify a rebind id to prevent the spinner from restarting on later binds. com.android.internal.R.drawable.progress_small_material com.android.internal.R.drawable.progress_small_material, ) } else if (isPlayingState(state.state)) { getStandardAction(context, controller, state.actions, PlaybackState.ACTION_PAUSE) Loading Loading @@ -128,7 +130,7 @@ fun createActionsFromState( nextCustomAction(), nextCustomAction(), reserveNext, reservePrev reservePrev, ) } Loading @@ -146,7 +148,7 @@ private fun getStandardAction( context: Context, controller: MediaController, stateActions: Long, @PlaybackState.Actions action: Long @PlaybackState.Actions action: Long, ): MediaAction? { if (!includesAction(stateActions, action)) { return null Loading @@ -158,7 +160,7 @@ private fun getStandardAction( context.getDrawable(R.drawable.ic_media_play), { controller.transportControls.play() }, context.getString(R.string.controls_media_button_play), context.getDrawable(R.drawable.ic_media_play_container) context.getDrawable(R.drawable.ic_media_play_container), ) } PlaybackState.ACTION_PAUSE -> { Loading @@ -166,7 +168,7 @@ private fun getStandardAction( context.getDrawable(R.drawable.ic_media_pause), { controller.transportControls.pause() }, context.getString(R.string.controls_media_button_pause), context.getDrawable(R.drawable.ic_media_pause_container) context.getDrawable(R.drawable.ic_media_pause_container), ) } PlaybackState.ACTION_SKIP_TO_PREVIOUS -> { Loading @@ -174,7 +176,7 @@ private fun getStandardAction( MediaControlDrawables.getPrevIcon(context), { controller.transportControls.skipToPrevious() }, context.getString(R.string.controls_media_button_prev), null null, ) } PlaybackState.ACTION_SKIP_TO_NEXT -> { Loading @@ -182,7 +184,7 @@ private fun getStandardAction( MediaControlDrawables.getNextIcon(context), { controller.transportControls.skipToNext() }, context.getString(R.string.controls_media_button_next), null null, ) } else -> null Loading @@ -194,13 +196,13 @@ private fun getCustomAction( context: Context, packageName: String, controller: MediaController, customAction: PlaybackState.CustomAction customAction: PlaybackState.CustomAction, ): MediaAction { return MediaAction( Icon.createWithResource(packageName, customAction.icon).loadDrawable(context), { controller.transportControls.sendCustomAction(customAction, customAction.extras) }, customAction.name, null null, ) } Loading @@ -218,7 +220,7 @@ private fun includesAction(stateActions: Long, @PlaybackState.Actions action: Lo /** Generate action buttons based on notification actions */ fun createActionsFromNotification( context: Context, sbn: StatusBarNotification sbn: StatusBarNotification, ): Pair<List<MediaNotificationAction>, List<Int>> { val notif = sbn.notification val actionIcons: MutableList<MediaNotificationAction> = ArrayList() Loading @@ -229,7 +231,7 @@ fun createActionsFromNotification( if (actionsToShowCollapsed.size > MAX_COMPACT_ACTIONS) { Log.e( TAG, "Too many compact actions for ${sbn.key}, limiting to first $MAX_COMPACT_ACTIONS" "Too many compact actions for ${sbn.key}, limiting to first $MAX_COMPACT_ACTIONS", ) actionsToShowCollapsed = actionsToShowCollapsed.subList(0, MAX_COMPACT_ACTIONS) } Loading @@ -239,7 +241,7 @@ fun createActionsFromNotification( Log.w( TAG, "Too many notification actions for ${sbn.key}, " + "limiting to first $MAX_NOTIFICATION_ACTIONS" "limiting to first $MAX_NOTIFICATION_ACTIONS", ) } Loading @@ -253,7 +255,7 @@ fun createActionsFromNotification( val themeText = com.android.settingslib.Utils.getColorAttr( context, com.android.internal.R.attr.textColorPrimary com.android.internal.R.attr.textColorPrimary, ) .defaultColor Loading @@ -271,7 +273,7 @@ fun createActionsFromNotification( action.isAuthenticationRequired, action.actionIntent, mediaActionIcon, action.title action.title, ) actionIcons.add(mediaAction) } Loading @@ -288,7 +290,7 @@ fun createActionsFromNotification( */ fun getNotificationActions( actions: List<MediaNotificationAction>, activityStarter: ActivityStarter activityStarter: ActivityStarter, ): List<MediaAction> { return actions.map { action -> val runnable = Loading @@ -303,7 +305,7 @@ fun getNotificationActions( activityStarter.dismissKeyguardThenExecute( { sendPendingIntent(action.actionIntent) }, {}, true true, ) else -> sendPendingIntent(actionIntent) } Loading
packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDataProcessor.kt +60 −53 File changed.Preview size limit exceeded, changes collapsed. Show changes
packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/LegacyMediaDataManagerImplTest.kt +12 −6 Original line number Diff line number Diff line Loading @@ -1890,7 +1890,7 @@ class LegacyMediaDataManagerImplTest(flags: FlagsParameterization) : SysuiTestCa // Callback gets an updated state val state = PlaybackState.Builder().setState(PlaybackState.STATE_PLAYING, 0L, 1f).build() stateCallbackCaptor.value.invoke(KEY, state) onStateUpdated(KEY, state) // Listener is notified of updated state verify(listener) Loading @@ -1911,7 +1911,7 @@ class LegacyMediaDataManagerImplTest(flags: FlagsParameterization) : SysuiTestCa // No media added with this key stateCallbackCaptor.value.invoke(KEY, state) onStateUpdated(KEY, state) verify(listener, never()) .onMediaDataLoaded(eq(KEY), any(), any(), anyBoolean(), anyInt(), anyBoolean()) } Loading @@ -1928,7 +1928,7 @@ class LegacyMediaDataManagerImplTest(flags: FlagsParameterization) : SysuiTestCa val state = PlaybackState.Builder().build() // Then no changes are made stateCallbackCaptor.value.invoke(KEY, state) onStateUpdated(KEY, state) verify(listener, never()) .onMediaDataLoaded(eq(KEY), any(), any(), anyBoolean(), anyInt(), anyBoolean()) } Loading @@ -1939,7 +1939,7 @@ class LegacyMediaDataManagerImplTest(flags: FlagsParameterization) : SysuiTestCa whenever(controller.playbackState).thenReturn(state) addNotificationAndLoad() stateCallbackCaptor.value.invoke(KEY, state) onStateUpdated(KEY, state) verify(listener) .onMediaDataLoaded( Loading Loading @@ -1983,7 +1983,7 @@ class LegacyMediaDataManagerImplTest(flags: FlagsParameterization) : SysuiTestCa backgroundExecutor.runAllReady() foregroundExecutor.runAllReady() stateCallbackCaptor.value.invoke(PACKAGE_NAME, state) onStateUpdated(PACKAGE_NAME, state) verify(listener) .onMediaDataLoaded( Loading @@ -2008,7 +2008,7 @@ class LegacyMediaDataManagerImplTest(flags: FlagsParameterization) : SysuiTestCa .build() addNotificationAndLoad() stateCallbackCaptor.value.invoke(KEY, state) onStateUpdated(KEY, state) verify(listener) .onMediaDataLoaded( Loading Loading @@ -2518,4 +2518,10 @@ class LegacyMediaDataManagerImplTest(flags: FlagsParameterization) : SysuiTestCa eq(false), ) } private fun onStateUpdated(key: String, state: PlaybackState) { stateCallbackCaptor.value.invoke(key, state) backgroundExecutor.runAllReady() foregroundExecutor.runAllReady() } }
packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataProcessorTest.kt +13 −6 Original line number Diff line number Diff line Loading @@ -1967,7 +1967,7 @@ class MediaDataProcessorTest(flags: FlagsParameterization) : SysuiTestCase() { // Callback gets an updated state val state = PlaybackState.Builder().setState(PlaybackState.STATE_PLAYING, 0L, 1f).build() stateCallbackCaptor.value.invoke(KEY, state) testScope.onStateUpdated(KEY, state) // Listener is notified of updated state verify(listener) Loading @@ -1988,7 +1988,7 @@ class MediaDataProcessorTest(flags: FlagsParameterization) : SysuiTestCase() { // No media added with this key stateCallbackCaptor.value.invoke(KEY, state) testScope.onStateUpdated(KEY, state) verify(listener, never()) .onMediaDataLoaded(eq(KEY), any(), any(), anyBoolean(), anyInt(), anyBoolean()) } Loading @@ -2005,7 +2005,7 @@ class MediaDataProcessorTest(flags: FlagsParameterization) : SysuiTestCase() { val state = PlaybackState.Builder().build() // Then no changes are made stateCallbackCaptor.value.invoke(KEY, state) testScope.onStateUpdated(KEY, state) verify(listener, never()) .onMediaDataLoaded(eq(KEY), any(), any(), anyBoolean(), anyInt(), anyBoolean()) } Loading @@ -2016,7 +2016,7 @@ class MediaDataProcessorTest(flags: FlagsParameterization) : SysuiTestCase() { whenever(controller.playbackState).thenReturn(state) addNotificationAndLoad() stateCallbackCaptor.value.invoke(KEY, state) testScope.onStateUpdated(KEY, state) verify(listener) .onMediaDataLoaded( Loading Loading @@ -2059,7 +2059,7 @@ class MediaDataProcessorTest(flags: FlagsParameterization) : SysuiTestCase() { backgroundExecutor.runAllReady() foregroundExecutor.runAllReady() stateCallbackCaptor.value.invoke(PACKAGE_NAME, state) testScope.onStateUpdated(PACKAGE_NAME, state) verify(listener) .onMediaDataLoaded( Loading @@ -2084,7 +2084,7 @@ class MediaDataProcessorTest(flags: FlagsParameterization) : SysuiTestCase() { .build() addNotificationAndLoad() stateCallbackCaptor.value.invoke(KEY, state) testScope.onStateUpdated(KEY, state) verify(listener) .onMediaDataLoaded( Loading Loading @@ -2603,4 +2603,11 @@ class MediaDataProcessorTest(flags: FlagsParameterization) : SysuiTestCase() { eq(false), ) } /** Helper function to update state and run executors */ private fun TestScope.onStateUpdated(key: String, state: PlaybackState) { stateCallbackCaptor.value.invoke(key, state) runCurrent() advanceUntilIdle() } }