From 8a2af3b3bd00aba8fe5a50026d61252799b9da5f Mon Sep 17 00:00:00 2001 From: Beth Thibodeau Date: Tue, 26 May 2020 19:57:42 -0400 Subject: [PATCH] Fix CME crashes Create a copy of the listeners list before iterating over it, and add an assert for notification entry updates Those should only happen on the main thread, so adding the assert will allow us to find if that is not happening somewhere in the notification pipeline. Fixes: 156863310 Test: manual Change-Id: I157dafdba0c1cecb26dd7e969f3be26ca4e45472 --- .../src/com/android/systemui/media/MediaDataManager.kt | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt index 009f5494cefeb..cf7fbfa9461ee 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt @@ -36,6 +36,7 @@ import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.statusbar.notification.MediaNotificationProcessor import com.android.systemui.statusbar.notification.row.HybridGroupManager +import com.android.systemui.util.Assert import com.android.systemui.util.Utils import java.io.IOException import java.util.concurrent.Executor @@ -85,6 +86,7 @@ class MediaDataManager @Inject constructor( fun onNotificationAdded(key: String, sbn: StatusBarNotification) { if (Utils.useQsMediaPlayer(context) && isMediaNotification(sbn)) { + Assert.isMainThread() if (!mediaEntries.containsKey(key)) { mediaEntries.put(key, LOADING) } @@ -269,19 +271,23 @@ class MediaDataManager @Inject constructor( } fun onMediaDataLoaded(key: String, data: MediaData) { + Assert.isMainThread() if (mediaEntries.containsKey(key)) { // Otherwise this was removed already mediaEntries.put(key, data) - listeners.forEach { + val listenersCopy = listeners.toSet() + listenersCopy.forEach { it.onMediaDataLoaded(key, data) } } } fun onNotificationRemoved(key: String) { + Assert.isMainThread() val removed = mediaEntries.remove(key) if (removed != null) { - listeners.forEach { + val listenersCopy = listeners.toSet() + listenersCopy.forEach { it.onMediaDataRemoved(key) } }