Merge "Support desktop tasks in recents animation" into tm-qpr-dev

This commit is contained in:
Ats Jenk
2023-01-23 18:14:53 +00:00
committed by Android (Google) Code Review
7 changed files with 134 additions and 10 deletions

View File

@@ -127,6 +127,7 @@ import com.android.quickstep.util.SurfaceTransaction;
import com.android.quickstep.util.SurfaceTransactionApplier;
import com.android.quickstep.util.SwipePipToHomeAnimator;
import com.android.quickstep.util.TaskViewSimulator;
import com.android.quickstep.views.DesktopTaskView;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
import com.android.systemui.shared.recents.model.Task;
@@ -878,7 +879,11 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
public void onRecentsAnimationStart(RecentsAnimationController controller,
RecentsAnimationTargets targets) {
super.onRecentsAnimationStart(controller, targets);
mRemoteTargetHandles = mTargetGluer.assignTargetsForSplitScreen(mContext, targets);
if (DesktopTaskView.DESKTOP_MODE_SUPPORTED && targets.hasDesktopTasks()) {
mRemoteTargetHandles = mTargetGluer.assignTargetsForDesktop(targets);
} else {
mRemoteTargetHandles = mTargetGluer.assignTargetsForSplitScreen(mContext, targets);
}
mRecentsAnimationController = controller;
mRecentsAnimationTargets = targets;
mSwipePipToHomeReleaseCheck = new RemoteAnimationTargets.ReleaseCheck();

View File

@@ -15,11 +15,15 @@
*/
package com.android.quickstep;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.view.RemoteAnimationTarget.MODE_CLOSING;
import android.app.WindowConfiguration;
import android.graphics.Rect;
import android.view.RemoteAnimationTarget;
import com.android.quickstep.views.DesktopTaskView;
/**
* Extension of {@link RemoteAnimationTargets} with additional information about swipe
* up animation
@@ -40,4 +44,22 @@ public class RecentsAnimationTargets extends RemoteAnimationTargets {
public boolean hasTargets() {
return unfilteredApps.length != 0;
}
/**
* Check if target apps contain desktop tasks which have windowing mode set to {@link
* WindowConfiguration#WINDOWING_MODE_FREEFORM}
*
* @return {@code true} if at least one target app is a desktop task
*/
public boolean hasDesktopTasks() {
if (!DesktopTaskView.DESKTOP_MODE_SUPPORTED) {
return false;
}
for (RemoteAnimationTarget target : apps) {
if (target.windowConfiguration.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
return true;
}
}
return false;
}
}

View File

@@ -26,6 +26,7 @@ import com.android.launcher3.util.SplitConfigurationOptions.SplitBounds;
import com.android.quickstep.util.AnimatorControllerWithResistance;
import com.android.quickstep.util.TaskViewSimulator;
import com.android.quickstep.util.TransformParams;
import com.android.quickstep.views.DesktopTaskView;
import java.util.ArrayList;
@@ -41,8 +42,8 @@ public class RemoteTargetGluer {
* Use this constructor if remote targets are split-screen independent
*/
public RemoteTargetGluer(Context context, BaseActivityInterface sizingStrategy,
RemoteAnimationTargets targets) {
mRemoteTargetHandles = createHandles(context, sizingStrategy, targets.apps.length);
RemoteAnimationTargets targets, boolean forDesktop) {
init(context, sizingStrategy, targets.apps.length, forDesktop);
}
/**
@@ -50,15 +51,31 @@ public class RemoteTargetGluer {
* running tasks
*/
public RemoteTargetGluer(Context context, BaseActivityInterface sizingStrategy) {
if (DesktopTaskView.DESKTOP_MODE_SUPPORTED) {
// TODO: binder call, only for prototyping. Creating the gluer should be postponed so
// we can create it when we have the remote animation targets ready.
int desktopTasks = SystemUiProxy.INSTANCE.get(context).getVisibleDesktopTaskCount();
if (desktopTasks > 0) {
init(context, sizingStrategy, desktopTasks, true /* forDesktop */);
return;
}
}
int[] splitIds = TopTaskTracker.INSTANCE.get(context).getRunningSplitTaskIds();
mRemoteTargetHandles = createHandles(context, sizingStrategy, splitIds.length == 2 ? 2 : 1);
init(context, sizingStrategy, splitIds.length == 2 ? 2 : 1, false /* forDesktop */);
}
private void init(Context context, BaseActivityInterface sizingStrategy, int numHandles,
boolean forDesktop) {
mRemoteTargetHandles = createHandles(context, sizingStrategy, numHandles, forDesktop);
}
private RemoteTargetHandle[] createHandles(Context context,
BaseActivityInterface sizingStrategy, int numHandles) {
BaseActivityInterface sizingStrategy, int numHandles, boolean forDesktop) {
RemoteTargetHandle[] handles = new RemoteTargetHandle[numHandles];
for (int i = 0; i < numHandles; i++) {
TaskViewSimulator tvs = new TaskViewSimulator(context, sizingStrategy);
tvs.setIsDesktopTask(forDesktop);
TransformParams transformParams = new TransformParams();
handles[i] = new RemoteTargetHandle(tvs, transformParams);
}
@@ -135,6 +152,20 @@ public class RemoteTargetGluer {
return mRemoteTargetHandles;
}
/**
* Similar to {@link #assignTargets(RemoteAnimationTargets)}, except this creates distinct
* transform params per app in {@code targets.apps} list.
*/
public RemoteTargetHandle[] assignTargetsForDesktop(RemoteAnimationTargets targets) {
for (int i = 0; i < mRemoteTargetHandles.length; i++) {
RemoteAnimationTarget primaryTaskTarget = targets.apps[i];
mRemoteTargetHandles[i].mTransformParams.setTargetSet(
createRemoteAnimationTargetsForTaskId(targets, primaryTaskTarget.taskId));
mRemoteTargetHandles[i].mTaskViewSimulator.setPreview(primaryTaskTarget, null);
}
return mRemoteTargetHandles;
}
private Rect getStartBounds(RemoteAnimationTarget target) {
return target.startBounds == null ? target.screenSpaceBounds : target.startBounds;
}
@@ -172,6 +203,33 @@ public class RemoteTargetGluer {
filteredApps, targets.wallpapers, targets.nonApps, targets.targetMode);
}
/**
* Ensures that we only animate one specific app target. Includes ancillary targets such as
* home/recents
*
* @param targets remote animation targets to filter
* @param taskId id for a task that we want this remote animation to apply to
* @return {@link RemoteAnimationTargets} where app target only includes the app that has the
* {@code taskId} that was passed in
*/
private RemoteAnimationTargets createRemoteAnimationTargetsForTaskId(
RemoteAnimationTargets targets, int taskId) {
RemoteAnimationTarget[] targetApp = null;
for (RemoteAnimationTarget targetCompat : targets.unfilteredApps) {
if (targetCompat.taskId == taskId) {
targetApp = new RemoteAnimationTarget[]{targetCompat};
break;
}
}
if (targetApp == null) {
targetApp = new RemoteAnimationTarget[0];
}
return new RemoteAnimationTargets(targetApp, targets.wallpapers, targets.nonApps,
targets.targetMode);
}
public RemoteTargetHandle[] getRemoteTargetHandles() {
return mRemoteTargetHandles;
}

View File

@@ -949,4 +949,16 @@ public class SystemUiProxy implements ISystemUiProxy {
}
}
}
/** Call shell to get number of visible freeform tasks */
public int getVisibleDesktopTaskCount() {
if (mDesktopMode != null) {
try {
return mDesktopMode.getVisibleTaskCount();
} catch (RemoteException e) {
Log.w(TAG, "Failed call getVisibleDesktopTaskCount", e);
}
}
return 0;
}
}

