Fix quick switch in between two split pairs crash
Launcher always receive recent animatino start callback before
onStageTaskChanged callback, which result to not able to identify the
correct animate targets to animate. Update to fetch animate target from
wrapped remote animation target directly.
Fix: 236226779
Test: quick in between two split pairs won't crash
Change-Id: Ic10db086256b4a1ed53e5a3becb6fa9114df74ec
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index 4f10dde..b102705 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -876,7 +876,7 @@
if (DesktopTaskView.DESKTOP_MODE_SUPPORTED && targets.hasDesktopTasks()) {
mRemoteTargetHandles = mTargetGluer.assignTargetsForDesktop(targets);
} else {
- mRemoteTargetHandles = mTargetGluer.assignTargetsForSplitScreen(mContext, targets);
+ mRemoteTargetHandles = mTargetGluer.assignTargetsForSplitScreen(targets);
}
mRecentsAnimationController = controller;
mRecentsAnimationTargets = targets;
diff --git a/quickstep/src/com/android/quickstep/RemoteTargetGluer.java b/quickstep/src/com/android/quickstep/RemoteTargetGluer.java
index 9b00dcf..f30d3f1 100644
--- a/quickstep/src/com/android/quickstep/RemoteTargetGluer.java
+++ b/quickstep/src/com/android/quickstep/RemoteTargetGluer.java
@@ -89,7 +89,7 @@
* Length of targets.apps should match that of {@link #mRemoteTargetHandles}.
*
* If split screen may be active when this is called, you might want to use
- * {@link #assignTargetsForSplitScreen(Context, RemoteAnimationTargets)}
+ * {@link #assignTargetsForSplitScreen(RemoteAnimationTargets)}
*/
public RemoteTargetHandle[] assignTargets(RemoteAnimationTargets targets) {
for (int i = 0; i < mRemoteTargetHandles.length; i++) {
@@ -102,43 +102,45 @@
}
/**
- * Similar to {@link #assignTargets(RemoteAnimationTargets)}, except this matches the
- * apps in targets.apps to that of the _active_ split screened tasks.
- * See {@link #assignTargetsForSplitScreen(RemoteAnimationTargets, int[])}
+ * Similar to {@link #assignTargets(RemoteAnimationTargets)}, except this assigns the
+ * apps in {@code targets.apps} to the {@link #mRemoteTargetHandles} with index 0 will being
+ * the left/top task, index 1 right/bottom.
*/
- public RemoteTargetHandle[] assignTargetsForSplitScreen(
- Context context, RemoteAnimationTargets targets) {
- int[] splitIds = TopTaskTracker.INSTANCE.get(context).getRunningSplitTaskIds();
- return assignTargetsForSplitScreen(targets, splitIds);
- }
-
- /**
- * Assigns the provided splitIDs to the {@link #mRemoteTargetHandles}, with index 0 will being
- * the left/top task, index 1 right/bottom
- */
- public RemoteTargetHandle[] assignTargetsForSplitScreen(RemoteAnimationTargets targets,
- int[] splitIds) {
- RemoteAnimationTarget topLeftTarget; // only one set if single/fullscreen task
- RemoteAnimationTarget bottomRightTarget;
+ public RemoteTargetHandle[] assignTargetsForSplitScreen(RemoteAnimationTargets targets) {
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.
mRemoteTargetHandles[0].mTransformParams.setTargetSet(targets);
if (targets.apps.length > 0) {
// Unclear why/when target.apps length == 0, but it sure does happen :(
- topLeftTarget = targets.apps[0];
- mRemoteTargetHandles[0].mTaskViewSimulator.setPreview(topLeftTarget, null);
+ mRemoteTargetHandles[0].mTaskViewSimulator.setPreview(targets.apps[0], null);
}
} else {
- // split screen
- topLeftTarget = targets.findTask(splitIds[0]);
- bottomRightTarget = targets.findTask(splitIds[1]);
+ RemoteAnimationTarget topLeftTarget = targets.apps[0];
+
+ // Fetch the adjacent target for split screen.
+ RemoteAnimationTarget bottomRightTarget = null;
+ for (int i = 1; i < targets.apps.length; i++) {
+ final RemoteAnimationTarget target = targets.apps[i];
+ Rect topLeftBounds = getStartBounds(topLeftTarget);
+ Rect bounds = getStartBounds(target);
+ if (topLeftBounds.left > bounds.right || topLeftBounds.top > bounds.bottom) {
+ bottomRightTarget = topLeftTarget;
+ topLeftTarget = target;
+ break;
+ } else if (topLeftBounds.right < bounds.left || topLeftBounds.bottom < bounds.top) {
+ bottomRightTarget = target;
+ break;
+ }
+ }
// remoteTargetHandle[0] denotes topLeft task, so we pass in the bottomRight to exclude,
// vice versa
mSplitBounds = new SplitBounds(
getStartBounds(topLeftTarget),
- getStartBounds(bottomRightTarget), splitIds[0], splitIds[1]);
+ getStartBounds(bottomRightTarget),
+ topLeftTarget.taskId,
+ bottomRightTarget.taskId);
mRemoteTargetHandles[0].mTransformParams.setTargetSet(
createRemoteAnimationTargetsForTarget(targets, bottomRightTarget));
mRemoteTargetHandles[0].mTaskViewSimulator.setPreview(topLeftTarget,
diff --git a/quickstep/src/com/android/quickstep/TaskViewUtils.java b/quickstep/src/com/android/quickstep/TaskViewUtils.java
index 1a72e3f..da97df6 100644
--- a/quickstep/src/com/android/quickstep/TaskViewUtils.java
+++ b/quickstep/src/com/android/quickstep/TaskViewUtils.java
@@ -190,7 +190,7 @@
if (forDesktop) {
remoteTargetHandles = gluer.assignTargetsForDesktop(targets);
} else if (v.containsMultipleTasks()) {
- remoteTargetHandles = gluer.assignTargetsForSplitScreen(targets, v.getTaskIds());
+ remoteTargetHandles = gluer.assignTargetsForSplitScreen(targets);
} else {
remoteTargetHandles = gluer.assignTargets(targets);
}
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 2505d91..0f7c8af 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -4977,8 +4977,7 @@
mRemoteTargetHandles = gluer.assignTargetsForDesktop(recentsAnimationTargets);
} else {
gluer = new RemoteTargetGluer(getContext(), getSizeStrategy());
- mRemoteTargetHandles = gluer.assignTargetsForSplitScreen(
- getContext(), recentsAnimationTargets);
+ mRemoteTargetHandles = gluer.assignTargetsForSplitScreen(recentsAnimationTargets);
}
mSplitBoundsConfig = gluer.getSplitBounds();
// Add release check to the targets from the RemoteTargetGluer and not the targets