Increase number of triggers for taskData reloading in TasksRepository

- Simplified AbsSwipeUpHandler.switchToScreenshot to remove the unused refreshView=false parameter, so we RecentsView.updateThumbnail don't need to return a TaskView
- Changed TasksRepository.setThumbnailOverride to addThumbnailOverride, that'll accumulate overrides being sent to it
- Handled RecentsView.updateThumbnail to add an override to TasksRepository
- visibleTaskIds being sent to TasksRepository now take acccount of fileering out mTmpRunningTasks
- Updated a few TODOs around thumbnail/icon reloading

Bug: 342560598
Test: TasksRepositoryTest
Flag: com.android.launcher3.enable_refactor_task_thumbnail
Change-Id: Ia892819c45f20e82fbda275fd0e39081d6362cb6
This commit is contained in:
Alex Chau
2024-08-01 12:42:00 +01:00
parent 2293967dba
commit 4c7dcc4b02
10 changed files with 119 additions and 109 deletions
@@ -2100,7 +2100,6 @@ public abstract class AbsSwipeUpHandler<T extends RecentsViewContainer,
// If there are no targets, then we don't need to capture anything
mStateCallback.setStateOnUiThread(STATE_SCREENSHOT_CAPTURED);
} else {
boolean finishTransitionPosted = false;
// If we already have cached screenshot(s) from running tasks, skip update
boolean shouldUpdate = false;
int[] runningTaskIds = mGestureState.getRunningTaskIds(mIsSwipeForSplit);
@@ -2124,45 +2123,32 @@ public abstract class AbsSwipeUpHandler<T extends RecentsViewContainer,
}
MAIN_EXECUTOR.execute(() -> {
if (!updateThumbnail(false /* refreshView */)) {
setScreenshotCapturedState();
}
updateThumbnail();
setScreenshotCapturedState();
});
});
return;
}
finishTransitionPosted = updateThumbnail(false /* refreshView */);
updateThumbnail();
}
if (!finishTransitionPosted) {
setScreenshotCapturedState();
}
setScreenshotCapturedState();
}
}
// Returns whether finish transition was posted.
private boolean updateThumbnail(boolean refreshView) {
private void updateThumbnail() {
if (mGestureState.getEndTarget() == HOME
|| mGestureState.getEndTarget() == NEW_TASK
|| mGestureState.getEndTarget() == ALL_APPS
|| mRecentsView == null) {
// Capture the screenshot before finishing the transition to home or quickswitching to
// ensure it's taken in the correct orientation, but no need to update the thumbnail.
return false;
return;
}
boolean finishTransitionPosted = false;
TaskView updatedTaskView = mRecentsView.updateThumbnail(mTaskSnapshotCache, refreshView);
if (updatedTaskView != null && refreshView && !mCanceled) {
// Defer finishing the animation until the next launcher frame with the
// new thumbnail
finishTransitionPosted = ViewUtils.postFrameDrawn(updatedTaskView,
() -> mStateCallback.setStateOnUiThread(STATE_SCREENSHOT_CAPTURED),
this::isCanceled);
}
return finishTransitionPosted;
mRecentsView.updateThumbnail(mTaskSnapshotCache);
}
private void setScreenshotCapturedState() {
@@ -46,5 +46,5 @@ interface RecentTasksRepository {
* Override [ThumbnailData] with a map of taskId to [ThumbnailData]. The override only applies
* if the tasks are already visible, and will be invalidated when tasks become invisible.
*/
fun setThumbnailOverride(thumbnailOverride: Map<Int, ThumbnailData>)
fun addOrUpdateThumbnailOverride(thumbnailOverride: Map<Int, ThumbnailData>)
}
@@ -82,12 +82,15 @@ class TasksRepository(
override fun setVisibleTasks(visibleTaskIdList: List<Int>) {
this.visibleTaskIds.value = visibleTaskIdList.toSet()
setThumbnailOverride(thumbnailOverride.value)
addOrUpdateThumbnailOverride(emptyMap())
}
override fun setThumbnailOverride(thumbnailOverride: Map<Int, ThumbnailData>) {
override fun addOrUpdateThumbnailOverride(thumbnailOverride: Map<Int, ThumbnailData>) {
this.thumbnailOverride.value =
thumbnailOverride.filterKeys(this.visibleTaskIds.value::contains).toMap()
this.thumbnailOverride.value
.toMutableMap()
.apply { putAll(thumbnailOverride) }
.filterKeys(this.visibleTaskIds.value::contains)
}
/** Flow wrapper for [TaskThumbnailDataSource.getThumbnailInBackground] api */
@@ -58,8 +58,8 @@ class RecentsViewModel(
recentsViewData.thumbnailSplashProgress.value = taskThumbnailSplashAlpha
}
fun setThumbnailOverride(thumbnailOverride: Map<Int, ThumbnailData>) {
recentsTasksRepository.setThumbnailOverride(thumbnailOverride)
fun addOrUpdateThumbnailOverride(thumbnailOverride: Map<Int, ThumbnailData>) {
recentsTasksRepository.addOrUpdateThumbnailOverride(thumbnailOverride)
}
suspend fun waitForThumbnailsToUpdate(updatedThumbnails: Map<Int, ThumbnailData>) {
@@ -1047,8 +1047,11 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
@Override
@Nullable
public Task onTaskThumbnailChanged(int taskId, ThumbnailData thumbnailData) {
if (enableRefactorTaskThumbnail()) {
// TODO(b/342560598): Listen in TaskRepository and reload
return null;
}
if (mHandleTaskStackChanges) {
// TODO(b/342560598): Handle onTaskThumbnailChanged for new TTV.
if (!enableRefactorTaskThumbnail()) {
TaskView taskView = getTaskViewByTaskId(taskId);
if (taskView != null) {
@@ -1067,6 +1070,7 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
@Override
public void onTaskIconChanged(String pkg, UserHandle user) {
// TODO(b/342560598): Listen in TaskRepository and reload.
for (int i = 0; i < getTaskViewCount(); i++) {
TaskView tv = requireTaskViewAt(i);
Task task = tv.getFirstTask();
@@ -1082,47 +1086,38 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
@Override
public void onTaskIconChanged(int taskId) {
if (enableRefactorTaskThumbnail()) {
return;
}
TaskView taskView = getTaskViewByTaskId(taskId);
if (taskView != null) {
taskView.refreshTaskThumbnailSplash();
}
}
/**
* Update the thumbnail(s) of the relevant TaskView.
*
* @param refreshNow Refresh immediately if it's true.
*/
@Nullable
public TaskView updateThumbnail(
HashMap<Integer, ThumbnailData> thumbnailData, boolean refreshNow) {
/** Updates the thumbnail(s) of the relevant TaskView. */
public void updateThumbnail(Map<Integer, ThumbnailData> thumbnailData) {
if (enableRefactorTaskThumbnail()) {
// TODO(b/342560598): Handle updateThumbnail for new TTV.
return null;
}
TaskView updatedTaskView = null;
for (Map.Entry<Integer, ThumbnailData> entry : thumbnailData.entrySet()) {
Integer id = entry.getKey();
ThumbnailData thumbnail = entry.getValue();
TaskView taskView = getTaskViewByTaskId(id);
if (taskView == null) {
continue;
mRecentsViewModel.addOrUpdateThumbnailOverride(thumbnailData);
} else {
for (Map.Entry<Integer, ThumbnailData> entry : thumbnailData.entrySet()) {
Integer id = entry.getKey();
ThumbnailData thumbnail = entry.getValue();
TaskView taskView = getTaskViewByTaskId(id);
if (taskView == null) {
continue;
}
// taskView could be a GroupedTaskView, so select the relevant task by ID
TaskContainer taskContainer = taskView.getTaskContainerById(id);
if (taskContainer == null) {
continue;
}
Task task = taskContainer.getTask();
TaskThumbnailViewDeprecated taskThumbnailViewDeprecated =
taskContainer.getThumbnailViewDeprecated();
taskThumbnailViewDeprecated.setThumbnail(task, thumbnail, /*refreshNow=*/false);
}
// taskView could be a GroupedTaskView, so select the relevant task by ID
TaskContainer taskAttributes = taskView.getTaskContainerById(id);
if (taskAttributes == null) {
continue;
}
Task task = taskAttributes.getTask();
TaskThumbnailViewDeprecated taskThumbnailViewDeprecated =
taskAttributes.getThumbnailViewDeprecated();
taskThumbnailViewDeprecated.setThumbnail(task, thumbnail, refreshNow);
// thumbnailData can contain 1-2 ids, but they should correspond to the same
// TaskView, so overwriting is ok
updatedTaskView = taskView;
}
return updatedTaskView;
}
@Override
@@ -2440,10 +2435,6 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
List<Task> tasksToUpdate = containers.stream()
.map(TaskContainer::getTask)
.collect(Collectors.toCollection(ArrayList::new));
if (enableRefactorTaskThumbnail()) {
visibleTaskIds.addAll(
tasksToUpdate.stream().map((task) -> task.key.id).toList());
}
if (mTmpRunningTasks != null) {
for (Task t : mTmpRunningTasks) {
// Skip loading if this is the task that we are animating into
@@ -2451,6 +2442,10 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
tasksToUpdate.removeIf(task -> task == t);
}
}
if (enableRefactorTaskThumbnail()) {
visibleTaskIds.addAll(
tasksToUpdate.stream().map((task) -> task.key.id).toList());
}
if (tasksToUpdate.isEmpty()) {
continue;
}
@@ -2507,6 +2502,11 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
mModel.preloadCacheIfNeeded();
}
if (enableRefactorTaskThumbnail()) {
// TODO(b/342560598): Listen in TaskRepository and reload.
return;
}
// Whenever the high res loading state changes, poke each of the visible tasks to see if
// they want to updated their thumbnail state
for (int i = 0; i < mHasVisibleTaskData.size(); i++) {
@@ -61,7 +61,7 @@ class RecentsViewHelper(private val recentsViewModel: RecentsViewModel) {
// viewAttachedScope.
recentsViewModel.setRunningTaskShowScreenshot(true)
if (updatedThumbnails != null) {
recentsViewModel.setThumbnailOverride(updatedThumbnails)
recentsViewModel.addOrUpdateThumbnailOverride(updatedThumbnails)
}
viewAttachedScope.launch {
recentsViewModel.waitForRunningTaskShowScreenshotToUpdate()
@@ -1398,7 +1398,6 @@ constructor(
protected open fun refreshTaskThumbnailSplash() {
if (!enableRefactorTaskThumbnail()) {
// TODO(b/342560598) handle onTaskIconChanged
taskContainers.forEach { it.thumbnailViewDeprecated.refreshSplashView() }
}
}