From 4c045988c1ea768f2279245236847d7f17c01625 Mon Sep 17 00:00:00 2001 From: Uwais Ashraf Date: Wed, 18 Sep 2024 05:47:29 +0000 Subject: [PATCH] Revert^2 "Use ConcurrentHashMap to make private maps thread safe" This reverts commit f480cf371a199c92eee26adebafc2c72a41129f0. Reason for revert: not the cause of b/367736714 Change-Id: If9b400c5474d9ec51f51f1de86c80b9337857fac --- .../com/android/quickstep/RecentsModel.java | 12 ++-- .../data/TaskVisualsChangedDelegate.kt | 72 +++++++++---------- 2 files changed, 43 insertions(+), 41 deletions(-) diff --git a/quickstep/src/com/android/quickstep/RecentsModel.java b/quickstep/src/com/android/quickstep/RecentsModel.java index a01ceb2446..d073580fb5 100644 --- a/quickstep/src/com/android/quickstep/RecentsModel.java +++ b/quickstep/src/com/android/quickstep/RecentsModel.java @@ -56,6 +56,7 @@ import com.android.systemui.shared.system.TaskStackChangeListeners; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.function.Consumer; @@ -76,7 +77,8 @@ public class RecentsModel implements RecentTasksDataSource, IconChangeListener, private static final Executor RECENTS_MODEL_EXECUTOR = Executors.newSingleThreadExecutor( new SimpleThreadFactory("TaskThumbnailIconCache-", THREAD_PRIORITY_BACKGROUND)); - private final List mThumbnailChangeListeners = new ArrayList<>(); + private final ConcurrentLinkedQueue mThumbnailChangeListeners = + new ConcurrentLinkedQueue<>(); private final Context mContext; private final RecentTasksList mTaskList; @@ -239,8 +241,8 @@ public class RecentsModel implements RecentTasksDataSource, IconChangeListener, public boolean onTaskSnapshotChanged(int taskId, ThumbnailData snapshot) { mThumbnailCache.updateTaskSnapShot(taskId, snapshot); - for (int i = mThumbnailChangeListeners.size() - 1; i >= 0; i--) { - Task task = mThumbnailChangeListeners.get(i).onTaskThumbnailChanged(taskId, snapshot); + for (TaskVisualsChangeListener listener : mThumbnailChangeListeners) { + Task task = listener.onTaskThumbnailChanged(taskId, snapshot); if (task != null) { task.thumbnail = snapshot; } @@ -269,8 +271,8 @@ public class RecentsModel implements RecentTasksDataSource, IconChangeListener, @Override public void onAppIconChanged(String packageName, UserHandle user) { mIconCache.invalidateCacheEntries(packageName, user); - for (int i = mThumbnailChangeListeners.size() - 1; i >= 0; i--) { - mThumbnailChangeListeners.get(i).onTaskIconChanged(packageName, user); + for (TaskVisualsChangeListener listener : mThumbnailChangeListeners) { + listener.onTaskIconChanged(packageName, user); } } diff --git a/quickstep/src/com/android/quickstep/recents/data/TaskVisualsChangedDelegate.kt b/quickstep/src/com/android/quickstep/recents/data/TaskVisualsChangedDelegate.kt index a141e89c23..a45d194a1c 100644 --- a/quickstep/src/com/android/quickstep/recents/data/TaskVisualsChangedDelegate.kt +++ b/quickstep/src/com/android/quickstep/recents/data/TaskVisualsChangedDelegate.kt @@ -23,6 +23,7 @@ import com.android.quickstep.recents.data.TaskVisualsChangedDelegate.TaskThumbna import com.android.quickstep.util.TaskVisualsChangeListener import com.android.systemui.shared.recents.model.Task import com.android.systemui.shared.recents.model.ThumbnailData +import java.util.concurrent.ConcurrentHashMap /** Delegates the checking of task visuals (thumbnails, high res changes, icons) */ interface TaskVisualsChangedDelegate : @@ -30,7 +31,7 @@ interface TaskVisualsChangedDelegate : /** Registers a callback for visuals relating to icons */ fun registerTaskIconChangedCallback( taskKey: Task.TaskKey, - taskIconChangedCallback: TaskIconChangedCallback + taskIconChangedCallback: TaskIconChangedCallback, ) /** Unregisters a callback for visuals relating to icons */ @@ -39,7 +40,7 @@ interface TaskVisualsChangedDelegate : /** Registers a callback for visuals relating to thumbnails */ fun registerTaskThumbnailChangedCallback( taskKey: Task.TaskKey, - taskThumbnailChangedCallback: TaskThumbnailChangedCallback + taskThumbnailChangedCallback: TaskThumbnailChangedCallback, ) /** Unregisters a callback for visuals relating to thumbnails */ @@ -66,31 +67,9 @@ class TaskVisualsChangedDelegateImpl( private val highResLoadingStateNotifier: HighResLoadingStateNotifier, ) : TaskVisualsChangedDelegate { private val taskIconChangedCallbacks = - mutableMapOf>() + ConcurrentHashMap>() private val taskThumbnailChangedCallbacks = - mutableMapOf>() - private var isListening = false - - @Synchronized - private fun onCallbackRegistered() { - if (isListening) return - - taskVisualsChangeNotifier.addThumbnailChangeListener(this) - highResLoadingStateNotifier.addCallback(this) - isListening = true - } - - @Synchronized - private fun onCallbackUnregistered() { - if (!isListening) return - - if (taskIconChangedCallbacks.size + taskThumbnailChangedCallbacks.size == 0) { - taskVisualsChangeNotifier.removeThumbnailChangeListener(this) - highResLoadingStateNotifier.removeCallback(this) - } - - isListening = false - } + ConcurrentHashMap>() override fun onTaskIconChanged(taskId: Int) { taskIconChangedCallbacks[taskId]?.let { (_, callback) -> callback.onTaskIconChanged() } @@ -119,27 +98,48 @@ class TaskVisualsChangedDelegateImpl( override fun registerTaskIconChangedCallback( taskKey: Task.TaskKey, - taskIconChangedCallback: TaskIconChangedCallback + taskIconChangedCallback: TaskIconChangedCallback, ) { - taskIconChangedCallbacks[taskKey.id] = taskKey to taskIconChangedCallback - onCallbackRegistered() + updateCallbacks { + taskIconChangedCallbacks[taskKey.id] = taskKey to taskIconChangedCallback + } } override fun unregisterTaskIconChangedCallback(taskKey: Task.TaskKey) { - taskIconChangedCallbacks.remove(taskKey.id) - onCallbackUnregistered() + updateCallbacks { taskIconChangedCallbacks.remove(taskKey.id) } } override fun registerTaskThumbnailChangedCallback( taskKey: Task.TaskKey, - taskThumbnailChangedCallback: TaskThumbnailChangedCallback + taskThumbnailChangedCallback: TaskThumbnailChangedCallback, ) { - taskThumbnailChangedCallbacks[taskKey.id] = taskKey to taskThumbnailChangedCallback - onCallbackRegistered() + updateCallbacks { + taskThumbnailChangedCallbacks[taskKey.id] = taskKey to taskThumbnailChangedCallback + } } override fun unregisterTaskThumbnailChangedCallback(taskKey: Task.TaskKey) { - taskThumbnailChangedCallbacks.remove(taskKey.id) - onCallbackUnregistered() + updateCallbacks { taskThumbnailChangedCallbacks.remove(taskKey.id) } + } + + @Synchronized + private fun updateCallbacks(callbackModifier: () -> Unit) { + val prevHasCallbacks = + taskIconChangedCallbacks.size + taskThumbnailChangedCallbacks.size > 0 + callbackModifier() + + val currHasCallbacks = + taskIconChangedCallbacks.size + taskThumbnailChangedCallbacks.size > 0 + + when { + prevHasCallbacks && !currHasCallbacks -> { + taskVisualsChangeNotifier.removeThumbnailChangeListener(this) + highResLoadingStateNotifier.removeCallback(this) + } + !prevHasCallbacks && currHasCallbacks -> { + taskVisualsChangeNotifier.addThumbnailChangeListener(this) + highResLoadingStateNotifier.addCallback(this) + } + } } }