From 4c7dcc4b02034aa244c6f4d529ef3682db230b4d Mon Sep 17 00:00:00 2001 From: Alex Chau Date: Fri, 26 Jul 2024 21:28:18 +0100 Subject: [PATCH] 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 --- .../android/quickstep/AbsSwipeUpHandler.java | 28 ++--- .../recents/data/RecentTasksRepository.kt | 2 +- .../quickstep/recents/data/TasksRepository.kt | 9 +- .../recents/viewmodel/RecentsViewModel.kt | 4 +- .../android/quickstep/views/RecentsView.java | 74 ++++++------- .../quickstep/views/RecentsViewHelper.kt | 2 +- .../com/android/quickstep/views/TaskView.kt | 1 - .../recents/data/FakeTasksRepository.kt | 2 +- .../recents/data/TasksRepositoryTest.kt | 104 +++++++++++------- .../recents/viewmodel/RecentsViewModelTest.kt | 2 +- 10 files changed, 119 insertions(+), 109 deletions(-) diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java index 5a03ae650b..de7f0baa4a 100644 --- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java +++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java @@ -2100,7 +2100,6 @@ public abstract class AbsSwipeUpHandler { - 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() { diff --git a/quickstep/src/com/android/quickstep/recents/data/RecentTasksRepository.kt b/quickstep/src/com/android/quickstep/recents/data/RecentTasksRepository.kt index d5aaed56ca..4f7a541fee 100644 --- a/quickstep/src/com/android/quickstep/recents/data/RecentTasksRepository.kt +++ b/quickstep/src/com/android/quickstep/recents/data/RecentTasksRepository.kt @@ -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) + fun addOrUpdateThumbnailOverride(thumbnailOverride: Map) } diff --git a/quickstep/src/com/android/quickstep/recents/data/TasksRepository.kt b/quickstep/src/com/android/quickstep/recents/data/TasksRepository.kt index 0714170dbb..6acc940130 100644 --- a/quickstep/src/com/android/quickstep/recents/data/TasksRepository.kt +++ b/quickstep/src/com/android/quickstep/recents/data/TasksRepository.kt @@ -82,12 +82,15 @@ class TasksRepository( override fun setVisibleTasks(visibleTaskIdList: List) { this.visibleTaskIds.value = visibleTaskIdList.toSet() - setThumbnailOverride(thumbnailOverride.value) + addOrUpdateThumbnailOverride(emptyMap()) } - override fun setThumbnailOverride(thumbnailOverride: Map) { + override fun addOrUpdateThumbnailOverride(thumbnailOverride: Map) { 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 */ diff --git a/quickstep/src/com/android/quickstep/recents/viewmodel/RecentsViewModel.kt b/quickstep/src/com/android/quickstep/recents/viewmodel/RecentsViewModel.kt index 7205fc8bff..54e34a00da 100644 --- a/quickstep/src/com/android/quickstep/recents/viewmodel/RecentsViewModel.kt +++ b/quickstep/src/com/android/quickstep/recents/viewmodel/RecentsViewModel.kt @@ -58,8 +58,8 @@ class RecentsViewModel( recentsViewData.thumbnailSplashProgress.value = taskThumbnailSplashAlpha } - fun setThumbnailOverride(thumbnailOverride: Map) { - recentsTasksRepository.setThumbnailOverride(thumbnailOverride) + fun addOrUpdateThumbnailOverride(thumbnailOverride: Map) { + recentsTasksRepository.addOrUpdateThumbnailOverride(thumbnailOverride) } suspend fun waitForThumbnailsToUpdate(updatedThumbnails: Map) { diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index 8b6bc39970..3702f930cd 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -1047,8 +1047,11 @@ public abstract class RecentsView thumbnailData, boolean refreshNow) { + /** Updates the thumbnail(s) of the relevant TaskView. */ + public void updateThumbnail(Map thumbnailData) { if (enableRefactorTaskThumbnail()) { - // TODO(b/342560598): Handle updateThumbnail for new TTV. - return null; - } - TaskView updatedTaskView = null; - for (Map.Entry 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 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 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 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) { + override fun addOrUpdateThumbnailOverride(thumbnailOverride: Map) { setThumbnailOverrideInternal(thumbnailOverride) } diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/data/TasksRepositoryTest.kt b/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/data/TasksRepositoryTest.kt index aee5d1ebc9..b34e15634e 100644 --- a/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/data/TasksRepositoryTest.kt +++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/data/TasksRepositoryTest.kt @@ -193,57 +193,79 @@ class TasksRepositoryTest { } @Test - fun setThumbnailOverrideOverrideThumbnails() = runTest { + fun addThumbnailOverrideOverrideThumbnails() = runTest { recentsModel.seedTasks(defaultTaskList) val bitmap1 = taskThumbnailDataSource.taskIdToBitmap[1] - val bitmap2 = taskThumbnailDataSource.taskIdToBitmap[2] - val thumbnailOverride = createThumbnailData() - systemUnderTest.getAllTaskData(forceRefresh = true) - - systemUnderTest.setVisibleTasks(listOf(1)) - systemUnderTest.setThumbnailOverride(mapOf(2 to thumbnailOverride)) - systemUnderTest.setVisibleTasks(listOf(1, 2)) - - // .drop(1) to ignore initial null content before from thumbnail was loaded. - assertThat(systemUnderTest.getThumbnailById(1).drop(1).first()!!.thumbnail) - .isEqualTo(bitmap1) - assertThat(systemUnderTest.getThumbnailById(2).first()!!.thumbnail).isEqualTo(bitmap2) - } - - @Test - fun setThumbnailOverrideClearedWhenTaskBecomeInvisible() = runTest { - recentsModel.seedTasks(defaultTaskList) - val bitmap1 = taskThumbnailDataSource.taskIdToBitmap[1] - val bitmap2 = taskThumbnailDataSource.taskIdToBitmap[2] - val thumbnailOverride = createThumbnailData() + val thumbnailOverride2 = createThumbnailData() systemUnderTest.getAllTaskData(forceRefresh = true) systemUnderTest.setVisibleTasks(listOf(1, 2)) - systemUnderTest.setThumbnailOverride(mapOf(2 to thumbnailOverride)) - systemUnderTest.setVisibleTasks(listOf(1)) - systemUnderTest.setVisibleTasks(listOf(1, 2)) - - // .drop(1) to ignore initial null content before from thumbnail was loaded. - assertThat(systemUnderTest.getThumbnailById(1).drop(1).first()!!.thumbnail) - .isEqualTo(bitmap1) - assertThat(systemUnderTest.getThumbnailById(2).first()!!.thumbnail).isEqualTo(bitmap2) - } - - @Test - fun setThumbnailOverrideDoesNotOverrideInvisibleTasks() = runTest { - recentsModel.seedTasks(defaultTaskList) - val bitmap1 = taskThumbnailDataSource.taskIdToBitmap[1] - val thumbnailOverride = createThumbnailData() - systemUnderTest.getAllTaskData(forceRefresh = true) - - systemUnderTest.setVisibleTasks(listOf(1, 2)) - systemUnderTest.setThumbnailOverride(mapOf(2 to thumbnailOverride)) + systemUnderTest.addOrUpdateThumbnailOverride(mapOf(2 to thumbnailOverride2)) // .drop(1) to ignore initial null content before from thumbnail was loaded. assertThat(systemUnderTest.getThumbnailById(1).drop(1).first()!!.thumbnail) .isEqualTo(bitmap1) assertThat(systemUnderTest.getThumbnailById(2).first()!!.thumbnail) - .isEqualTo(thumbnailOverride.thumbnail) + .isEqualTo(thumbnailOverride2.thumbnail) + } + + @Test + fun addThumbnailOverrideMultipleOverrides() = runTest { + recentsModel.seedTasks(defaultTaskList) + val thumbnailOverride1 = createThumbnailData() + val thumbnailOverride2 = createThumbnailData() + val thumbnailOverride3 = createThumbnailData() + systemUnderTest.getAllTaskData(forceRefresh = true) + + systemUnderTest.setVisibleTasks(listOf(1, 2)) + systemUnderTest.addOrUpdateThumbnailOverride(mapOf(1 to thumbnailOverride1)) + systemUnderTest.addOrUpdateThumbnailOverride(mapOf(2 to thumbnailOverride2)) + systemUnderTest.addOrUpdateThumbnailOverride(mapOf(2 to thumbnailOverride3)) + + assertThat(systemUnderTest.getThumbnailById(1).first()!!.thumbnail) + .isEqualTo(thumbnailOverride1.thumbnail) + assertThat(systemUnderTest.getThumbnailById(2).first()!!.thumbnail) + .isEqualTo(thumbnailOverride3.thumbnail) + } + + @Test + fun addThumbnailOverrideClearedWhenTaskBecomeInvisible() = runTest { + recentsModel.seedTasks(defaultTaskList) + val bitmap2 = taskThumbnailDataSource.taskIdToBitmap[2] + val thumbnailOverride1 = createThumbnailData() + val thumbnailOverride2 = createThumbnailData() + systemUnderTest.getAllTaskData(forceRefresh = true) + + systemUnderTest.setVisibleTasks(listOf(1, 2)) + systemUnderTest.addOrUpdateThumbnailOverride(mapOf(1 to thumbnailOverride1)) + systemUnderTest.addOrUpdateThumbnailOverride(mapOf(2 to thumbnailOverride2)) + // Making task 2 invisible and visible again should clear the override + systemUnderTest.setVisibleTasks(listOf(1)) + systemUnderTest.setVisibleTasks(listOf(1, 2)) + + // .drop(1) to ignore initial null content before from thumbnail was loaded. + assertThat(systemUnderTest.getThumbnailById(1).first()!!.thumbnail) + .isEqualTo(thumbnailOverride1.thumbnail) + assertThat(systemUnderTest.getThumbnailById(2).drop(1).first()!!.thumbnail) + .isEqualTo(bitmap2) + } + + @Test + fun addThumbnailOverrideDoesNotOverrideInvisibleTasks() = runTest { + recentsModel.seedTasks(defaultTaskList) + val bitmap1 = taskThumbnailDataSource.taskIdToBitmap[1] + val bitmap2 = taskThumbnailDataSource.taskIdToBitmap[2] + val thumbnailOverride = createThumbnailData() + systemUnderTest.getAllTaskData(forceRefresh = true) + + systemUnderTest.setVisibleTasks(listOf(1)) + systemUnderTest.addOrUpdateThumbnailOverride(mapOf(2 to thumbnailOverride)) + systemUnderTest.setVisibleTasks(listOf(1, 2)) + + // .drop(1) to ignore initial null content before from thumbnail was loaded. + assertThat(systemUnderTest.getThumbnailById(1).drop(1).first()!!.thumbnail) + .isEqualTo(bitmap1) + assertThat(systemUnderTest.getThumbnailById(2).first()!!.thumbnail).isEqualTo(bitmap2) } private fun createTaskWithId(taskId: Int) = diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/viewmodel/RecentsViewModelTest.kt b/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/viewmodel/RecentsViewModelTest.kt index 00dbcc14a7..b3caf2d284 100644 --- a/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/viewmodel/RecentsViewModelTest.kt +++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/viewmodel/RecentsViewModelTest.kt @@ -89,7 +89,7 @@ class RecentsViewModelTest { val thumbnailUpdate = mapOf(2 to thumbnailDataOverride) systemUnderTest.setRunningTaskShowScreenshot(true) - systemUnderTest.setThumbnailOverride(thumbnailUpdate) + systemUnderTest.addOrUpdateThumbnailOverride(thumbnailUpdate) systemUnderTest.waitForRunningTaskShowScreenshotToUpdate() systemUnderTest.waitForThumbnailsToUpdate(thumbnailUpdate)