Merge "Launch multiple tasks at once" into sc-v2-dev am: 438f796626

Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Launcher3/+/15705481

Change-Id: I79b5fc2781fd6746cdcf4ee08c7216548c2479fa
This commit is contained in:
TreeHugger Robot
2021-08-30 21:31:39 +00:00
committed by Automerger Merge Worker
4 changed files with 55 additions and 41 deletions
@@ -366,8 +366,8 @@ public final class TaskViewUtils {
* 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 @@ public final class TaskViewUtils {
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 @@ public final class TaskViewUtils {
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 @@ public final class TaskViewUtils {
}
/** 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 @@ public final class TaskViewUtils {
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;
}
}
@@ -33,7 +33,7 @@ import com.android.launcher3.util.SplitConfigurationOptions.StagePosition;
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 @@ import com.android.systemui.shared.system.RemoteTransitionRunner;
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 @@ public class SplitSelectStateController {
/**
* 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 @@ public class SplitSelectStateController {
*/
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 @@ public class SplitSelectStateController {
*/
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 @@ public class SplitSelectStateController {
* 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 @@ public class SplitSelectStateController {
* chosen
*/
public boolean isSplitSelectActive() {
return mInitialTaskView != null && mSecondTaskView == null;
return mInitialTask != null && mSecondTask == null;
}
public Rect getInitialBounds() {
@@ -4,6 +4,7 @@ import android.content.Context;
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;
@@ -94,6 +95,13 @@ public class GroupedTaskView extends TaskView {
}
}
@Override
public RunnableList launchTaskAnimated() {
getRecentsView().getSplitPlaceholder().launchTasks(mTask, mSecondaryTask,
SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT);
return null;
}
@Override
public void onRecycle() {
super.onRecycle();
@@ -3568,7 +3568,8 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
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 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
secondTaskEndingBounds, taskView.getThumbnail(),
true /*fadeWithThumbnail*/);
pendingAnimation.addEndListener(aBoolean -> {
mSplitSelectStateController.setSecondTaskId(taskView);
mSplitSelectStateController.setSecondTaskId(taskView.getTask());
resetFromSplitSelectionState();
});
mSecondSplitHiddenTaskView = taskView;