Launch multiple tasks at once
Bug: 195675206
Change-Id: I31c76e8dfec617092f73e989ce94bf0ab693d0d1
diff --git a/quickstep/src/com/android/quickstep/TaskViewUtils.java b/quickstep/src/com/android/quickstep/TaskViewUtils.java
index 5b9e214..d4c94db 100644
--- a/quickstep/src/com/android/quickstep/TaskViewUtils.java
+++ b/quickstep/src/com/android/quickstep/TaskViewUtils.java
@@ -366,8 +366,8 @@
* device is considered in multiWindowMode and things like insets and stuff change
* and calculations have to be adjusted in the animations for that
*/
- public static void composeRecentsSplitLaunchAnimator(@NonNull TaskView initialView,
- @NonNull TaskView v, @NonNull TransitionInfo transitionInfo,
+ public static void composeRecentsSplitLaunchAnimator(@NonNull Task initalTask,
+ @NonNull Task secondTask, @NonNull TransitionInfo transitionInfo,
SurfaceControl.Transaction t, @NonNull Runnable finishCallback) {
final TransitionInfo.Change[] splitRoots = new TransitionInfo.Change[2];
@@ -377,7 +377,7 @@
final int mode = change.getMode();
// Find the target tasks' root tasks since those are the split stages that need to
// be animated (the tasks themselves are children and thus inherit animation).
- if (taskId == initialView.getTask().key.id || taskId == v.getTask().key.id) {
+ if (taskId == initalTask.key.id || taskId == secondTask.key.id) {
if (!(mode == TRANSIT_OPEN || mode == TRANSIT_TO_FRONT)) {
throw new IllegalStateException(
"Expected task to be showing, but it is " + mode);
@@ -386,7 +386,7 @@
throw new IllegalStateException("Initiating multi-split launch but the split"
+ "root of " + taskId + " is already visible or has broken hierarchy.");
}
- splitRoots[taskId == initialView.getTask().key.id ? 0 : 1] =
+ splitRoots[taskId == initalTask.key.id ? 0 : 1] =
transitionInfo.getChange(change.getParent());
}
}
@@ -406,8 +406,8 @@
}
/** Legacy version (until shell transitions are enabled) */
- public static void composeRecentsSplitLaunchAnimatorLegacy(@NonNull TaskView initialView,
- @NonNull TaskView v, @NonNull RemoteAnimationTargetCompat[] appTargets,
+ public static void composeRecentsSplitLaunchAnimatorLegacy(@NonNull Task initialTask,
+ @NonNull Task secondTask, @NonNull RemoteAnimationTargetCompat[] appTargets,
@NonNull RemoteAnimationTargetCompat[] wallpaperTargets,
@NonNull RemoteAnimationTargetCompat[] nonAppTargets,
@NonNull Runnable finishCallback) {
@@ -416,12 +416,12 @@
for (int i = 0; i < appTargets.length; ++i) {
final int taskId = appTargets[i].taskInfo != null ? appTargets[i].taskInfo.taskId : -1;
final int mode = appTargets[i].mode;
- if (taskId == initialView.getTask().key.id || taskId == v.getTask().key.id) {
+ if (taskId == initialTask.key.id || taskId == secondTask.key.id) {
if (mode != MODE_OPENING) {
throw new IllegalStateException(
"Expected task to be opening, but it is " + mode);
}
- splitRoots[taskId == initialView.getTask().key.id ? 0 : 1] = i;
+ splitRoots[taskId == initialTask.key.id ? 0 : 1] = i;
}
}
diff --git a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
index cbc5584..ac5f5d8 100644
--- a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
+++ b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
@@ -33,7 +33,7 @@
import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.TaskAnimationManager;
import com.android.quickstep.TaskViewUtils;
-import com.android.quickstep.views.TaskView;
+import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.system.RemoteAnimationAdapterCompat;
import com.android.systemui.shared.system.RemoteAnimationRunnerCompat;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
@@ -47,23 +47,21 @@
public class SplitSelectStateController {
private final SystemUiProxy mSystemUiProxy;
- private TaskView mInitialTaskView;
- private TaskView mSecondTaskView;
private @StagePosition int mStagePosition;
+ private Task mInitialTask;
+ private Task mSecondTask;
private Rect mInitialBounds;
- private final Handler mHandler;
public SplitSelectStateController(Handler handler, SystemUiProxy systemUiProxy) {
mSystemUiProxy = systemUiProxy;
- mHandler = handler;
}
/**
* To be called after first task selected
*/
- public void setInitialTaskSelect(TaskView taskView, @StagePosition int stagePosition,
+ public void setInitialTaskSelect(Task taskView, @StagePosition int stagePosition,
Rect initialBounds) {
- mInitialTaskView = taskView;
+ mInitialTask = taskView;
mStagePosition = stagePosition;
mInitialBounds = initialBounds;
}
@@ -71,21 +69,28 @@
/**
* To be called after second task selected
*/
- public void setSecondTaskId(TaskView taskView) {
- mSecondTaskView = taskView;
+ public void setSecondTaskId(Task taskView) {
+ mSecondTask = taskView;
+ launchTasks(mInitialTask, mSecondTask, mStagePosition);
+ }
+
+ /**
+ * @param stagePosition representing location of task1
+ */
+ public void launchTasks(Task task1, Task task2, @StagePosition int stagePosition) {
// Assume initial task is for top/left part of screen
- final int[] taskIds = mStagePosition == STAGE_POSITION_TOP_OR_LEFT
- ? new int[]{mInitialTaskView.getTask().key.id, taskView.getTask().key.id}
- : new int[]{taskView.getTask().key.id, mInitialTaskView.getTask().key.id};
+ final int[] taskIds = stagePosition == STAGE_POSITION_TOP_OR_LEFT
+ ? new int[]{task1.key.id, task2.key.id}
+ : new int[]{task2.key.id, task1.key.id};
if (TaskAnimationManager.ENABLE_SHELL_TRANSITIONS) {
RemoteSplitLaunchTransitionRunner animationRunner =
- new RemoteSplitLaunchTransitionRunner(mInitialTaskView, taskView);
+ new RemoteSplitLaunchTransitionRunner(task1, task2);
mSystemUiProxy.startTasks(taskIds[0], null /* mainOptions */, taskIds[1],
null /* sideOptions */, STAGE_POSITION_BOTTOM_OR_RIGHT,
new RemoteTransitionCompat(animationRunner, MAIN_EXECUTOR));
} else {
RemoteSplitLaunchAnimationRunner animationRunner =
- new RemoteSplitLaunchAnimationRunner(mInitialTaskView, taskView);
+ new RemoteSplitLaunchAnimationRunner(task1, task2);
final RemoteAnimationAdapter adapter = new RemoteAnimationAdapter(
RemoteAnimationAdapterCompat.wrapRemoteAnimationRunner(animationRunner),
300, 150,
@@ -105,19 +110,19 @@
*/
private class RemoteSplitLaunchTransitionRunner implements RemoteTransitionRunner {
- private final TaskView mInitialTaskView;
- private final TaskView mTaskView;
+ private final Task mInitialTask;
+ private final Task mSecondTask;
- RemoteSplitLaunchTransitionRunner(TaskView initialTaskView, TaskView taskView) {
- mInitialTaskView = initialTaskView;
- mTaskView = taskView;
+ RemoteSplitLaunchTransitionRunner(Task initialTask, Task secondTask) {
+ mInitialTask = initialTask;
+ mSecondTask = secondTask;
}
@Override
public void startAnimation(IBinder transition, TransitionInfo info,
SurfaceControl.Transaction t, Runnable finishCallback) {
- TaskViewUtils.composeRecentsSplitLaunchAnimator(mInitialTaskView, mTaskView,
- info, t, finishCallback);
+ TaskViewUtils.composeRecentsSplitLaunchAnimator(mInitialTask,
+ mSecondTask, info, t, finishCallback);
// After successful launch, call resetState
resetState();
}
@@ -129,20 +134,20 @@
*/
private class RemoteSplitLaunchAnimationRunner implements RemoteAnimationRunnerCompat {
- private final TaskView mInitialTaskView;
- private final TaskView mTaskView;
+ private final Task mInitialTask;
+ private final Task mSecondTask;
- RemoteSplitLaunchAnimationRunner(TaskView initialTaskView, TaskView taskView) {
- mInitialTaskView = initialTaskView;
- mTaskView = taskView;
+ RemoteSplitLaunchAnimationRunner(Task initialTask, Task secondTask) {
+ mInitialTask = initialTask;
+ mSecondTask = secondTask;
}
@Override
public void onAnimationStart(int transit, RemoteAnimationTargetCompat[] apps,
RemoteAnimationTargetCompat[] wallpapers, RemoteAnimationTargetCompat[] nonApps,
Runnable finishedCallback) {
- TaskViewUtils.composeRecentsSplitLaunchAnimatorLegacy(mInitialTaskView, mTaskView, apps,
- wallpapers, nonApps, finishedCallback);
+ TaskViewUtils.composeRecentsSplitLaunchAnimatorLegacy(mInitialTask,
+ mSecondTask, apps, wallpapers, nonApps, finishedCallback);
// After successful launch, call resetState
resetState();
}
@@ -157,8 +162,8 @@
* To be called if split select was cancelled
*/
public void resetState() {
- mInitialTaskView = null;
- mSecondTaskView = null;
+ mInitialTask = null;
+ mSecondTask = null;
mStagePosition = SplitConfigurationOptions.STAGE_POSITION_UNDEFINED;
mInitialBounds = null;
}
@@ -168,7 +173,7 @@
* chosen
*/
public boolean isSplitSelectActive() {
- return mInitialTaskView != null && mSecondTaskView == null;
+ return mInitialTask != null && mSecondTask == null;
}
public Rect getInitialBounds() {
diff --git a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
index 1bc7c75..e1e1c65 100644
--- a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
+++ b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
@@ -4,6 +4,7 @@
import android.util.AttributeSet;
import com.android.launcher3.R;
+import com.android.launcher3.util.RunnableList;
import com.android.launcher3.util.SplitConfigurationOptions;
import com.android.quickstep.RecentsModel;
import com.android.quickstep.TaskThumbnailCache;
@@ -95,6 +96,13 @@
}
@Override
+ public RunnableList launchTaskAnimated() {
+ getRecentsView().getSplitPlaceholder().launchTasks(mTask, mSecondaryTask,
+ SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT);
+ return null;
+ }
+
+ @Override
public void onRecycle() {
super.onRecycle();
mSnapshotView2.setThumbnail(mSecondaryTask, null);
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 18387dc..810ecce 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -3568,7 +3568,8 @@
mSplitHiddenTaskView = taskView;
Rect initialBounds = new Rect(taskView.getLeft(), taskView.getTop(), taskView.getRight(),
taskView.getBottom());
- mSplitSelectStateController.setInitialTaskSelect(taskView, stagePosition, initialBounds);
+ mSplitSelectStateController.setInitialTaskSelect(taskView.getTask(),
+ stagePosition, initialBounds);
mSplitHiddenTaskViewIndex = indexOfChild(taskView);
if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
finishRecentsAnimation(true, null);
@@ -3609,7 +3610,7 @@
secondTaskEndingBounds, taskView.getThumbnail(),
true /*fadeWithThumbnail*/);
pendingAnimation.addEndListener(aBoolean -> {
- mSplitSelectStateController.setSecondTaskId(taskView);
+ mSplitSelectStateController.setSecondTaskId(taskView.getTask());
resetFromSplitSelectionState();
});
mSecondSplitHiddenTaskView = taskView;