Loading quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java +14 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -662,6 +663,14 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>, } 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()); } Loading Loading @@ -915,7 +924,12 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>, 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; Loading quickstep/src/com/android/quickstep/RemoteTargetGluer.java +25 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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, Loading Loading @@ -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. Loading Loading @@ -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. * <p> * 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; } Loading quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java +6 −1 Original line number Diff line number Diff line Loading @@ -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(); Loading Loading @@ -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, Loading Loading
quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java +14 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -662,6 +663,14 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>, } 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()); } Loading Loading @@ -915,7 +924,12 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>, 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; Loading
quickstep/src/com/android/quickstep/RemoteTargetGluer.java +25 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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, Loading Loading @@ -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. Loading Loading @@ -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. * <p> * 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; } Loading
quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java +6 −1 Original line number Diff line number Diff line Loading @@ -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(); Loading Loading @@ -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, Loading