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:
@@ -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() }
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -65,7 +65,7 @@ class FakeTasksRepository : RecentTasksRepository {
|
||||
setThumbnailOverrideInternal(thumbnailOverrideMap)
|
||||
}
|
||||
|
||||
override fun setThumbnailOverride(thumbnailOverride: Map<Int, ThumbnailData>) {
|
||||
override fun addOrUpdateThumbnailOverride(thumbnailOverride: Map<Int, ThumbnailData>) {
|
||||
setThumbnailOverrideInternal(thumbnailOverride)
|
||||
}
|
||||
|
||||
|
||||
+63
-41
@@ -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) =
|
||||
|
||||
+1
-1
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user