Use concurrent list to prevent ConcurrentModificationException

TasksRepository.setVisibleTasks can add/remove listeners while HighResLoadingState.updateState iterates over them.

Bug: 408978565
Flag: com.android.launcher3.enable_refactor_task_thumbnail
Test: SwitchBackToSplitFromRecentGesturalNavLandscape#switchBackToSplitFromRecent
Test: Manual - made exception extremely likely by constantly adding/removing listeners. Could easily repro exceptions, then added this CL and could no longer repro.
Change-Id: Ic04717527fcbdb9301a6e313f9e666e2f5135b3e
This commit is contained in:
Uwais Ashraf
2025-04-12 00:38:19 +00:00
parent 7dce980f9a
commit 4dc3313044
@@ -18,6 +18,7 @@ package com.android.quickstep
import android.content.res.Resources
import com.android.quickstep.recents.data.HighResLoadingStateNotifier
import java.util.concurrent.CopyOnWriteArrayList
/** Determines when high res or low res thumbnails should be loaded. */
class HighResLoadingState : HighResLoadingStateNotifier {
@@ -38,7 +39,7 @@ class HighResLoadingState : HighResLoadingStateNotifier {
var isEnabled: Boolean = false
private set
private val callbacks = ArrayList<HighResLoadingStateChangedCallback>()
private val callbacks = CopyOnWriteArrayList<HighResLoadingStateChangedCallback>()
interface HighResLoadingStateChangedCallback {
fun onHighResLoadingStateChanged(enabled: Boolean)
@@ -56,7 +57,7 @@ class HighResLoadingState : HighResLoadingStateNotifier {
val prevState = isEnabled
isEnabled = forceHighResThumbnails || (visible && !flingingFast)
if (prevState != isEnabled) {
for (callback in callbacks.asReversed()) {
for (callback in callbacks) {
callback.onHighResLoadingStateChanged(isEnabled)
}
}