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:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user