From 13e1445773ef7fa42e85a84c7debce8128379ff4 Mon Sep 17 00:00:00 2001 From: minch Date: Thu, 20 Mar 2025 21:02:32 +0000 Subject: Migrate to TopTaskTracker.getPlaceholderGroupedTaskInfo Migrate all the call sites of `TopTaskTracker.getPlaceholderTasks` and `getSplitPlaceholderTask`s to the new API `getPlaceholderGroupedTaskInfo` Bug: 401582344 Flag: EXEMPT refactor Test: m Change-Id: I0d71508f4dd9633fea025ed842c4c048d0e70462 --- .../com/android/quickstep/AbsSwipeUpHandler.java | 20 ++-- .../android/quickstep/FallbackSwipeHandler.java | 3 +- .../src/com/android/quickstep/TopTaskTracker.java | 71 ++++---------- .../quickstep/fallback/FallbackRecentsView.java | 19 ++-- .../fallback/window/RecentsWindowSwipeHandler.java | 5 +- .../quickstep/views/LauncherRecentsView.java | 6 +- .../com/android/quickstep/views/RecentsView.java | 106 ++++++++------------- .../android/quickstep/views/RecentsViewUtils.kt | 18 ++++ 8 files changed, 102 insertions(+), 146 deletions(-) (limited to 'quickstep/src') diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java index 47aa1de646..48630b11d3 100644 --- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java +++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java @@ -161,7 +161,6 @@ import com.android.quickstep.views.TaskView; import com.android.quickstep.views.TaskViewType; import com.android.systemui.animation.TransitionAnimator; import com.android.systemui.contextualeducation.GestureType; -import com.android.systemui.shared.recents.model.Task; import com.android.systemui.shared.recents.model.ThumbnailData; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.InputConsumerController; @@ -170,6 +169,7 @@ import com.android.systemui.shared.system.SysUiStatsLog; import com.android.systemui.shared.system.TaskStackChangeListener; import com.android.systemui.shared.system.TaskStackChangeListeners; import com.android.wm.shell.Flags; +import com.android.wm.shell.shared.GroupedTaskInfo; import com.android.wm.shell.shared.TransactionPool; import com.android.wm.shell.shared.desktopmode.DesktopModeStatus; import com.android.wm.shell.shared.startingsurface.SplashScreenExitAnimationUtils; @@ -182,7 +182,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; -import java.util.Objects; import java.util.Optional; import java.util.OptionalInt; import java.util.function.Consumer; @@ -693,26 +692,23 @@ public abstract class AbsSwipeUpHandler< } protected void notifyGestureAnimationStartToRecents() { - Task[] runningTasks; - TopTaskTracker.CachedTaskInfo cachedTaskInfo = mGestureState.getRunningTask(); - if (mIsSwipeForSplit) { - int[] splitTaskIds = TopTaskTracker.INSTANCE.get(mContext).getRunningSplitTaskIds(); - runningTasks = cachedTaskInfo.getSplitPlaceholderTasks(splitTaskIds); - } else { - runningTasks = cachedTaskInfo.getPlaceholderTasks(); - } + int[] splitTaskIds = mIsSwipeForSplit + ? TopTaskTracker.INSTANCE.get(mContext).getRunningSplitTaskIds() + : null; + GroupedTaskInfo groupedTaskInfo = + mGestureState.getRunningTask().getPlaceholderGroupedTaskInfo(splitTaskIds); // Safeguard against any null tasks being sent to recents view, happens when quickswitching // very quickly w/ split tasks because TopTaskTracker provides stale information compared to // actual running tasks in the recents animation. // TODO(b/236226779), Proper fix (ag/22237143) - if (Arrays.stream(runningTasks).anyMatch(Objects::isNull)) { + if (groupedTaskInfo == null) { return; } if (mRecentsView == null) { return; } - mRecentsView.onGestureAnimationStart(runningTasks); + mRecentsView.onGestureAnimationStart(groupedTaskInfo); TaskView currentPageTaskView = mRecentsView.getCurrentPageTaskView(); if (currentPageTaskView != null) { mPreviousTaskViewType = currentPageTaskView.getType(); diff --git a/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java b/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java index 7d8a53d61b..9365383880 100644 --- a/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java +++ b/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java @@ -218,7 +218,8 @@ public class FallbackSwipeHandler extends if (mRunningOverHome) { if (DisplayController.getNavigationMode(mContext).hasGestures) { mRecentsView.onGestureAnimationStartOnHome( - mGestureState.getRunningTask().getPlaceholderTasks()); + mGestureState.getRunningTask().getPlaceholderGroupedTaskInfo( + /* splitTaskIds = */ null)); } } else { super.notifyGestureAnimationStartToRecents(); diff --git a/quickstep/src/com/android/quickstep/TopTaskTracker.java b/quickstep/src/com/android/quickstep/TopTaskTracker.java index ef5c1db8f0..43e8ff9902 100644 --- a/quickstep/src/com/android/quickstep/TopTaskTracker.java +++ b/quickstep/src/com/android/quickstep/TopTaskTracker.java @@ -55,8 +55,6 @@ import com.android.launcher3.util.TraceHelper; import com.android.quickstep.dagger.QuickstepBaseAppComponent; import com.android.quickstep.util.DesksUtils; import com.android.quickstep.util.ExternalDisplaysKt; -import com.android.systemui.shared.recents.model.Task; -import com.android.systemui.shared.recents.model.Task.TaskKey; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.TaskStackChangeListener; import com.android.systemui.shared.system.TaskStackChangeListeners; @@ -527,64 +525,26 @@ public class TopTaskTracker extends ISplitScreenListener.Stub implements TaskSta : new CachedTaskInfo(visibleNonExcludedTasks, mCanEnterDesktopMode); } - /** - * Returns {@link Task} array which can be used as a placeholder until the true object - * is loaded by the model - */ - public Task[] getPlaceholderTasks() { - final TaskInfo baseTask = getLegacyBaseTask(); - // TODO(346588978): Update this to return more than a single task once the callers - // are refactored - return baseTask == null - ? new Task[0] - : new Task[]{Task.from(new TaskKey(baseTask), baseTask, false)}; - } - /** * Returns {@link TaskInfo} array corresponding to the provided task ids which can be - * used as a placeholder until the true object is loaded by the model. Returns null - * directly when [enableShellTopTaskTracking] is true, as it will be a no-op when the - * flag is enabled. + * used as a placeholder until the true object is loaded by the model. Only used when + * enableShellTopTaskTracking() is disabled. */ private TaskInfo[] getSplitPlaceholderTasksInfo(int[] splitTaskIds) { - if (enableShellTopTaskTracking()) { - return null; - } else { - if (mTopTask == null) { - return new TaskInfo[0]; - } - TaskInfo[] result = new TaskInfo[splitTaskIds.length]; - for (int i = 0; i < splitTaskIds.length; i++) { - final int index = i; - int taskId = splitTaskIds[i]; - mAllCachedTasks.forEach(rti -> { - if (rti.taskId == taskId) { - result[index] = rti; - } - }); - } - return result; + if (mTopTask == null) { + return new TaskInfo[0]; } - } - - /** - * Returns {@link Task} array corresponding to the provided task ids which can be - * used as a placeholder until the true object is loaded by the model. Returns null - * directly when [enableShellTopTaskTracking] is true, as it will be a no-op when the - * flag is enabled. - */ - public Task[] getSplitPlaceholderTasks(int[] splitTaskIds) { - if (enableShellTopTaskTracking()) { - return null; - } else { - TaskInfo[] tasksInfo = getSplitPlaceholderTasksInfo(splitTaskIds); - Task[] tasks = new Task[tasksInfo.length]; - for (int i = 0; i < tasksInfo.length; i++) { - tasks[i] = Task.from(new TaskKey(tasksInfo[i]), tasksInfo[i], /* isLocked = */ - false); - } - return tasks; + TaskInfo[] result = new TaskInfo[splitTaskIds.length]; + for (int i = 0; i < splitTaskIds.length; i++) { + final int index = i; + int taskId = splitTaskIds[i]; + mAllCachedTasks.forEach(rti -> { + if (rti.taskId == taskId) { + result[index] = rti; + } + }); } + return result; } private boolean isDesktopTask(TaskInfo taskInfo) { @@ -616,6 +576,9 @@ public class TopTaskTracker extends ISplitScreenListener.Stub implements TaskSta } if (splitTaskIds != null && splitTaskIds.length >= 2) { TaskInfo[] splitTasksInfo = getSplitPlaceholderTasksInfo(splitTaskIds); + if (splitTasksInfo[0] == null || splitTasksInfo[1] == null) { + return null; + } return GroupedTaskInfo.forSplitTasks(splitTasksInfo[0], splitTasksInfo[1], /* splitBounds = */ null); } else if (isDesktopTask(baseTaskInfo)) { diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java index 695c77c991..dc1cdde4bc 100644 --- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java +++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java @@ -56,6 +56,7 @@ import com.android.quickstep.views.RecentsViewContainer; import com.android.quickstep.views.TaskContainer; import com.android.quickstep.views.TaskView; import com.android.systemui.shared.recents.model.Task; +import com.android.wm.shell.shared.GroupedTaskInfo; import java.util.ArrayList; import java.util.Arrays; @@ -116,11 +117,13 @@ public class FallbackRecentsView 0 ? homeTask[0] : null; - onGestureAnimationStart(homeTask); + if (homeTaskInfo != null) { + mHomeTask = Task.from(homeTaskInfo.getTaskInfo1()); + } + onGestureAnimationStart(homeTaskInfo); } /** @@ -175,13 +178,13 @@ public class FallbackRecentsView 1) { + protected boolean shouldAddStubTaskView(GroupedTaskInfo groupedTaskInfo) { + if (!groupedTaskInfo.isBaseType(GroupedTaskInfo.TYPE_FULLSCREEN)) { // can't be in split screen w/ home task - return super.shouldAddStubTaskView(runningTasks); + return super.shouldAddStubTaskView(groupedTaskInfo); } - Task runningTask = runningTasks[0]; + Task runningTask = Task.from(groupedTaskInfo.getTaskInfo1()); if (mHomeTask != null && runningTask != null && mHomeTask.key.id == runningTask.key.id && !hasTaskViews() && mLoadPlanEverApplied) { @@ -190,7 +193,7 @@ public class FallbackRecentsView mGroupedTaskViewPool; private final ViewPool mDesktopTaskViewPool; - private final TaskOverlayFactory mTaskOverlayFactory; + protected final TaskOverlayFactory mTaskOverlayFactory; protected boolean mDisallowScrollToClearAll; // True if it is not allowed to scroll to [AddDesktopButton]. @@ -671,7 +672,7 @@ public abstract class RecentsView< return; } Log.d(TAG, "onTaskRemoved: " + taskId); - Task.TaskKey taskKey = taskContainer.getTask().key; + TaskKey taskKey = taskContainer.getTask().key; UI_HELPER_EXECUTOR.execute(new CancellableTask<>( () -> PackageManagerWrapper.getInstance() .getActivityInfo(taskKey.getComponent(), taskKey.userId) == null, @@ -2100,12 +2101,12 @@ public abstract class RecentsView< if (newRunningTaskView != null) { setRunningTaskViewId(newRunningTaskView.getTaskViewId()); } else { - if (mActiveGestureRunningTasks != null) { + if (mActiveGestureGroupedTaskInfo != null) { // This will update mRunningTaskViewId and create a stub view if necessary. // We try to avoid this because it can cause a scroll jump, but it is needed // for cases where the running task isn't included in this load plan (e.g. if // the current running task is excludedFromRecents.) - showCurrentTask(mActiveGestureRunningTasks, "applyLoadPlan"); + showCurrentTask(mActiveGestureGroupedTaskInfo, "applyLoadPlan"); newRunningTaskView = getRunningTaskView(); } else { setRunningTaskViewId(INVALID_TASK_ID); @@ -2826,7 +2827,7 @@ public abstract class RecentsView< * Handle the edge case where Recents could increment task count very high over long * period of device usage. Probably will never happen, but meh. */ - private TaskView getTaskViewFromPool(TaskViewType type) { + protected TaskView getTaskViewFromPool(TaskViewType type) { TaskView taskView; switch (type) { case GROUPED: @@ -2880,10 +2881,9 @@ public abstract class RecentsView< */ // TODO: b/401582344 - Implement a way to exclude the `DesktopWallpaperActivity` from being // considered in Overview. - public void onGestureAnimationStart(Task[] runningTasks) { - Log.d(TAG, "onGestureAnimationStart - runningTasks: " + Arrays.toString(runningTasks)); - mActiveGestureRunningTasks = runningTasks; - + public void onGestureAnimationStart(GroupedTaskInfo groupedTaskInfo) { + Log.d(TAG, "onGestureAnimationStart - groupedTaskInfo: " + groupedTaskInfo); + mActiveGestureGroupedTaskInfo = groupedTaskInfo; // This needs to be called before the other states are set since it can create the task view if (mOrientationState.setGestureActive(true)) { @@ -2893,7 +2893,7 @@ public abstract class RecentsView< updateSizeAndPadding(); } - showCurrentTask(mActiveGestureRunningTasks, "onGestureAnimationStart"); + showCurrentTask(groupedTaskInfo, "onGestureAnimationStart"); setEnableFreeScroll(false); setEnableDrawingLiveTile(false); setRunningTaskHidden(true); @@ -2908,7 +2908,7 @@ public abstract class RecentsView< } private boolean isGestureActive() { - return mActiveGestureRunningTasks != null; + return mActiveGestureGroupedTaskInfo != null; } /** @@ -3046,7 +3046,7 @@ public abstract class RecentsView< * Called when a gesture from an app has finished, and the animation to the target has ended. */ public void onGestureAnimationEnd() { - mActiveGestureRunningTasks = null; + mActiveGestureGroupedTaskInfo = null; if (mOrientationState.setGestureActive(false)) { updateOrientationHandler(/* forceRecreateDragLayerControllers = */ false); } @@ -3085,10 +3085,17 @@ public abstract class RecentsView< /** * Returns true if we should add a stub taskView for the running task id */ - protected boolean shouldAddStubTaskView(Task[] runningTasks) { - int[] runningTaskIds = Arrays.stream(runningTasks).mapToInt(task -> task.key.id).toArray(); + protected boolean shouldAddStubTaskView(GroupedTaskInfo groupedTaskInfo) { + int[] runningTaskIds; + if (groupedTaskInfo != null) { + runningTaskIds = groupedTaskInfo.getTaskInfoList().stream().mapToInt( + taskInfo -> taskInfo.taskId).toArray(); + } else { + runningTaskIds = new int[0]; + } TaskView matchingTaskView = null; - if (hasDesktopTask(runningTasks) && runningTaskIds.length == 1) { + if (groupedTaskInfo != null && groupedTaskInfo.isBaseType(GroupedTaskInfo.TYPE_DESK) + && runningTaskIds.length == 1) { // TODO(b/342635213): Unsure if it's expected, desktop runningTasks only have a single // taskId, therefore we match any DesktopTaskView that contains the runningTaskId. TaskView taskview = getTaskViewByTaskId(runningTaskIds[0]); @@ -3102,53 +3109,36 @@ public abstract class RecentsView< } /** - * Creates a `DesktopTaskView` for the currently active desk on this display, which contains the - * gievn `runningTasks`. - */ - private DesktopTaskView createDesktopTaskViewForActiveDesk(Task[] runningTasks) { - final int activeDeskId = mUtils.getActiveDeskIdOnThisDisplay(); - final var desktopTaskView = (DesktopTaskView) getTaskViewFromPool(TaskViewType.DESKTOP); - - // TODO: b/401582344 - Implement a way to exclude the `DesktopWallpaperActivity`. - desktopTaskView.bind( - new DesktopTask(activeDeskId, mContainer.getDisplayId(), - Arrays.asList(runningTasks)), - mOrientationState, mTaskOverlayFactory); - return desktopTaskView; - } - - /** - * Creates a task view (if necessary) to represent the task with the {@param runningTaskId}. + * Creates a task view (if necessary) to represent the tasks with the {@param groupedTaskInfo}. * * All subsequent calls to reload will keep the task as the first item until {@link #reset()} * is called. Also scrolls the view to this task. */ - private void showCurrentTask(Task[] runningTasks, String caller) { - Log.d(TAG, "showCurrentTask(" + caller + ") - runningTasks: " - + Arrays.toString(runningTasks)); - if (runningTasks.length == 0) { + private void showCurrentTask(GroupedTaskInfo groupedTaskInfo, String caller) { + Log.d(TAG, "showCurrentTask(" + caller + ") - groupedTaskInfo: " + groupedTaskInfo); + if (groupedTaskInfo == null) { return; } int runningTaskViewId = -1; - if (shouldAddStubTaskView(runningTasks)) { + if (shouldAddStubTaskView(groupedTaskInfo)) { boolean wasEmpty = getChildCount() == 0; // Add an empty view for now until the task plan is loaded and applied final TaskView taskView; - final boolean needGroupTaskView = runningTasks.length > 1; - final boolean needDesktopTask = hasDesktopTask(runningTasks); - if (needDesktopTask) { - taskView = createDesktopTaskViewForActiveDesk(runningTasks); - } else if (needGroupTaskView) { + if (groupedTaskInfo.isBaseType(GroupedTaskInfo.TYPE_DESK)) { + taskView = mUtils.createDesktopTaskViewForActiveDesk(groupedTaskInfo); + } else if (groupedTaskInfo.isBaseType(GroupedTaskInfo.TYPE_SPLIT)) { taskView = getTaskViewFromPool(TaskViewType.GROUPED); // When we create a placeholder task view mSplitBoundsConfig will be null, but with // the actual app running we won't need to show the thumbnail until all the tasks // load later anyways - ((GroupedTaskView) taskView).bind(runningTasks[0], runningTasks[1], - mOrientationState, mTaskOverlayFactory, mSplitBoundsConfig); + ((GroupedTaskView) taskView).bind(Task.from(groupedTaskInfo.getTaskInfo1()), + Task.from(groupedTaskInfo.getTaskInfo2()), mOrientationState, + mTaskOverlayFactory, mSplitBoundsConfig); } else { taskView = getTaskViewFromPool(TaskViewType.SINGLE); - taskView.bind(runningTasks[0], mOrientationState, mTaskOverlayFactory); + taskView.bind(Task.from(groupedTaskInfo.getTaskInfo1()), mOrientationState, + mTaskOverlayFactory); } if (mAddDesktopButton != null && wasEmpty) { addView(mAddDesktopButton); @@ -3165,7 +3155,7 @@ public abstract class RecentsView< makeMeasureSpec(getMeasuredHeight(), EXACTLY)); layout(getLeft(), getTop(), getRight(), getBottom()); } else { - var runningTaskView = getTaskViewByTaskId(runningTasks[0].key.id); + var runningTaskView = getTaskViewByTaskId(groupedTaskInfo.getTaskInfo1().taskId); if (runningTaskView != null) { runningTaskViewId = runningTaskView.getTaskViewId(); } @@ -3198,22 +3188,6 @@ public abstract class RecentsView< reloadIfNeeded(); } - private boolean hasDesktopTask(Task[] runningTasks) { - if (!DesktopModeStatus.canEnterDesktopMode(mContext)) { - return false; - } - for (Task task : runningTasks) { - if (task.key.windowingMode == WindowConfiguration.WINDOWING_MODE_FREEFORM) { - return true; - } - } - - // A running empty desk will have a single running app for the `DesktopWallpaperActivity`. - // TODO: b/401582344 - Implement a way to exclude the `DesktopWallpaperActivity`. - - return false; - } - /** * Sets the running task id, cleaning up the old running task if necessary. */ diff --git a/quickstep/src/com/android/quickstep/views/RecentsViewUtils.kt b/quickstep/src/com/android/quickstep/views/RecentsViewUtils.kt index 50941fefa8..b265b13393 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsViewUtils.kt +++ b/quickstep/src/com/android/quickstep/views/RecentsViewUtils.kt @@ -39,7 +39,9 @@ import com.android.quickstep.util.DesktopTask import com.android.quickstep.util.GroupTask import com.android.quickstep.util.isExternalDisplay import com.android.quickstep.views.RecentsView.RUNNING_TASK_ATTACH_ALPHA +import com.android.systemui.shared.recents.model.Task import com.android.systemui.shared.recents.model.ThumbnailData +import com.android.wm.shell.shared.GroupedTaskInfo import java.util.function.BiConsumer import kotlin.math.min import kotlin.reflect.KMutableProperty1 @@ -459,6 +461,22 @@ class RecentsViewUtils(private val recentsView: RecentsView<*, *>) { } } + /** + * Creates a [DesktopTaskView] for the currently active desk on this display, which contains the + * tasks with the given [groupedTaskInfo]. + */ + fun createDesktopTaskViewForActiveDesk(groupedTaskInfo: GroupedTaskInfo): DesktopTaskView { + val desktopTaskView = + recentsView.getTaskViewFromPool(TaskViewType.DESKTOP) as DesktopTaskView + val tasks: List = groupedTaskInfo.taskInfoList.map { taskInfo -> Task.from(taskInfo) } + desktopTaskView.bind( + DesktopTask(groupedTaskInfo.deskId, groupedTaskInfo.deskDisplayId, tasks), + recentsView.mOrientationState, + recentsView.mTaskOverlayFactory, + ) + return desktopTaskView + } + companion object { class RecentsViewFloatProperty( private val utilsProperty: KMutableProperty1 -- cgit v1.2.3-59-g8ed1b