summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java8
-rw-r--r--services/core/java/com/android/server/wm/DisplayRotation.java10
-rw-r--r--services/core/java/com/android/server/wm/RecentsAnimationController.java51
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java30
4 files changed, 89 insertions, 10 deletions
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index c7cf4b05564f..3dbc517af45c 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -5492,6 +5492,14 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
}
boolean updateDisplayOverrideConfigurationLocked() {
+ // Preemptively cancel the running recents animation -- SysUI can't currently handle this
+ // case properly since the signals it receives all happen post-change
+ final RecentsAnimationController recentsAnimationController =
+ mWmService.getRecentsAnimationController();
+ if (recentsAnimationController != null) {
+ recentsAnimationController.cancelAnimationForDisplayChange();
+ }
+
Configuration values = new Configuration();
computeScreenConfiguration(values);
diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java
index c8f2777cc172..73d6cecd9155 100644
--- a/services/core/java/com/android/server/wm/DisplayRotation.java
+++ b/services/core/java/com/android/server/wm/DisplayRotation.java
@@ -480,6 +480,16 @@ public class DisplayRotation {
return false;
}
+ // Preemptively cancel the running recents animation -- SysUI can't currently handle this
+ // case properly since the signals it receives all happen post-change. We do this earlier
+ // in the rotation flow, since DisplayContent.updateDisplayOverrideConfigurationLocked seems
+ // to happen too late.
+ final RecentsAnimationController recentsAnimationController =
+ mService.getRecentsAnimationController();
+ if (recentsAnimationController != null) {
+ recentsAnimationController.cancelAnimationForDisplayChange();
+ }
+
final Transition t = (useShellTransitions
&& !mService.mAtmService.getTransitionController().isCollecting())
? mService.mAtmService.getTransitionController().createTransition(TRANSIT_CHANGE)
diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java
index 5362771ed286..a7e633527b54 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimationController.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java
@@ -221,7 +221,7 @@ public class RecentsAnimationController implements DeathRecipient {
final ArraySet<Task> tasks = Sets.newArraySet(task);
snapshotController.snapshotTasks(tasks);
snapshotController.addSkipClosingAppSnapshotTasks(tasks);
- return snapshotController.getSnapshot(taskId, 0 /* userId */,
+ return snapshotController.getSnapshot(taskId, task.mUserId,
false /* restoreFromDisk */, false /* isLowResolution */);
}
}
@@ -353,18 +353,23 @@ public class RecentsAnimationController implements DeathRecipient {
@Override
public void cleanupScreenshot() {
- synchronized (mService.mGlobalLock) {
- if (mRecentScreenshotAnimator != null) {
- mRecentScreenshotAnimator.cancelAnimation();
- mRecentScreenshotAnimator = null;
+ final long token = Binder.clearCallingIdentity();
+ try {
+ synchronized (mService.mGlobalLock) {
+ if (mRecentScreenshotAnimator != null) {
+ mRecentScreenshotAnimator.cancelAnimation();
+ mRecentScreenshotAnimator = null;
+ }
}
+ } finally {
+ Binder.restoreCallingIdentity(token);
}
}
@Override
public void setWillFinishToHome(boolean willFinishToHome) {
synchronized (mService.getWindowManagerLock()) {
- mWillFinishToHome = willFinishToHome;
+ RecentsAnimationController.this.setWillFinishToHome(willFinishToHome);
}
}
@@ -513,7 +518,6 @@ public class RecentsAnimationController implements DeathRecipient {
|| config.getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
}
-
@VisibleForTesting
AnimationAdapter addAnimation(Task task, boolean isRecentTaskInvisible) {
return addAnimation(task, isRecentTaskInvisible, false /* hidden */,
@@ -816,6 +820,18 @@ public class RecentsAnimationController implements DeathRecipient {
cancelAnimation(REORDER_KEEP_IN_PLACE, screenshot, "rootTaskOrderChanged");
}
+ /**
+ * If there is a recents animation running, we need to cancel the animation and snapshot the
+ * tasks before the change (to ensure they are captured at the right configuration)
+ */
+ public void cancelAnimationForDisplayChange() {
+ if (mCanceled) {
+ return;
+ }
+ cancelAnimation(mWillFinishToHome ? REORDER_MOVE_TO_TOP : REORDER_MOVE_TO_ORIGINAL_POSITION,
+ true /* screenshot */, "cancelAnimationForDisplayChange");
+ }
+
private void cancelAnimation(@ReorderMode int reorderMode, boolean screenshot, String reason) {
ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "cancelAnimation(): reason=%s", reason);
synchronized (mService.getWindowManagerLock()) {
@@ -826,7 +842,7 @@ public class RecentsAnimationController implements DeathRecipient {
mService.mH.removeCallbacks(mFailsafeRunnable);
mCanceled = true;
- if (screenshot) {
+ if (screenshot && !mPendingAnimations.isEmpty()) {
// Screen shot previous task when next task starts transition and notify the runner.
// We will actually finish the animation once the runner calls cleanUpScreenshot().
final Task task = mPendingAnimations.get(0).mTask;
@@ -853,6 +869,11 @@ public class RecentsAnimationController implements DeathRecipient {
}
}
+ @VisibleForTesting
+ void setWillFinishToHome(boolean willFinishToHome) {
+ mWillFinishToHome = willFinishToHome;
+ }
+
/**
* Cancel recents animation when the next app transition starts.
* <p>
@@ -905,7 +926,8 @@ public class RecentsAnimationController implements DeathRecipient {
return null;
}
- final TaskScreenshotAnimatable animatable = new TaskScreenshotAnimatable(mService.mSurfaceControlFactory, task,
+ final TaskScreenshotAnimatable animatable = new TaskScreenshotAnimatable(
+ mService.mSurfaceControlFactory, task,
new SurfaceControl.ScreenshotHardwareBuffer(taskSnapshot.getHardwareBuffer(),
taskSnapshot.getColorSpace(), false /* containsSecureLayers */));
mRecentScreenshotAnimator = new SurfaceAnimator(
@@ -1006,7 +1028,16 @@ public class RecentsAnimationController implements DeathRecipient {
@Override
public void binderDied() {
- cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION, "binderDied");
+ if (!mCanceled) {
+ cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION, "binderDied");
+ } else {
+ synchronized (mService.getWindowManagerLock()) {
+ if (mRecentScreenshotAnimator != null) {
+ mRecentScreenshotAnimator.cancelAnimation();
+ mRecentScreenshotAnimator = null;
+ }
+ }
+ }
synchronized (mService.getWindowManagerLock()) {
// Clear associated input consumers on runner death
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
index 39a59c9e5064..afd0ecf0fdee 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
@@ -655,6 +655,36 @@ public class RecentsAnimationControllerTest extends WindowTestsBase {
assertFalse(win1.mHasSurface);
}
+ @Test
+ public void testCancelForRotation_ReorderToTop() throws Exception {
+ mWm.setRecentsAnimationController(mController);
+ final ActivityRecord activity = createActivityRecord(mDefaultDisplay);
+ final WindowState win1 = createWindow(null, TYPE_BASE_APPLICATION, activity, "win1");
+ activity.addWindow(win1);
+
+ mController.addAnimation(activity.getTask(), false /* isRecentTaskInvisible */);
+ mController.setWillFinishToHome(true);
+ mController.cancelAnimationForDisplayChange();
+
+ verify(mMockRunner).onAnimationCanceled(any());
+ verify(mAnimationCallbacks).onAnimationFinished(REORDER_MOVE_TO_TOP, false);
+ }
+
+ @Test
+ public void testCancelForRotation_ReorderToOriginalPosition() throws Exception {
+ mWm.setRecentsAnimationController(mController);
+ final ActivityRecord activity = createActivityRecord(mDefaultDisplay);
+ final WindowState win1 = createWindow(null, TYPE_BASE_APPLICATION, activity, "win1");
+ activity.addWindow(win1);
+
+ mController.addAnimation(activity.getTask(), false /* isRecentTaskInvisible */);
+ mController.setWillFinishToHome(false);
+ mController.cancelAnimationForDisplayChange();
+
+ verify(mMockRunner).onAnimationCanceled(any());
+ verify(mAnimationCallbacks).onAnimationFinished(REORDER_MOVE_TO_ORIGINAL_POSITION, false);
+ }
+
private ActivityRecord createHomeActivity() {
final ActivityRecord homeActivity = new ActivityBuilder(mWm.mAtmService)
.setParentTask(mRootHomeTask)