Merge "Prevent NPE issues when removing media" into tm-qpr-dev am: 22530aa35b
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/21407257
Change-Id: Ifb05b37cfae0123fed66960f29421b5bb366d581
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDataManager.kt b/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDataManager.kt
index 520edef..f5558a2 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDataManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDataManager.kt
@@ -1343,9 +1343,9 @@
if (keyguardUpdateMonitor.isUserInLockdown(removed.userId)) {
logger.logMediaRemoved(removed.appUid, removed.packageName, removed.instanceId)
} else if (useMediaResumption && removed.resumeAction != null && removed.isLocalSession()) {
- convertToResumePlayer(removed)
+ convertToResumePlayer(key, removed)
} else if (mediaFlags.isRetainingPlayersEnabled()) {
- handlePossibleRemoval(removed, notificationRemoved = true)
+ handlePossibleRemoval(key, removed, notificationRemoved = true)
} else {
notifyMediaDataRemoved(key)
logger.logMediaRemoved(removed.appUid, removed.packageName, removed.instanceId)
@@ -1359,7 +1359,7 @@
val entry = mediaEntries.remove(key) ?: return
// Clear token since the session is no longer valid
val updated = entry.copy(token = null)
- handlePossibleRemoval(updated)
+ handlePossibleRemoval(key, updated)
}
/**
@@ -1368,8 +1368,11 @@
* if it was removed before becoming inactive. (Assumes that [removed] was removed from
* [mediaEntries] before this function was called)
*/
- private fun handlePossibleRemoval(removed: MediaData, notificationRemoved: Boolean = false) {
- val key = removed.notificationKey!!
+ private fun handlePossibleRemoval(
+ key: String,
+ removed: MediaData,
+ notificationRemoved: Boolean = false
+ ) {
val hasSession = removed.token != null
if (hasSession && removed.semanticActions != null) {
// The app was using session actions, and the session is still valid: keep player
@@ -1395,13 +1398,12 @@
"($hasSession) gone for inactive player $key"
)
}
- convertToResumePlayer(removed)
+ convertToResumePlayer(key, removed)
}
}
/** Set the given [MediaData] as a resume state player and notify listeners */
- private fun convertToResumePlayer(data: MediaData) {
- val key = data.notificationKey!!
+ private fun convertToResumePlayer(key: String, data: MediaData) {
if (DEBUG) Log.d(TAG, "Converting $key to resume")
// Move to resume key (aka package name) if that key doesn't already exist.
val resumeAction = data.resumeAction?.let { getResumeMediaAction(it) }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDataManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDataManagerTest.kt
index 9f12329..a07a714 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDataManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDataManagerTest.kt
@@ -1897,6 +1897,20 @@
.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 */
private fun addNotificationAndLoad() {
mediaDataManager.onNotificationAdded(KEY, mediaNotification)