Merge "Prevent NPE issues when removing media" into tm-qpr-dev

This commit is contained in:
Beth Thibodeau
2023-02-14 21:59:09 +00:00
committed by Android (Google) Code Review
2 changed files with 24 additions and 8 deletions

View File

@@ -1343,9 +1343,9 @@ class MediaDataManager(
if (keyguardUpdateMonitor.isUserInLockdown(removed.userId)) { if (keyguardUpdateMonitor.isUserInLockdown(removed.userId)) {
logger.logMediaRemoved(removed.appUid, removed.packageName, removed.instanceId) logger.logMediaRemoved(removed.appUid, removed.packageName, removed.instanceId)
} else if (useMediaResumption && removed.resumeAction != null && removed.isLocalSession()) { } else if (useMediaResumption && removed.resumeAction != null && removed.isLocalSession()) {
convertToResumePlayer(removed) convertToResumePlayer(key, removed)
} else if (mediaFlags.isRetainingPlayersEnabled()) { } else if (mediaFlags.isRetainingPlayersEnabled()) {
handlePossibleRemoval(removed, notificationRemoved = true) handlePossibleRemoval(key, removed, notificationRemoved = true)
} else { } else {
notifyMediaDataRemoved(key) notifyMediaDataRemoved(key)
logger.logMediaRemoved(removed.appUid, removed.packageName, removed.instanceId) logger.logMediaRemoved(removed.appUid, removed.packageName, removed.instanceId)
@@ -1359,7 +1359,7 @@ class MediaDataManager(
val entry = mediaEntries.remove(key) ?: return val entry = mediaEntries.remove(key) ?: return
// Clear token since the session is no longer valid // Clear token since the session is no longer valid
val updated = entry.copy(token = null) val updated = entry.copy(token = null)
handlePossibleRemoval(updated) handlePossibleRemoval(key, updated)
} }
/** /**
@@ -1368,8 +1368,11 @@ class MediaDataManager(
* if it was removed before becoming inactive. (Assumes that [removed] was removed from * if it was removed before becoming inactive. (Assumes that [removed] was removed from
* [mediaEntries] before this function was called) * [mediaEntries] before this function was called)
*/ */
private fun handlePossibleRemoval(removed: MediaData, notificationRemoved: Boolean = false) { private fun handlePossibleRemoval(
val key = removed.notificationKey!! key: String,
removed: MediaData,
notificationRemoved: Boolean = false
) {
val hasSession = removed.token != null val hasSession = removed.token != null
if (hasSession && removed.semanticActions != null) { if (hasSession && removed.semanticActions != null) {
// The app was using session actions, and the session is still valid: keep player // The app was using session actions, and the session is still valid: keep player
@@ -1395,13 +1398,12 @@ class MediaDataManager(
"($hasSession) gone for inactive player $key" "($hasSession) gone for inactive player $key"
) )
} }
convertToResumePlayer(removed) convertToResumePlayer(key, removed)
} }
} }
/** Set the given [MediaData] as a resume state player and notify listeners */ /** Set the given [MediaData] as a resume state player and notify listeners */
private fun convertToResumePlayer(data: MediaData) { private fun convertToResumePlayer(key: String, data: MediaData) {
val key = data.notificationKey!!
if (DEBUG) Log.d(TAG, "Converting $key to resume") if (DEBUG) Log.d(TAG, "Converting $key to resume")
// Move to resume key (aka package name) if that key doesn't already exist. // Move to resume key (aka package name) if that key doesn't already exist.
val resumeAction = data.resumeAction?.let { getResumeMediaAction(it) } val resumeAction = data.resumeAction?.let { getResumeMediaAction(it) }

View File

@@ -1897,6 +1897,20 @@ class MediaDataManagerTest : SysuiTestCase() {
.onMediaDataLoaded(eq(PACKAGE_NAME), any(), any(), anyBoolean(), anyInt(), anyBoolean()) .onMediaDataLoaded(eq(PACKAGE_NAME), any(), any(), anyBoolean(), anyInt(), anyBoolean())
} }
@Test
fun testSessionDestroyed_noNotificationKey_stillRemoved() {
whenever(mediaFlags.isRetainingPlayersEnabled()).thenReturn(true)
whenever(mediaFlags.areMediaSessionActionsEnabled(any(), any())).thenReturn(true)
// When a notiifcation is added and then removed before it is fully processed
mediaDataManager.onNotificationAdded(KEY, mediaNotification)
backgroundExecutor.runAllReady()
mediaDataManager.onNotificationRemoved(KEY)
// We still make sure to remove it
verify(listener).onMediaDataRemoved(eq(KEY))
}
/** Helper function to add a media notification and capture the resulting MediaData */ /** Helper function to add a media notification and capture the resulting MediaData */
private fun addNotificationAndLoad() { private fun addNotificationAndLoad() {
mediaDataManager.onNotificationAdded(KEY, mediaNotification) mediaDataManager.onNotificationAdded(KEY, mediaNotification)