diff --git a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchController.java b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchController.java index 358d703b75..46501c4fc8 100644 --- a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchController.java +++ b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchController.java @@ -245,11 +245,20 @@ public final class KeyboardQuickSwitchController implements } void updateThumbnailInBackground(Task task, Consumer callback) { - mModel.getThumbnailCache().updateThumbnailInBackground(task, callback); + mModel.getThumbnailCache().getThumbnailInBackground(task, + thumbnailData -> { + task.thumbnail = thumbnailData; + callback.accept(thumbnailData); + }); } void updateIconInBackground(Task task, Consumer callback) { - mModel.getIconCache().updateIconInBackground(task, callback); + mModel.getIconCache().getIconInBackground(task, (icon, contentDescription, title) -> { + task.icon = icon; + task.titleDescription = contentDescription; + task.title = title; + callback.accept(task); + }); } void onCloseComplete() { diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarRecentAppsController.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarRecentAppsController.kt index fc3b4c758e..dbebdb2ae5 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarRecentAppsController.kt +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarRecentAppsController.kt @@ -24,11 +24,9 @@ import com.android.launcher3.util.CancellableTask import com.android.quickstep.RecentsModel import com.android.quickstep.util.DesktopTask import com.android.quickstep.util.GroupTask -import com.android.systemui.shared.recents.model.Task import com.android.window.flags.Flags.enableDesktopWindowingMode import com.android.window.flags.Flags.enableDesktopWindowingTaskbarRunningApps import java.io.PrintWriter -import java.util.function.Consumer /** * Provides recent apps functionality, when the Taskbar Recent Apps section is enabled. Behavior: @@ -166,9 +164,16 @@ class TaskbarRecentAppsController( for (groupTask in shownTasks) { for (task in groupTask.tasks) { - val callback = - Consumer { controllers.taskbarViewController.onTaskUpdated(it) } - val cancellableTask = recentsModel.iconCache.updateIconInBackground(task, callback) + val cancellableTask = + recentsModel.iconCache.getIconInBackground(task) { + icon, + contentDescription, + title -> + task.icon = icon + task.titleDescription = contentDescription + task.title = title + controllers.taskbarViewController.onTaskUpdated(task) + } if (cancellableTask != null) { iconLoadRequests.add(cancellableTask) } diff --git a/quickstep/src/com/android/quickstep/TaskIconCache.java b/quickstep/src/com/android/quickstep/TaskIconCache.java index e6febff5f7..b3a9199bf9 100644 --- a/quickstep/src/com/android/quickstep/TaskIconCache.java +++ b/quickstep/src/com/android/quickstep/TaskIconCache.java @@ -55,7 +55,6 @@ import com.android.systemui.shared.recents.model.Task.TaskKey; import com.android.systemui.shared.system.PackageManagerWrapper; import java.util.concurrent.Executor; -import java.util.function.Consumer; /** * Manages the caching of task icons and related data. @@ -103,21 +102,21 @@ public class TaskIconCache implements DisplayInfoChangeListener { * @param callback The callback to receive the task after its data has been populated. * @return A cancelable handle to the request */ - public CancellableTask updateIconInBackground(Task task, Consumer callback) { + public CancellableTask getIconInBackground(Task task, GetTaskIconCallback callback) { Preconditions.assertUIThread(); if (task.icon != null) { // Nothing to load, the icon is already loaded - callback.accept(task); + callback.onTaskIconReceived(task.icon, task.titleDescription, task.title); return null; } CancellableTask request = new CancellableTask<>( () -> getCacheEntry(task), MAIN_EXECUTOR, result -> { - task.icon = result.icon; - task.titleDescription = result.contentDescription; - task.title = result.title; - callback.accept(task); + callback.onTaskIconReceived( + result.icon, + result.contentDescription, + result.title); dispatchIconUpdate(task.key.id); } ); @@ -280,6 +279,12 @@ public class TaskIconCache implements DisplayInfoChangeListener { public String title = ""; } + /** Callback used when retrieving app icons from cache. */ + public interface GetTaskIconCallback { + /** Called when task icon is retrieved. */ + void onTaskIconReceived(Drawable icon, String contentDescription, String title); + } + void registerTaskVisualsChangeListener(TaskVisualsChangeListener newListener) { mTaskVisualsChangeListener = newListener; } diff --git a/quickstep/src/com/android/quickstep/TaskThumbnailCache.java b/quickstep/src/com/android/quickstep/TaskThumbnailCache.java index 38e927f95f..3c6c3e4a94 100644 --- a/quickstep/src/com/android/quickstep/TaskThumbnailCache.java +++ b/quickstep/src/com/android/quickstep/TaskThumbnailCache.java @@ -131,8 +131,7 @@ public class TaskThumbnailCache implements TaskThumbnailDataSource { Preconditions.assertUIThread(); // Fetch the thumbnail for this task and put it in the cache if (task.thumbnail == null) { - updateThumbnailInBackground(task.key, lowResolution, - t -> task.thumbnail = t); + getThumbnailInBackground(task.key, lowResolution, t -> task.thumbnail = t); } } @@ -145,13 +144,13 @@ public class TaskThumbnailCache implements TaskThumbnailDataSource { } /** - * Asynchronously fetches the icon and other task data for the given {@param task}. + * Asynchronously fetches the thumbnail for the given {@code task}. * * @param callback The callback to receive the task after its data has been populated. * @return A cancelable handle to the request */ @Override - public CancellableTask updateThumbnailInBackground( + public CancellableTask getThumbnailInBackground( Task task, @NonNull Consumer callback) { Preconditions.assertUIThread(); @@ -164,10 +163,7 @@ public class TaskThumbnailCache implements TaskThumbnailDataSource { return null; } - return updateThumbnailInBackground(task.key, !mHighResLoadingState.isEnabled(), t -> { - task.thumbnail = t; - callback.accept(t); - }); + return getThumbnailInBackground(task.key, !mHighResLoadingState.isEnabled(), callback); } /** @@ -187,7 +183,7 @@ public class TaskThumbnailCache implements TaskThumbnailDataSource { return newSize > oldSize; } - private CancellableTask updateThumbnailInBackground(TaskKey key, + private CancellableTask getThumbnailInBackground(TaskKey key, boolean lowResolution, Consumer callback) { Preconditions.assertUIThread(); diff --git a/quickstep/src/com/android/quickstep/recents/data/TasksRepository.kt b/quickstep/src/com/android/quickstep/recents/data/TasksRepository.kt index b21a1b4add..9f3ef4adb2 100644 --- a/quickstep/src/com/android/quickstep/recents/data/TasksRepository.kt +++ b/quickstep/src/com/android/quickstep/recents/data/TasksRepository.kt @@ -67,14 +67,15 @@ class TasksRepository( this.visibleTaskIds.value = visibleTaskIdList.toSet() } - /** Flow wrapper for [TaskThumbnailDataSource.updateThumbnailInBackground] api */ + /** Flow wrapper for [TaskThumbnailDataSource.getThumbnailInBackground] api */ private fun getThumbnailDataRequest(task: Task): ThumbnailDataRequest = flow { emit(task.key.id to task.thumbnail) val thumbnailDataResult: ThumbnailData? = suspendCancellableCoroutine { continuation -> val cancellableTask = - taskThumbnailDataSource.updateThumbnailInBackground(task) { + taskThumbnailDataSource.getThumbnailInBackground(task) { + task.thumbnail = it continuation.resume(it) } continuation.invokeOnCancellation { cancellableTask?.cancel() } @@ -94,12 +95,7 @@ class TasksRepository( tasks.filter { it.key.id in visibleIds } } val visibleThumbnailDataRequests: Flow> = - visibleTasks.map { - it.map { visibleTask -> - val taskCopy = Task(visibleTask).apply { thumbnail = visibleTask.thumbnail } - getThumbnailDataRequest(taskCopy) - } - } + visibleTasks.map { visibleTasksList -> visibleTasksList.map(::getThumbnailDataRequest) } return visibleThumbnailDataRequests.flatMapLatest { thumbnailRequestFlows: List -> if (thumbnailRequestFlows.isEmpty()) { diff --git a/quickstep/src/com/android/quickstep/task/thumbnail/data/TaskThumbnailDataSource.kt b/quickstep/src/com/android/quickstep/task/thumbnail/data/TaskThumbnailDataSource.kt index 55598f0a2d..986acbeb31 100644 --- a/quickstep/src/com/android/quickstep/task/thumbnail/data/TaskThumbnailDataSource.kt +++ b/quickstep/src/com/android/quickstep/task/thumbnail/data/TaskThumbnailDataSource.kt @@ -22,7 +22,7 @@ import com.android.systemui.shared.recents.model.ThumbnailData import java.util.function.Consumer interface TaskThumbnailDataSource { - fun updateThumbnailInBackground( + fun getThumbnailInBackground( task: Task, callback: Consumer ): CancellableTask? diff --git a/quickstep/src/com/android/quickstep/util/SplitWithKeyboardShortcutController.java b/quickstep/src/com/android/quickstep/util/SplitWithKeyboardShortcutController.java index 5e42b9001b..27fb31de73 100644 --- a/quickstep/src/com/android/quickstep/util/SplitWithKeyboardShortcutController.java +++ b/quickstep/src/com/android/quickstep/util/SplitWithKeyboardShortcutController.java @@ -138,12 +138,13 @@ public class SplitWithKeyboardShortcutController { mLauncher, mLauncher.getDragLayer(), controller.screenshotTask(runningTaskInfo.taskId).getThumbnail(), null /* icon */, startingTaskRect); + Task task = Task.from(new Task.TaskKey(runningTaskInfo), runningTaskInfo, + false /* isLocked */); RecentsModel.INSTANCE.get(mLauncher.getApplicationContext()) .getIconCache() - .updateIconInBackground( - Task.from(new Task.TaskKey(runningTaskInfo), runningTaskInfo, - false /* isLocked */), - (task) -> floatingTaskView.setIcon(task.icon)); + .getIconInBackground( + task, + (icon, contentDescription, title) -> floatingTaskView.setIcon(icon)); floatingTaskView.setAlpha(1); floatingTaskView.addStagingAnimation(anim, startingTaskRect, mTempRect, false /* fadeWithThumbnail */, true /* isStagedTask */); diff --git a/quickstep/src/com/android/quickstep/views/TaskView.kt b/quickstep/src/com/android/quickstep/views/TaskView.kt index b922df4e69..c7731f1bda 100644 --- a/quickstep/src/com/android/quickstep/views/TaskView.kt +++ b/quickstep/src/com/android/quickstep/views/TaskView.kt @@ -851,7 +851,8 @@ constructor( taskContainers.forEach { if (visible) { recentsModel.thumbnailCache - .updateThumbnailInBackground(it.task) { thumbnailData -> + .getThumbnailInBackground(it.task) { thumbnailData -> + it.task.thumbnail = thumbnailData it.thumbnailViewDeprecated.setThumbnail(it.task, thumbnailData) } ?.also { request -> pendingThumbnailLoadRequests.add(request) } @@ -867,12 +868,15 @@ constructor( taskContainers.forEach { if (visible) { recentsModel.iconCache - .updateIconInBackground(it.task) { task -> - setIcon(it.iconView, task.icon) + .getIconInBackground(it.task) { icon, contentDescription, title -> + it.task.icon = icon + it.task.titleDescription = contentDescription + it.task.title = title + setIcon(it.iconView, icon) if (enableOverviewIconMenu()) { - setText(it.iconView, task.title) + setText(it.iconView, title) } - it.digitalWellBeingToast?.initialize(task) + it.digitalWellBeingToast?.initialize(it.task) } ?.also { request -> pendingIconLoadRequests.add(request) } } else { diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/data/FakeTaskThumbnailDataSource.kt b/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/data/FakeTaskThumbnailDataSource.kt index b66b7351bf..30fc4916a8 100644 --- a/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/data/FakeTaskThumbnailDataSource.kt +++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/data/FakeTaskThumbnailDataSource.kt @@ -32,7 +32,7 @@ class FakeTaskThumbnailDataSource : TaskThumbnailDataSource { var shouldLoadSynchronously: Boolean = true /** Retrieves and sets a thumbnail on [task] from [taskIdToBitmap]. */ - override fun updateThumbnailInBackground( + override fun getThumbnailInBackground( task: Task, callback: Consumer ): CancellableTask? {