View File

@@ -39,6 +39,7 @@ import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.anim.Interpolators.TOUCH_RESPONSE_INTERPOLATOR;
import static com.android.launcher3.anim.Interpolators.clampToProgress;
import static com.android.launcher3.util.MultiPropertyFactory.MULTI_PROPERTY_VALUE;
import static com.android.quickstep.views.DesktopTaskView.DESKTOP_MODE_SUPPORTED;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -78,6 +79,7 @@ import com.android.quickstep.util.SurfaceTransaction.SurfaceProperties;
import com.android.quickstep.util.SurfaceTransactionApplier;
import com.android.quickstep.util.TaskViewSimulator;
import com.android.quickstep.util.TransformParams;
import com.android.quickstep.views.DesktopTaskView;
import com.android.quickstep.views.GroupedTaskView;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskThumbnailView;
@@ -182,9 +184,12 @@ public final class TaskViewUtils {
// Re-use existing handles
remoteTargetHandles = recentsViewHandles;
} else {
boolean forDesktop = DESKTOP_MODE_SUPPORTED && v instanceof DesktopTaskView;
RemoteTargetGluer gluer = new RemoteTargetGluer(v.getContext(),
recentsView.getSizeStrategy(), targets);
if (v.containsMultipleTasks()) {
recentsView.getSizeStrategy(), targets, forDesktop);
if (forDesktop) {
remoteTargetHandles = gluer.assignTargetsForDesktop(targets);
} else if (v.containsMultipleTasks()) {
remoteTargetHandles = gluer.assignTargetsForSplitScreen(targets, v.getTaskIds());
} else {
remoteTargetHandles = gluer.assignTargets(targets);

View File

@@ -104,6 +104,7 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
private SplitBounds mSplitBounds;
private Boolean mDrawsBelowRecents = null;
private boolean mIsGridTask;
private boolean mIsDesktopTask;
private int mTaskRectTranslationX;
private int mTaskRectTranslationY;
@@ -145,6 +146,13 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
if (mDp == null) {
return 1;
}
if (mIsDesktopTask) {
mTaskRect.set(mThumbnailPosition);
mPivot.set(mTaskRect.centerX(), mTaskRect.centerY());
return 1;
}
if (mIsGridTask) {
mSizeStrategy.calculateGridTaskSize(mContext, mDp, mTaskRect,
mOrientationState.getOrientationHandler());
@@ -227,6 +235,13 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
mIsGridTask = isGridTask;
}
/**
* Sets whether this task is part of desktop tasks in overview.
*/
public void setIsDesktopTask(boolean desktop) {
mIsDesktopTask = desktop;
}
/**
* Apply translations on TaskRect's starting location.
*/

View File

@@ -4911,9 +4911,16 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
return;
}
RemoteTargetGluer gluer = new RemoteTargetGluer(getContext(), getSizeStrategy());
mRemoteTargetHandles = gluer.assignTargetsForSplitScreen(
getContext(), recentsAnimationTargets);
RemoteTargetGluer gluer;
if (DESKTOP_MODE_SUPPORTED && recentsAnimationTargets.hasDesktopTasks()) {
gluer = new RemoteTargetGluer(getContext(), getSizeStrategy(), recentsAnimationTargets,
true /* forDesktop */);
mRemoteTargetHandles = gluer.assignTargetsForDesktop(recentsAnimationTargets);
} else {
gluer = new RemoteTargetGluer(getContext(), getSizeStrategy());
mRemoteTargetHandles = gluer.assignTargetsForSplitScreen(
getContext(), recentsAnimationTargets);
}
mSplitBoundsConfig = gluer.getSplitBounds();
// Add release check to the targets from the RemoteTargetGluer and not the targets
// passed in because in the event we're in split screen, we use the passed in targets