Remove all external usages of `GroupTask.task1/2` from Launcher3
See go/refactor-group-task for details. This CL removes all the usages
of `task1` and `task2` from `GroupTask` in Launcher3. Follow-up CLs will
remove it from NexusLauncher and remove the fields altogether.
Bug: 388593902
Test: m
Flag: EXEMPT pure refactor with no behavior change.
Change-Id: I902c8135b3a0aae95acf25267b3bcbf286bd4e7d
diff --git a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchController.java b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchController.java
index 3736e6d..23065b5 100644
--- a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchController.java
@@ -233,7 +233,8 @@
}
private boolean shouldExcludeTask(GroupTask task, Set<Integer> taskIdsToExclude) {
- return Flags.taskbarOverflow() && taskIdsToExclude.contains(task.task1.key.id);
+ return Flags.taskbarOverflow() && task.getTasks().stream().anyMatch(
+ t -> taskIdsToExclude.contains(t.key.id));
}
private void processLoadedTasks(List<GroupTask> tasks, Set<Integer> taskIdsToExclude) {
diff --git a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchView.java b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchView.java
index 306443e..73f9bea 100644
--- a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchView.java
@@ -51,6 +51,9 @@
import com.android.launcher3.testing.TestLogging;
import com.android.launcher3.testing.shared.TestProtocol;
import com.android.quickstep.util.GroupTask;
+import com.android.quickstep.util.SingleTask;
+import com.android.quickstep.util.SplitTask;
+import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
import java.util.HashMap;
@@ -255,14 +258,21 @@
layoutInflater,
previousTaskView);
- final boolean firstTaskIsLeftTopTask =
- groupTask.mSplitBounds == null
- || groupTask.mSplitBounds.leftTopTaskId == groupTask.task1.key.id
- || groupTask.task2 == null;
+ Task task1;
+ Task task2;
+ if (groupTask instanceof SplitTask splitTask) {
+ task1 = splitTask.getTopLeftTask();
+ task2 = splitTask.getBottomRightTask();
+ } else if (groupTask instanceof SingleTask singleTask) {
+ task1 = singleTask.getTask();
+ task2 = null;
+ } else {
+ continue;
+ }
currentTaskView.setThumbnailsForSplitTasks(
- firstTaskIsLeftTopTask ? groupTask.task1 : groupTask.task2,
- firstTaskIsLeftTopTask ? groupTask.task2 : groupTask.task1,
+ task1,
+ task2,
updateTasks ? mViewCallbacks::updateThumbnailInBackground : null,
updateTasks ? mViewCallbacks::updateIconInBackground : null,
groupTask.mSplitBounds);
diff --git a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchViewController.java b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchViewController.java
index 8cb43d2..5af7ff8 100644
--- a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchViewController.java
@@ -44,6 +44,7 @@
import com.android.launcher3.views.BaseDragLayer;
import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.util.GroupTask;
+import com.android.quickstep.util.SingleTask;
import com.android.quickstep.util.SlideInRemoteTransition;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.recents.model.ThumbnailData;
@@ -281,9 +282,10 @@
return -1;
}
RemoteTransition remoteTransition = slideInTransition;
- if (mOnDesktop
- && mControllers.taskbarActivityContext.canUnminimizeDesktopTask(task.task1.key.id)
- ) {
+ boolean canUnminimizeDesktopTask = task instanceof SingleTask singleTask
+ && mControllers.taskbarActivityContext.canUnminimizeDesktopTask(
+ singleTask.getTask().key.id);
+ if (mOnDesktop && canUnminimizeDesktopTask) {
// This app is being unminimized - use our own transition runner.
remoteTransition = new RemoteTransition(
new DesktopAppLaunchTransition(
diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
index 5a8fba6..4143157 100644
--- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
@@ -49,7 +49,7 @@
import com.android.quickstep.HomeVisibilityState;
import com.android.quickstep.RecentsAnimationCallbacks;
import com.android.quickstep.SystemUiProxy;
-import com.android.quickstep.util.GroupTask;
+import com.android.quickstep.util.SplitTask;
import com.android.quickstep.views.RecentsView;
import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags;
import com.android.wm.shell.shared.bubbles.BubbleBarLocation;
@@ -480,8 +480,8 @@
@Override
public void launchSplitTasks(
- @NonNull GroupTask groupTask, @Nullable RemoteTransition remoteTransition) {
- mLauncher.launchSplitTasks(groupTask, remoteTransition);
+ @NonNull SplitTask splitTask, @Nullable RemoteTransition remoteTransition) {
+ mLauncher.launchSplitTasks(splitTask, remoteTransition);
}
@Override
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index e8a0c45..6bfbfdd 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -155,6 +155,8 @@
import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.util.DesktopTask;
import com.android.quickstep.util.GroupTask;
+import com.android.quickstep.util.SingleTask;
+import com.android.quickstep.util.SplitTask;
import com.android.quickstep.views.DesktopTaskView;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
@@ -1293,11 +1295,13 @@
mControllers.keyboardQuickSwitchController.closeQuickSwitchView(false);
- if (tag instanceof GroupTask groupTask) {
+ // TODO: b/316004172, b/343289567: Handle `DesktopTask` and `SplitTask`.
+ if (tag instanceof SingleTask singleTask) {
RemoteTransition remoteTransition =
- (areDesktopTasksVisible() && canUnminimizeDesktopTask(groupTask.task1.key.id))
+ (areDesktopTasksVisible() && canUnminimizeDesktopTask(
+ singleTask.getTask().key.id))
? createDesktopAppLaunchRemoteTransition(AppLaunchType.UNMINIMIZE,
- Cuj.CUJ_DESKTOP_MODE_APP_LAUNCH_FROM_ICON)
+ Cuj.CUJ_DESKTOP_MODE_APP_LAUNCH_FROM_ICON)
: null;
if (areDesktopTasksVisible() && mControllers.uiController.isInOverviewUi()) {
RunnableList runnableList = recents.launchRunningDesktopTaskView();
@@ -1305,12 +1309,12 @@
// launch.
if (runnableList != null) {
runnableList.add(() -> UI_HELPER_EXECUTOR.execute(
- () -> handleGroupTaskLaunch(groupTask, remoteTransition,
+ () -> handleGroupTaskLaunch(singleTask, remoteTransition,
areDesktopTasksVisible(),
DesktopTaskToFrontReason.TASKBAR_TAP)));
}
} else {
- handleGroupTaskLaunch(groupTask, remoteTransition, areDesktopTasksVisible(),
+ handleGroupTaskLaunch(singleTask, remoteTransition, areDesktopTasksVisible(),
DesktopTaskToFrontReason.TASKBAR_TAP);
}
mControllers.taskbarStashController.updateAndAnimateTransientTaskbar(true);
@@ -1480,13 +1484,13 @@
remoteTransition));
return;
}
- if (onDesktop) {
- boolean useRemoteTransition = canUnminimizeDesktopTask(task.task1.key.id);
+ if (onDesktop && task instanceof SingleTask singleTask) {
+ boolean useRemoteTransition = canUnminimizeDesktopTask(singleTask.getTask().key.id);
UI_HELPER_EXECUTOR.execute(() -> {
if (onStartCallback != null) {
onStartCallback.run();
}
- SystemUiProxy.INSTANCE.get(this).showDesktopApp(task.task1.key.id,
+ SystemUiProxy.INSTANCE.get(this).showDesktopApp(singleTask.getTask().key.id,
useRemoteTransition ? remoteTransition : null, toFrontReason);
if (onFinishCallback != null) {
onFinishCallback.run();
@@ -1494,18 +1498,19 @@
});
return;
}
- if (task.task2 == null) {
+ if (task instanceof SingleTask singleTask) {
UI_HELPER_EXECUTOR.execute(() -> {
ActivityOptions activityOptions =
makeDefaultActivityOptions(SPLASH_SCREEN_STYLE_UNDEFINED).options;
activityOptions.setRemoteTransition(remoteTransition);
ActivityManagerWrapper.getInstance().startActivityFromRecents(
- task.task1.key, activityOptions);
+ singleTask.getTask().key, activityOptions);
});
return;
}
- mControllers.uiController.launchSplitTasks(task, remoteTransition);
+ assert task instanceof SplitTask;
+ mControllers.uiController.launchSplitTasks((SplitTask) task, remoteTransition);
}
/** Returns whether the given task is minimized and can be unminimized. */
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
index a9e8d6d..3a83db2 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
@@ -80,9 +80,9 @@
import com.android.launcher3.util.IntSet;
import com.android.launcher3.util.ItemInfoMatcher;
import com.android.launcher3.views.BubbleTextHolder;
-import com.android.quickstep.util.GroupTask;
import com.android.quickstep.util.LogUtils;
import com.android.quickstep.util.MultiValueUpdateListener;
+import com.android.quickstep.util.SingleTask;
import com.android.systemui.shared.recents.model.Task;
import com.android.wm.shell.shared.draganddrop.DragAndDropConstants;
@@ -433,8 +433,8 @@
null, item.user));
}
intent.putExtra(Intent.EXTRA_USER, item.user);
- } else if (tag instanceof GroupTask groupTask && !groupTask.hasMultipleTasks()) {
- Task task = groupTask.task1;
+ } else if (tag instanceof SingleTask singleTask) {
+ Task task = singleTask.getTask();
clipDescription = new ClipDescription(task.titleDescription,
new String[] {
ClipDescription.MIMETYPE_APPLICATION_TASK
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarRecentAppsController.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarRecentAppsController.kt
index 6047999..417ef7e 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarRecentAppsController.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarRecentAppsController.kt
@@ -76,12 +76,14 @@
var shownTasks: List<GroupTask> = emptyList()
private set
+ val shownTaskIds: List<Int>
+ get() = shownTasks.flatMap { shownTask -> shownTask.tasks }.map { it.key.id }
+
/**
- * The task-state of an app, i.e. whether the app has a task and what state
- * that task is in.
+ * The task-state of an app, i.e. whether the app has a task and what state that task is in.
*
- * @property taskId The ID of the task if one exists (i.e. if the state is
- * RUNNING or MINIMIZED), null otherwise (NOT_RUNNING).
+ * @property taskId The ID of the task if one exists (i.e. if the state is RUNNING or
+ * MINIMIZED), null otherwise (NOT_RUNNING).
*/
data class TaskState(val runningAppState: RunningAppState, val taskId: Int? = null)
@@ -214,9 +216,9 @@
return shownHotseatItems.toTypedArray()
}
- private fun getOrderedAndWrappedDesktopTasks(): List<GroupTask> {
+ private fun getOrderedAndWrappedDesktopTasks(): List<SingleTask> {
val tasks = desktopTask?.tasks ?: emptyList()
- // Kind of hacky, we wrap each single task in the Desktop as a GroupTask.
+ // We wrap each task in the Desktop as a `SingleTask`.
val orderFromId = orderedRunningTaskIds.withIndex().associate { (index, id) -> id to index }
val sortedTasks = tasks.sortedWith(compareBy(nullsLast()) { orderFromId[it.key.id] })
return sortedTasks.map { SingleTask(it) }
@@ -286,7 +288,7 @@
}
private fun updateOrderedRunningTaskIds(): MutableList<Int> {
- val desktopTasksAsList = getOrderedAndWrappedDesktopTasks().flatMap { it.tasks }
+ val desktopTasksAsList = getOrderedAndWrappedDesktopTasks().map { it.task }
val desktopTaskIds = desktopTasksAsList.map { it.key.id }
var newOrder =
orderedRunningTaskIds
@@ -311,42 +313,43 @@
val newShownTasks =
if (Flags.enableMultiInstanceMenuTaskbar()) {
val deduplicatedDesktopTasks =
- desktopTasks.distinctBy { Pair(it.task1.key.packageName, it.task1.key.userId) }
+ desktopTasks.distinctBy { Pair(it.task.key.packageName, it.task.key.userId) }
shownTasks
.filter {
- !it.supportsMultipleTasks() &&
- it.task1.key.id in deduplicatedDesktopTasks.map { it.task1.key.id }
+ it is SingleTask &&
+ it.task.key.id in deduplicatedDesktopTasks.map { it.task.key.id }
}
.toMutableList()
.apply {
addAll(
deduplicatedDesktopTasks.filter { currentTask ->
- val currentTaskKey = currentTask.task1.key
- currentTaskKey.id !in shownTasks.map { it.task1.key.id } &&
+ val currentTaskKey = currentTask.task.key
+ currentTaskKey.id !in shownTaskIds &&
shownHotseatItems.none { hotseatItem ->
- hotseatItem.targetPackage == currentTaskKey.packageName &&
- hotseatItem.user.identifier == currentTaskKey.userId
+ currentTask.containsPackage(
+ hotseatItem.targetPackage,
+ hotseatItem.user.identifier,
+ )
}
}
)
}
} else {
- val desktopTaskIds = desktopTasks.map { it.task1.key.id }
+ val desktopTaskIds = desktopTasks.map { it.task.key.id }
val shownHotseatItemTaskIds =
shownHotseatItems.mapNotNull { it as? TaskItemInfo }.map { it.taskId }
shownTasks
- .filter { !it.supportsMultipleTasks() && it.task1.key.id in desktopTaskIds }
+ .filter { it is SingleTask && it.task.key.id in desktopTaskIds }
.toMutableList()
.apply {
addAll(
desktopTasks.filter { desktopTask ->
- desktopTask.task1.key.id !in
- shownTasks.map { shownTask -> shownTask.task1.key.id }
+ desktopTask.task.key.id !in shownTaskIds
}
)
- removeAll { it.task1.key.id in shownHotseatItemTaskIds }
+ removeAll { it is SingleTask && it.task.key.id in shownHotseatItemTaskIds }
}
}
@@ -371,21 +374,28 @@
groupTasks: List<GroupTask>,
shownHotseatItems: List<ItemInfo>,
): List<GroupTask> {
+ // TODO: b/393476333 - Check the behavior of the Taskbar recents section when empty desks
+ // become supported.
return if (Flags.enableMultiInstanceMenuTaskbar()) {
groupTasks.filter { groupTask ->
- val taskKey = groupTask.task1.key
// Keep tasks that are group tasks or unique package name/user combinations
- groupTask.hasMultipleTasks() ||
- shownHotseatItems.none {
- it.targetPackage == taskKey.packageName &&
- it.user.identifier == taskKey.userId
- }
+ when (groupTask) {
+ is SingleTask ->
+ shownHotseatItems.none {
+ groupTask.containsPackage(it.targetPackage, it.user.identifier)
+ }
+
+ else -> true
+ }
}
} else {
val hotseatPackages = shownHotseatItems.map { it.targetPackage }
groupTasks.filter { groupTask ->
- groupTask.hasMultipleTasks() ||
- !hotseatPackages.contains(groupTask.task1.key.packageName)
+ when (groupTask) {
+ is SingleTask -> hotseatPackages.none { groupTask.containsPackage(it) }
+
+ else -> true
+ }
}
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
index f29f95d..e5d642d 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
@@ -39,7 +39,7 @@
import com.android.launcher3.taskbar.bubbles.BubbleBarController;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.SplitConfigurationOptions;
-import com.android.quickstep.util.GroupTask;
+import com.android.quickstep.util.SplitTask;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskContainer;
import com.android.quickstep.views.TaskView;
@@ -332,7 +332,7 @@
* Launches the given task in split-screen.
*/
public void launchSplitTasks(
- @NonNull GroupTask groupTask, @Nullable RemoteTransition remoteTransition) { }
+ @NonNull SplitTask splitTask, @Nullable RemoteTransition remoteTransition) { }
/**
* Returns the matching view (if any) in the taskbar.
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
index e4e97e5..c7f33e9 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
@@ -70,6 +70,7 @@
import com.android.launcher3.util.Themes;
import com.android.launcher3.views.ActivityContext;
import com.android.quickstep.util.GroupTask;
+import com.android.quickstep.util.SingleTask;
import com.android.quickstep.views.TaskViewType;
import com.android.systemui.shared.recents.model.Task;
import com.android.wm.shell.shared.bubbles.BubbleBarLocation;
@@ -657,9 +658,10 @@
final Set<GroupTask> recentTasksSet = new ArraySet<>(recentTasks);
for (GroupTask task : recentTasks) {
if (mTaskbarOverflowView != null && overflownTasks != null
- && overflownTasks.size() < itemsToAddToOverflow) {
+ && overflownTasks.size() < itemsToAddToOverflow
+ && task instanceof SingleTask singleTask) {
// TODO(b/343289567 and b/316004172): support app pairs and desktop mode.
- overflownTasks.add(task.task1);
+ overflownTasks.add(singleTask.getTask());
if (overflownTasks.size() == itemsToAddToOverflow) {
mTaskbarOverflowView.setItems(overflownTasks);
}
@@ -733,18 +735,22 @@
&& tagClass.isInstance(getChildAt(mNextViewIndex).getTag());
}
- /** Binds the GroupTask to the BubbleTextView to be ready to present to the user. */
+ /** Binds the SingleTask to the BubbleTextView to be ready to present to the user. */
public void applyGroupTaskToBubbleTextView(BubbleTextView btv, GroupTask groupTask) {
- // TODO(b/343289567): support app pairs.
- Task task1 = groupTask.task1;
+ if (!(groupTask instanceof SingleTask singleTask)) {
+ // TODO(b/343289567 and b/316004172): support app pairs and desktop mode.
+ return;
+ }
+
+ Task task = singleTask.getTask();
// TODO(b/344038728): use FastBitmapDrawable instead of Drawable, to get disabled state
// while dragging.
- Drawable taskIcon = groupTask.task1.icon;
+ Drawable taskIcon = task.icon;
if (taskIcon != null) {
taskIcon = taskIcon.getConstantState().newDrawable().mutate();
}
- btv.applyIconAndLabel(taskIcon, task1.titleDescription);
- btv.setTag(groupTask);
+ btv.applyIconAndLabel(taskIcon, task.titleDescription);
+ btv.setTag(singleTask);
}
/**
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
index 0f05887..cbc5d3d 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
@@ -92,6 +92,7 @@
import com.android.launcher3.util.MultiTranslateDelegate;
import com.android.launcher3.util.MultiValueAlpha;
import com.android.quickstep.util.GroupTask;
+import com.android.quickstep.util.SingleTask;
import com.android.systemui.shared.recents.model.Task;
import com.android.wm.shell.shared.bubbles.BubbleBarLocation;
@@ -739,9 +740,9 @@
return mControllers.taskbarRecentAppsController.getRunningAppState(
itemInfo.getTaskId());
}
- if (tag instanceof GroupTask groupTask && !groupTask.hasMultipleTasks()) {
+ if (tag instanceof SingleTask singleTask) {
return mControllers.taskbarRecentAppsController.getRunningAppState(
- groupTask.task1.key.id);
+ singleTask.getTask().key.id);
}
return BubbleTextView.RunningAppState.NOT_RUNNING;
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index f672840..c880aa9 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -178,10 +178,10 @@
import com.android.quickstep.TouchInteractionService.TISBinder;
import com.android.quickstep.util.ActiveGestureProtoLogProxy;
import com.android.quickstep.util.AsyncClockEventDelegate;
-import com.android.quickstep.util.GroupTask;
import com.android.quickstep.util.LauncherUnfoldAnimationController;
import com.android.quickstep.util.QuickstepOnboardingPrefs;
import com.android.quickstep.util.SplitSelectStateController;
+import com.android.quickstep.util.SplitTask;
import com.android.quickstep.util.SplitToWorkspaceController;
import com.android.quickstep.util.SplitWithKeyboardShortcutController;
import com.android.quickstep.util.TISBindHelper;
@@ -1386,33 +1386,23 @@
}
/**
- * Launches the given {@link GroupTask} in splitscreen.
+ * Launches the given {@link SplitTask} in splitscreen.
*/
public void launchSplitTasks(
- @NonNull GroupTask groupTask, @Nullable RemoteTransition remoteTransition) {
- // SplitBounds can be null if coming from Taskbar launch.
- final boolean firstTaskIsLeftTopTask = isFirstTaskLeftTopTask(groupTask);
- // task2 should never be null when calling this method. Allow a crash to catch invalid calls
- Task task1 = firstTaskIsLeftTopTask ? groupTask.task1 : groupTask.task2;
- Task task2 = firstTaskIsLeftTopTask ? groupTask.task2 : groupTask.task1;
+ @NonNull SplitTask splitTask, @Nullable RemoteTransition remoteTransition) {
mSplitSelectStateController.launchExistingSplitPair(
null /* launchingTaskView */,
- task1.key.id,
- task2.key.id,
+ splitTask.getTopLeftTask().key.id,
+ splitTask.getBottomRightTask().key.id,
SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT,
/* callback= */ success -> mSplitSelectStateController.resetState(),
/* freezeTaskList= */ false,
- groupTask.mSplitBounds == null
+ splitTask.mSplitBounds == null
? SNAP_TO_2_50_50
- : groupTask.mSplitBounds.snapPosition,
+ : splitTask.mSplitBounds.snapPosition,
remoteTransition);
}
- private static boolean isFirstTaskLeftTopTask(@NonNull GroupTask groupTask) {
- return groupTask.mSplitBounds == null
- || groupTask.mSplitBounds.leftTopTaskId == groupTask.task1.key.id;
- }
-
/**
* Launches two apps as an app pair.
*/
diff --git a/quickstep/src/com/android/quickstep/util/DesktopTask.kt b/quickstep/src/com/android/quickstep/util/DesktopTask.kt
index 5463cf7..0669185 100644
--- a/quickstep/src/com/android/quickstep/util/DesktopTask.kt
+++ b/quickstep/src/com/android/quickstep/util/DesktopTask.kt
@@ -27,8 +27,6 @@
override fun containsTask(taskId: Int) = tasks.any { it.key.id == taskId }
- override fun hasMultipleTasks() = tasks.size > 1
-
override fun supportsMultipleTasks() = true
override fun copy() = DesktopTask(tasks)
diff --git a/quickstep/src/com/android/quickstep/util/GroupTask.kt b/quickstep/src/com/android/quickstep/util/GroupTask.kt
index d5bbcd3..8237d2e 100644
--- a/quickstep/src/com/android/quickstep/util/GroupTask.kt
+++ b/quickstep/src/com/android/quickstep/util/GroupTask.kt
@@ -50,9 +50,16 @@
/**
* Returns true if a task in this group has a package name that matches the given `packageName`.
*/
- fun containsPackage(packageName: String) = tasks.any { it.key.packageName == packageName }
+ fun containsPackage(packageName: String?) = tasks.any { it.key.packageName == packageName }
- open fun hasMultipleTasks() = task2 != null
+ /**
+ * Returns true if a task in this group has a package name that matches the given `packageName`,
+ * and its user ID matches the given `userId`.
+ */
+ fun containsPackage(packageName: String?, userId: Int) =
+ tasks.any { it.key.packageName == packageName && it.key.userId == userId }
+
+ fun isEmpty() = tasks.isEmpty()
/** Returns whether this task supports multiple tasks or not. */
open fun supportsMultipleTasks() = taskViewType == TaskViewType.GROUPED
@@ -78,6 +85,10 @@
/** A [Task] container that must contain exactly one task in the recent tasks list. */
class SingleTask(task: Task) :
GroupTask(task, task2 = null, mSplitBounds = null, TaskViewType.SINGLE) {
+
+ val task: Task
+ get() = task1
+
override fun copy() = SingleTask(task1)
override fun toString() = "type=$taskViewType task=$task1"
@@ -96,6 +107,12 @@
class SplitTask(task1: Task, task2: Task, splitBounds: SplitConfigurationOptions.SplitBounds) :
GroupTask(task1, task2, splitBounds, TaskViewType.GROUPED) {
+ val topLeftTask: Task
+ get() = if (mSplitBounds!!.leftTopTaskId == task1.key.id) task1!! else task2!!
+
+ val bottomRightTask: Task
+ get() = if (topLeftTask == task1) task2!! else task1!!
+
override fun copy() = SplitTask(task1, task2!!, mSplitBounds!!)
override fun toString() = "type=$taskViewType task1=$task1 task2=$task2"
diff --git a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
index 5f8b4d9..fd8b356 100644
--- a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
+++ b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
@@ -71,7 +71,6 @@
import com.android.launcher3.R;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.apppairs.AppPairIcon;
-import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.icons.IconProvider;
import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.model.data.ItemInfo;
@@ -260,7 +259,7 @@
GroupTask groupTask = taskGroups.get(i);
if (isInstanceOfAppPair(
groupTask, componentKeys.get(0), componentKeys.get(1))) {
- lastActiveTasks[0] = groupTask.task1;
+ lastActiveTasks[0] = ((SplitTask) groupTask).getTopLeftTask();
break;
}
}
@@ -314,11 +313,15 @@
*/
public boolean isInstanceOfAppPair(GroupTask groupTask, @NonNull ComponentKey componentKey1,
@NonNull ComponentKey componentKey2) {
- return ((isInstanceOfComponent(groupTask.task1, componentKey1)
- && isInstanceOfComponent(groupTask.task2, componentKey2))
- ||
- (isInstanceOfComponent(groupTask.task1, componentKey2)
- && isInstanceOfComponent(groupTask.task2, componentKey1)));
+ if (groupTask instanceof SplitTask splitTask) {
+ return ((isInstanceOfComponent(splitTask.getTopLeftTask(), componentKey1)
+ && isInstanceOfComponent(splitTask.getBottomRightTask(), componentKey2))
+ ||
+ (isInstanceOfComponent(splitTask.getTopLeftTask(), componentKey2)
+ && isInstanceOfComponent(splitTask.getBottomRightTask(),
+ componentKey1)));
+ }
+ return false;
}
/**
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index c0b026b..c6db576 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -212,9 +212,11 @@
import com.android.quickstep.util.LayoutUtils;
import com.android.quickstep.util.RecentsAtomicAnimationFactory;
import com.android.quickstep.util.RecentsOrientedState;
+import com.android.quickstep.util.SingleTask;
import com.android.quickstep.util.SplitAnimationController.Companion.SplitAnimInitProps;
import com.android.quickstep.util.SplitAnimationTimings;
import com.android.quickstep.util.SplitSelectStateController;
+import com.android.quickstep.util.SplitTask;
import com.android.quickstep.util.SurfaceTransaction;
import com.android.quickstep.util.SurfaceTransactionApplier;
import com.android.quickstep.util.TaskGridNavHelper;
@@ -1968,7 +1970,7 @@
GroupTask groupTask = taskGroups.get(i);
boolean containsStagedTask = stagedTaskIdToBeRemoved != INVALID_TASK_ID
&& groupTask.containsTask(stagedTaskIdToBeRemoved);
- boolean shouldSkipGroupTask = containsStagedTask && !groupTask.hasMultipleTasks();
+ boolean shouldSkipGroupTask = containsStagedTask && groupTask instanceof SingleTask;
if ((isSplitSelectionActive() && groupTask.taskViewType == TaskViewType.DESKTOP)
|| shouldSkipGroupTask) {
@@ -1982,25 +1984,27 @@
// to be a temporary container for the remaining task.
TaskView taskView = getTaskViewFromPool(
containsStagedTask ? TaskViewType.SINGLE : groupTask.taskViewType);
- if (taskView instanceof GroupedTaskView) {
- boolean firstTaskIsLeftTopTask =
- groupTask.mSplitBounds.leftTopTaskId == groupTask.task1.key.id;
- Task leftTopTask = firstTaskIsLeftTopTask ? groupTask.task1 : groupTask.task2;
- Task rightBottomTask = firstTaskIsLeftTopTask ? groupTask.task2 : groupTask.task1;
- ((GroupedTaskView) taskView).bind(leftTopTask, rightBottomTask, mOrientationState,
- mTaskOverlayFactory, groupTask.mSplitBounds);
- } else if (taskView instanceof DesktopTaskView) {
+ if (taskView instanceof GroupedTaskView groupedTaskView) {
+ var splitTask = (SplitTask) groupTask;
+ groupedTaskView.bind(splitTask.getTopLeftTask(),
+ splitTask.getBottomRightTask(), mOrientationState,
+ mTaskOverlayFactory, splitTask.mSplitBounds);
+ } else if (taskView instanceof DesktopTaskView desktopTaskView) {
// Minimized tasks should not be shown in Overview
List<Task> nonMinimizedTasks =
groupTask.getTasks().stream()
.filter(task -> !task.isMinimized)
.toList();
- ((DesktopTaskView) taskView).bind(nonMinimizedTasks, mOrientationState,
+ desktopTaskView.bind(nonMinimizedTasks, mOrientationState,
mTaskOverlayFactory);
- } else {
- Task task = groupTask.task1.key.id == stagedTaskIdToBeRemoved ? groupTask.task2
- : groupTask.task1;
+ } else if (groupTask instanceof SplitTask splitTask) {
+ Task task = splitTask.getTopLeftTask().key.id == stagedTaskIdToBeRemoved
+ ? splitTask.getBottomRightTask()
+ : splitTask.getTopLeftTask();
taskView.bind(task, mOrientationState, mTaskOverlayFactory);
+ } else {
+ taskView.bind(((SingleTask) groupTask).getTask(), mOrientationState,
+ mTaskOverlayFactory);
}
addView(taskView);
diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/util/SplitSelectStateControllerTest.kt b/quickstep/tests/multivalentTests/src/com/android/quickstep/util/SplitSelectStateControllerTest.kt
index 0491c07..e4bdba5 100644
--- a/quickstep/tests/multivalentTests/src/com/android/quickstep/util/SplitSelectStateControllerTest.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/util/SplitSelectStateControllerTest.kt
@@ -102,12 +102,12 @@
fun activeTasks_noMatchingTasks() {
val nonMatchingComponent = ComponentKey(ComponentName("no", "match"), primaryUserHandle)
val groupTask1 =
- generateGroupTask(
+ generateSplitTask(
ComponentName("pomegranate", "juice"),
ComponentName("pumpkin", "pie"),
)
val groupTask2 =
- generateGroupTask(
+ generateSplitTask(
ComponentName("hotdog", "juice"),
ComponentName("personal", "computer"),
)
@@ -143,12 +143,12 @@
val matchingComponent =
ComponentKey(ComponentName(matchingPackage, matchingClass), primaryUserHandle)
val groupTask1 =
- generateGroupTask(
+ generateSplitTask(
ComponentName(matchingPackage, matchingClass),
ComponentName("pomegranate", "juice"),
)
val groupTask2 =
- generateGroupTask(
+ generateSplitTask(
ComponentName("pumpkin", "pie"),
ComponentName("personal", "computer"),
)
@@ -170,7 +170,7 @@
it[0].key.baseIntent.component?.className,
matchingClass,
)
- assertEquals(it[0], groupTask1.task1)
+ assertEquals(it[0], groupTask1.topLeftTask)
}
// Capture callback from recentsModel#getTasks()
@@ -196,12 +196,12 @@
val nonPrimaryUserComponent =
ComponentKey(ComponentName(matchingPackage, matchingClass), nonPrimaryUserHandle)
val groupTask1 =
- generateGroupTask(
+ generateSplitTask(
ComponentName(matchingPackage, matchingClass),
ComponentName("pomegranate", "juice"),
)
val groupTask2 =
- generateGroupTask(
+ generateSplitTask(
ComponentName("pumpkin", "pie"),
ComponentName("personal", "computer"),
)
@@ -237,14 +237,14 @@
val nonPrimaryUserComponent =
ComponentKey(ComponentName(matchingPackage, matchingClass), nonPrimaryUserHandle)
val groupTask1 =
- generateGroupTask(
+ generateSplitTask(
ComponentName(matchingPackage, matchingClass),
nonPrimaryUserHandle,
ComponentName("pomegranate", "juice"),
nonPrimaryUserHandle,
)
val groupTask2 =
- generateGroupTask(
+ generateSplitTask(
ComponentName("pumpkin", "pie"),
ComponentName("personal", "computer"),
)
@@ -267,7 +267,7 @@
matchingClass,
)
assertEquals("userId mismatched", it[0].key.userId, nonPrimaryUserHandle.identifier)
- assertEquals(it[0], groupTask1.task1)
+ assertEquals(it[0], groupTask1.topLeftTask)
}
// Capture callback from recentsModel#getTasks()
@@ -293,12 +293,12 @@
val matchingComponent =
ComponentKey(ComponentName(matchingPackage, matchingClass), primaryUserHandle)
val groupTask1 =
- generateGroupTask(
+ generateSplitTask(
ComponentName(matchingPackage, matchingClass),
ComponentName("pumpkin", "pie"),
)
val groupTask2 =
- generateGroupTask(
+ generateSplitTask(
ComponentName("pomegranate", "juice"),
ComponentName(matchingPackage, matchingClass),
)
@@ -320,7 +320,7 @@
it[0].key.baseIntent.component?.className,
matchingClass,
)
- assertEquals(it[0], groupTask1.task1)
+ assertEquals(it[0], groupTask1.topLeftTask)
}
// Capture callback from recentsModel#getTasks()
@@ -348,9 +348,9 @@
ComponentKey(ComponentName(matchingPackage, matchingClass), primaryUserHandle)
val groupTask1 =
- generateGroupTask(ComponentName("hotdog", "pie"), ComponentName("pumpkin", "pie"))
+ generateSplitTask(ComponentName("hotdog", "pie"), ComponentName("pumpkin", "pie"))
val groupTask2 =
- generateGroupTask(
+ generateSplitTask(
ComponentName("pomegranate", "juice"),
ComponentName(matchingPackage, matchingClass),
)
@@ -374,7 +374,7 @@
it[1].key.baseIntent.component?.className,
matchingClass,
)
- assertEquals(it[1], groupTask2.task2)
+ assertEquals(it[1], groupTask2.bottomRightTask)
}
// Capture callback from recentsModel#getTasks()
@@ -401,9 +401,9 @@
ComponentKey(ComponentName(matchingPackage, matchingClass), primaryUserHandle)
val groupTask1 =
- generateGroupTask(ComponentName("hotdog", "pie"), ComponentName("pumpkin", "pie"))
+ generateSplitTask(ComponentName("hotdog", "pie"), ComponentName("pumpkin", "pie"))
val groupTask2 =
- generateGroupTask(
+ generateSplitTask(
ComponentName("pomegranate", "juice"),
ComponentName(matchingPackage, matchingClass),
)
@@ -426,7 +426,7 @@
it[0].key.baseIntent.component?.className,
matchingClass,
)
- assertEquals(it[0], groupTask2.task2)
+ assertEquals(it[0], groupTask2.bottomRightTask)
assertNull("No tasks should have matched", it[1] /*task*/)
}
@@ -454,12 +454,12 @@
ComponentKey(ComponentName(matchingPackage, matchingClass), primaryUserHandle)
val groupTask1 =
- generateGroupTask(
+ generateSplitTask(
ComponentName(matchingPackage, matchingClass),
ComponentName("pumpkin", "pie"),
)
val groupTask2 =
- generateGroupTask(
+ generateSplitTask(
ComponentName("pomegranate", "juice"),
ComponentName(matchingPackage, matchingClass),
)
@@ -482,7 +482,7 @@
it[0].key.baseIntent.component?.className,
matchingClass,
)
- assertEquals(it[0], groupTask1.task1)
+ assertEquals(it[0], groupTask1.topLeftTask)
assertEquals(
"ComponentName package mismatched",
it[1].key.baseIntent.component?.packageName,
@@ -493,7 +493,7 @@
it[1].key.baseIntent.component?.className,
matchingClass,
)
- assertEquals(it[1], groupTask2.task2)
+ assertEquals(it[1], groupTask2.bottomRightTask)
}
// Capture callback from recentsModel#getTasks()
@@ -524,14 +524,14 @@
ComponentKey(ComponentName(matchingPackage2, matchingClass2), primaryUserHandle)
val groupTask1 =
- generateGroupTask(ComponentName("hotdog", "pie"), ComponentName("pumpkin", "pie"))
+ generateSplitTask(ComponentName("hotdog", "pie"), ComponentName("pumpkin", "pie"))
val groupTask2 =
- generateGroupTask(
+ generateSplitTask(
ComponentName(matchingPackage2, matchingClass2),
ComponentName(matchingPackage, matchingClass),
)
val groupTask3 =
- generateGroupTask(
+ generateSplitTask(
ComponentName("hotdog", "pie"),
ComponentName(matchingPackage, matchingClass),
)
@@ -545,7 +545,7 @@
val taskConsumer =
Consumer<Array<Task>> {
assertEquals("Expected array length 2", 2, it.size)
- assertEquals("Found wrong task", it[0], groupTask2.task1)
+ assertEquals("Found wrong task", it[0], groupTask2.topLeftTask)
}
// Capture callback from recentsModel#getTasks()
@@ -640,11 +640,11 @@
verify(recentsView, times(0)).resetDesktopTaskFromSplitSelectState()
}
- // Generate GroupTask with default userId.
- private fun generateGroupTask(
+ /** Generates a [SplitTask] with default userId. */
+ private fun generateSplitTask(
task1ComponentName: ComponentName,
task2ComponentName: ComponentName,
- ): GroupTask {
+ ): SplitTask {
val task1 = Task()
var taskInfo = ActivityManager.RunningTaskInfo()
taskInfo.taskId = getUniqueId()
@@ -666,20 +666,20 @@
SplitConfigurationOptions.SplitBounds(
/* leftTopBounds = */ Rect(),
/* rightBottomBounds = */ Rect(),
- /* leftTopTaskId = */ -1,
- /* rightBottomTaskId = */ -1,
+ /* leftTopTaskId = */ task1.key.id,
+ /* rightBottomTaskId = */ task2.key.id,
/* snapPosition = */ SNAP_TO_2_50_50,
),
)
}
- // Generate GroupTask with custom user handles.
- private fun generateGroupTask(
+ /** Generates a [SplitTask] with custom user handles. */
+ private fun generateSplitTask(
task1ComponentName: ComponentName,
userHandle1: UserHandle,
task2ComponentName: ComponentName,
userHandle2: UserHandle,
- ): GroupTask {
+ ): SplitTask {
val task1 = Task()
var taskInfo = ActivityManager.RunningTaskInfo()
taskInfo.taskId = getUniqueId()
@@ -704,8 +704,8 @@
SplitConfigurationOptions.SplitBounds(
/* leftTopBounds = */ Rect(),
/* rightBottomBounds = */ Rect(),
- /* leftTopTaskId = */ -1,
- /* rightBottomTaskId = */ -1,
+ /* leftTopTaskId = */ task1.key.id,
+ /* rightBottomTaskId = */ task2.key.id,
/* snapPosition = */ SNAP_TO_2_50_50,
),
)