Launch GroupedTaskView from thumbnails
* Previously when starting the remote animation we were relying on SplitPlaceholderViews to animate into the proper place since we weren't launching from the TaskView itself * Now when launching from a GroupedTaskView, we use the existing animation that handles that animation in addition to showing the new split tasks Fixes: 206608786 Test: Thumbnails animate from home -> overview -> launch Change-Id: I1499ead7d90cd41e285ed0f4df66ea31f0dfbc95
This commit is contained in:
parent
8c8e2a22da
commit
788821ec4e
|
@ -301,7 +301,8 @@ public abstract class BaseQuickstepLauncher extends Launcher
|
|||
mActionsView = findViewById(R.id.overview_actions_view);
|
||||
RecentsView overviewPanel = (RecentsView) getOverviewPanel();
|
||||
SplitSelectStateController controller =
|
||||
new SplitSelectStateController(mHandler, SystemUiProxy.INSTANCE.get(this));
|
||||
new SplitSelectStateController(mHandler, SystemUiProxy.INSTANCE.get(this),
|
||||
getStateManager(), getDepthController());
|
||||
overviewPanel.init(mActionsView, controller);
|
||||
mActionsView.setDp(getDeviceProfile());
|
||||
mActionsView.updateVerticalMargin(SysUINavigationMode.getMode(this));
|
||||
|
|
|
@ -128,7 +128,8 @@ public final class RecentsActivity extends StatefulActivity<RecentsState> {
|
|||
SYSUI_PROGRESS.set(getRootView().getSysUiScrim(), 0f);
|
||||
|
||||
SplitSelectStateController controller =
|
||||
new SplitSelectStateController(mHandler, SystemUiProxy.INSTANCE.get(this));
|
||||
new SplitSelectStateController(mHandler, SystemUiProxy.INSTANCE.get(this),
|
||||
getStateManager(), null /*depthController*/);
|
||||
mDragLayer.recreateControllers();
|
||||
mFallbackRecentsView.init(mActionsView, controller);
|
||||
|
||||
|
|
|
@ -56,6 +56,7 @@ import android.view.View;
|
|||
import android.window.TransitionInfo;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.launcher3.BaseActivity;
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
|
@ -72,6 +73,7 @@ import com.android.quickstep.util.MultiValueUpdateListener;
|
|||
import com.android.quickstep.util.SurfaceTransactionApplier;
|
||||
import com.android.quickstep.util.TaskViewSimulator;
|
||||
import com.android.quickstep.util.TransformParams;
|
||||
import com.android.quickstep.views.GroupedTaskView;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.quickstep.views.TaskThumbnailView;
|
||||
import com.android.quickstep.views.TaskView;
|
||||
|
@ -149,10 +151,12 @@ public final class TaskViewUtils {
|
|||
return taskView;
|
||||
}
|
||||
|
||||
public static void createRecentsWindowAnimator(TaskView v, boolean skipViewChanges,
|
||||
RemoteAnimationTargetCompat[] appTargets,
|
||||
RemoteAnimationTargetCompat[] wallpaperTargets,
|
||||
RemoteAnimationTargetCompat[] nonAppTargets, DepthController depthController,
|
||||
public static void createRecentsWindowAnimator(
|
||||
@NonNull TaskView v, boolean skipViewChanges,
|
||||
@NonNull RemoteAnimationTargetCompat[] appTargets,
|
||||
@NonNull RemoteAnimationTargetCompat[] wallpaperTargets,
|
||||
@NonNull RemoteAnimationTargetCompat[] nonAppTargets,
|
||||
@Nullable DepthController depthController,
|
||||
PendingAnimation out) {
|
||||
RecentsView recentsView = v.getRecentsView();
|
||||
boolean isQuickSwitch = v.isEndQuickswitchCuj();
|
||||
|
@ -418,15 +422,46 @@ public final class TaskViewUtils {
|
|||
finishCallback.run();
|
||||
}
|
||||
|
||||
/** Legacy version (until shell transitions are enabled) */
|
||||
public static void composeRecentsSplitLaunchAnimatorLegacy(@NonNull Task initialTask,
|
||||
/**
|
||||
* Legacy version (until shell transitions are enabled)
|
||||
*
|
||||
* If {@param launchingTaskView} is not null, then this will play the tasks launch animation
|
||||
* from the position of the GroupedTaskView (when user taps on the TaskView to start it).
|
||||
* Technically this case should be taken care of by
|
||||
* {@link #composeRecentsSplitLaunchAnimatorLegacy()} below, but the way we launch tasks whether
|
||||
* it's a single task or multiple tasks results in different entry-points.
|
||||
*
|
||||
* If it is null, then it will simply fade in the starting apps and fade out launcher (for the
|
||||
* case where launcher handles animating starting split tasks from app icon) */
|
||||
public static void composeRecentsSplitLaunchAnimatorLegacy(
|
||||
@Nullable GroupedTaskView launchingTaskView,
|
||||
@NonNull Task initialTask,
|
||||
@NonNull Task secondTask, @NonNull RemoteAnimationTargetCompat[] appTargets,
|
||||
@NonNull RemoteAnimationTargetCompat[] wallpaperTargets,
|
||||
@NonNull RemoteAnimationTargetCompat[] nonAppTargets,
|
||||
@NonNull StateManager stateManager,
|
||||
@Nullable DepthController depthController,
|
||||
@NonNull Runnable finishCallback) {
|
||||
if (launchingTaskView != null) {
|
||||
AnimatorSet animatorSet = new AnimatorSet();
|
||||
RecentsView recentsView = launchingTaskView.getRecentsView();
|
||||
animatorSet.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
super.onAnimationEnd(animation);
|
||||
finishCallback.run();
|
||||
}
|
||||
});
|
||||
composeRecentsLaunchAnimator(animatorSet, launchingTaskView,
|
||||
appTargets, wallpaperTargets, nonAppTargets,
|
||||
true, stateManager,
|
||||
recentsView, depthController);
|
||||
animatorSet.start();
|
||||
return;
|
||||
}
|
||||
|
||||
final ArrayList<SurfaceControl> openingTargets = new ArrayList<>();
|
||||
final ArrayList<SurfaceControl> closingTargets = new ArrayList<>();
|
||||
|
||||
for (RemoteAnimationTargetCompat appTarget : appTargets) {
|
||||
final int taskId = appTarget.taskInfo != null ? appTarget.taskInfo.taskId : -1;
|
||||
final int mode = appTarget.mode;
|
||||
|
@ -490,7 +525,7 @@ public final class TaskViewUtils {
|
|||
@NonNull RemoteAnimationTargetCompat[] wallpaperTargets,
|
||||
@NonNull RemoteAnimationTargetCompat[] nonAppTargets, boolean launcherClosing,
|
||||
@NonNull StateManager stateManager, @NonNull RecentsView recentsView,
|
||||
@NonNull DepthController depthController) {
|
||||
@Nullable DepthController depthController) {
|
||||
boolean skipLauncherChanges = !launcherClosing;
|
||||
|
||||
TaskView taskView = findTaskViewToLaunch(recentsView, v, appTargets);
|
||||
|
|
|
@ -30,11 +30,18 @@ import android.view.RemoteAnimationAdapter;
|
|||
import android.view.SurfaceControl;
|
||||
import android.window.TransitionInfo;
|
||||
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.launcher3.statehandlers.DepthController;
|
||||
import com.android.launcher3.statemanager.StateManager;
|
||||
import com.android.launcher3.util.SplitConfigurationOptions;
|
||||
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.GroupedTaskView;
|
||||
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;
|
||||
|
@ -52,23 +59,32 @@ public class SplitSelectStateController {
|
|||
|
||||
private final Handler mHandler;
|
||||
private final SystemUiProxy mSystemUiProxy;
|
||||
private final StateManager mStateManager;
|
||||
private final DepthController mDepthController;
|
||||
private @StagePosition int mStagePosition;
|
||||
private Task mInitialTask;
|
||||
private Task mSecondTask;
|
||||
private Rect mInitialBounds;
|
||||
private boolean mRecentsAnimationRunning;
|
||||
/** If not null, this is the TaskView we want to launch from */
|
||||
@Nullable
|
||||
private GroupedTaskView mLaunchingTaskView;
|
||||
|
||||
public SplitSelectStateController(Handler handler, SystemUiProxy systemUiProxy) {
|
||||
public SplitSelectStateController(Handler handler, SystemUiProxy systemUiProxy,
|
||||
StateManager stateManager,
|
||||
DepthController depthController) {
|
||||
mHandler = handler;
|
||||
mSystemUiProxy = systemUiProxy;
|
||||
mStateManager = stateManager;
|
||||
mDepthController = depthController;
|
||||
}
|
||||
|
||||
/**
|
||||
* To be called after first task selected
|
||||
*/
|
||||
public void setInitialTaskSelect(Task taskView, @StagePosition int stagePosition,
|
||||
public void setInitialTaskSelect(Task task, @StagePosition int stagePosition,
|
||||
Rect initialBounds) {
|
||||
mInitialTask = taskView;
|
||||
mInitialTask = task;
|
||||
mStagePosition = stagePosition;
|
||||
mInitialBounds = initialBounds;
|
||||
}
|
||||
|
@ -76,12 +92,24 @@ public class SplitSelectStateController {
|
|||
/**
|
||||
* To be called after second task selected
|
||||
*/
|
||||
public void setSecondTaskId(Task taskView, Consumer<Boolean> callback) {
|
||||
mSecondTask = taskView;
|
||||
public void setSecondTaskId(Task task, Consumer<Boolean> callback) {
|
||||
mSecondTask = task;
|
||||
launchTasks(mInitialTask, mSecondTask, mStagePosition, callback,
|
||||
false /* freezeTaskList */);
|
||||
}
|
||||
|
||||
/**
|
||||
* To be called when we want to launch split pairs from an existing GroupedTaskView.
|
||||
*/
|
||||
public void launchTasks(GroupedTaskView groupedTaskView,
|
||||
Consumer<Boolean> callback, boolean freezeTaskList) {
|
||||
mLaunchingTaskView = groupedTaskView;
|
||||
TaskView.TaskIdAttributeContainer[] taskIdAttributeContainers =
|
||||
groupedTaskView.getTaskIdAttributeContainers();
|
||||
launchTasks(taskIdAttributeContainers[0].getTask(), taskIdAttributeContainers[1].getTask(),
|
||||
taskIdAttributeContainers[0].getStagePosition(), callback, freezeTaskList);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param stagePosition representing location of task1
|
||||
*/
|
||||
|
@ -169,8 +197,9 @@ public class SplitSelectStateController {
|
|||
RemoteAnimationTargetCompat[] wallpapers, RemoteAnimationTargetCompat[] nonApps,
|
||||
Runnable finishedCallback) {
|
||||
postAsyncCallback(mHandler,
|
||||
() -> TaskViewUtils.composeRecentsSplitLaunchAnimatorLegacy(mInitialTask,
|
||||
mSecondTask, apps, wallpapers, nonApps, () -> {
|
||||
() -> TaskViewUtils.composeRecentsSplitLaunchAnimatorLegacy(
|
||||
mLaunchingTaskView, mInitialTask, mSecondTask, apps, wallpapers,
|
||||
nonApps, mStateManager, mDepthController, () -> {
|
||||
finishedCallback.run();
|
||||
if (mSuccessCallback != null) {
|
||||
mSuccessCallback.accept(true);
|
||||
|
@ -201,6 +230,7 @@ public class SplitSelectStateController {
|
|||
mStagePosition = SplitConfigurationOptions.STAGE_POSITION_UNDEFINED;
|
||||
mInitialBounds = null;
|
||||
mRecentsAnimationRunning = false;
|
||||
mLaunchingTaskView = null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -156,8 +156,8 @@ public class GroupedTaskView extends TaskView {
|
|||
@Nullable
|
||||
@Override
|
||||
public RunnableList launchTaskAnimated() {
|
||||
getRecentsView().getSplitPlaceholder().launchTasks(mTask, mSecondaryTask,
|
||||
STAGE_POSITION_TOP_OR_LEFT, null /*callback*/,
|
||||
getRecentsView().getSplitPlaceholder().launchTasks(this /*groupedTaskView*/,
|
||||
null /*callback*/,
|
||||
false /* freezeTaskList */);
|
||||
return null;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue