From 57de6565a0e5f29e189497b985ad14e60a5be9ca Mon Sep 17 00:00:00 2001 From: Vinit Nayak Date: Tue, 16 May 2023 13:40:29 -0700 Subject: [PATCH] Resize mRemoteTargetHandles when RecentsAnimationStarts * TopTaskTracker gets updated too late after we've exited split screen so we can't use that to determine how many RemoteTargetHandles to use * We default to 2, and then scale it down to 1. Because we modify the array holding the handles directly, it should also get updated in AbsSwipeUpHandler * Temporary solution to stop setting up RecentsView if we detect that TopTaskTracker has incorrect data and re-setup when we get onRecentsAnimationStart() Test: Tested quickswitch in gestural and recents button double tap in button nav. Bug: 236226779 Flag: none Change-Id: I1bae7aed1f8712ddd1bf496acfcb851c0e32a115 --- .../android/quickstep/AbsSwipeUpHandler.java | 14 ++++++++++ .../android/quickstep/RemoteTargetGluer.java | 27 +++++++++++++++++-- .../quickstep/SwipeUpAnimationLogic.java | 7 ++++- 3 files changed, 45 insertions(+), 3 deletions(-) diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java index 928910d3ab..4131cf955c 100644 --- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java +++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java @@ -147,6 +147,7 @@ import com.android.wm.shell.startingsurface.SplashScreenExitAnimationUtils; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; +import java.util.Objects; import java.util.Optional; import java.util.function.Consumer; @@ -662,6 +663,14 @@ public abstract class AbsSwipeUpHandler, } else { runningTasks = mGestureState.getRunningTask().getPlaceholderTasks(); } + + // Safeguard against any null tasks being sent to recents view, happens when quickswitching + // very quickly w/ split tasks because TopTaskTracker provides stale information compared to + // actual running tasks in the recents animation. + // TODO(b/236226779), Proper fix (ag/22237143) + if (Arrays.stream(runningTasks).anyMatch(Objects::isNull)) { + return; + } mRecentsView.onGestureAnimationStart(runningTasks, mDeviceState.getRotationTouchHelper()); } @@ -915,7 +924,12 @@ public abstract class AbsSwipeUpHandler, if (DesktopTaskView.DESKTOP_MODE_SUPPORTED && targets.hasDesktopTasks()) { mRemoteTargetHandles = mTargetGluer.assignTargetsForDesktop(targets); } else { + int untrimmedAppCount = mRemoteTargetHandles.length; mRemoteTargetHandles = mTargetGluer.assignTargetsForSplitScreen(targets); + if (mRemoteTargetHandles.length < untrimmedAppCount && mIsSwipeForSplit) { + updateIsGestureForSplit(mRemoteTargetHandles.length); + setupRecentsViewUi(); + } } mRecentsAnimationController = controller; mRecentsAnimationTargets = targets; diff --git a/quickstep/src/com/android/quickstep/RemoteTargetGluer.java b/quickstep/src/com/android/quickstep/RemoteTargetGluer.java index d9c269a914..84b90b9b78 100644 --- a/quickstep/src/com/android/quickstep/RemoteTargetGluer.java +++ b/quickstep/src/com/android/quickstep/RemoteTargetGluer.java @@ -29,12 +29,15 @@ import com.android.quickstep.util.TransformParams; import com.android.quickstep.views.DesktopTaskView; import java.util.ArrayList; +import java.util.Arrays; /** * Glues together the necessary components to animate a remote target using a * {@link TaskViewSimulator} */ public class RemoteTargetGluer { + private static final int DEFAULT_NUM_HANDLES = 2; + private RemoteTargetHandle[] mRemoteTargetHandles; private SplitBounds mSplitBounds; @@ -62,8 +65,9 @@ public class RemoteTargetGluer { } } - int[] splitIds = TopTaskTracker.INSTANCE.get(context).getRunningSplitTaskIds(); - init(context, sizingStrategy, splitIds.length == 2 ? 2 : 1, false /* forDesktop */); + // Assume 2 handles needed for split, scale down as needed later on when we actually + // get remote targets + init(context, sizingStrategy, DEFAULT_NUM_HANDLES, false /* forDesktop */); } private void init(Context context, BaseActivityInterface sizingStrategy, int numHandles, @@ -108,6 +112,17 @@ public class RemoteTargetGluer { * the left/top task, index 1 right/bottom. */ public RemoteTargetHandle[] assignTargetsForSplitScreen(RemoteAnimationTargets targets) { + // Resize the mRemoteTargetHandles array since we started assuming split screen, but + // targets.apps is the ultimate source of truth here + long appCount = Arrays.stream(targets.apps) + .filter(app -> app.mode == targets.targetMode) + .count(); + if (appCount < mRemoteTargetHandles.length) { + RemoteTargetHandle[] newHandles = new RemoteTargetHandle[(int) appCount]; + System.arraycopy(mRemoteTargetHandles, 0/*src*/, newHandles, 0/*dst*/, (int) appCount); + mRemoteTargetHandles = newHandles; + } + if (mRemoteTargetHandles.length == 1) { // If we're not in split screen, the splitIds count doesn't really matter since we // should always hit this case. @@ -233,6 +248,14 @@ public class RemoteTargetGluer { targets.targetMode); } + /** + * The object returned by this is may be modified in + * {@link #assignTargetsForSplitScreen(RemoteAnimationTargets)}, specifically the length of the + * array may be shortened based on the number of RemoteAnimationTargets present. + *

+ * This can be accessed at any time, however the count will be more accurate if accessed after + * calling one of the respective assignTargets*() methods + */ public RemoteTargetHandle[] getRemoteTargetHandles() { return mRemoteTargetHandles; } diff --git a/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java b/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java index 1b4fdc4a8f..25ac47a45f 100644 --- a/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java +++ b/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java @@ -82,7 +82,8 @@ public abstract class SwipeUpAnimationLogic implements mContext = context; mDeviceState = deviceState; mGestureState = gestureState; - mIsSwipeForSplit = TopTaskTracker.INSTANCE.get(context).getRunningSplitTaskIds().length > 1; + updateIsGestureForSplit(TopTaskTracker.INSTANCE.get(context) + .getRunningSplitTaskIds().length); mTargetGluer = new RemoteTargetGluer(mContext, mGestureState.getActivityInterface()); mRemoteTargetHandles = mTargetGluer.getRemoteTargetHandles(); @@ -280,6 +281,10 @@ public abstract class SwipeUpAnimationLogic implements return out; } + protected void updateIsGestureForSplit(int targetCount) { + mIsSwipeForSplit = targetCount > 1; + } + private RectFSpringAnim getWindowAnimationToHomeInternal( HomeAnimationFactory homeAnimationFactory, RectF targetRect, TransformParams transformParams, TaskViewSimulator taskViewSimulator,