diff --git a/services/core/java/com/android/server/wm/SurfaceFreezer.java b/services/core/java/com/android/server/wm/SurfaceFreezer.java index c667db86e4104..233656ffd48d0 100644 --- a/services/core/java/com/android/server/wm/SurfaceFreezer.java +++ b/services/core/java/com/android/server/wm/SurfaceFreezer.java @@ -75,6 +75,7 @@ class SurfaceFreezer { */ void freeze(SurfaceControl.Transaction t, Rect startBounds, Point relativePosition, @Nullable SurfaceControl freezeTarget) { + reset(t); mFreezeBounds.set(startBounds); mLeash = SurfaceAnimator.createAnimationLeash(mAnimatable, mAnimatable.getSurfaceControl(), @@ -139,6 +140,22 @@ class SurfaceFreezer { } } + /** Resets the snapshot before taking another one if the animation hasn't been started yet. */ + private void reset(SurfaceControl.Transaction t) { + // Those would have been taken by the SurfaceAnimator if the animation has been started, so + // we can remove the leash directly. + // No need to reset the mAnimatable leash, as this is called before a new animation leash is + // created, so another #onAnimationLeashCreated will be called. + if (mSnapshot != null) { + mSnapshot.destroy(t); + mSnapshot = null; + } + if (mLeash != null) { + t.remove(mLeash); + mLeash = null; + } + } + void setLayer(SurfaceControl.Transaction t, int layer) { if (mLeash != null) { t.setLayer(mLeash, layer); diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java index bbeb980353edf..e75a2ce7f8296 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java @@ -1173,6 +1173,33 @@ public class WindowContainerTests extends WindowTestsBase { assertNull(surfaceAnimator.mSnapshot); } + @Test + public void testRemoveUnstartedFreezeSurfaceWhenFreezeAgain() { + final WindowContainer container = createTaskFragmentWithParentTask( + createTask(mDisplayContent), false); + container.mSurfaceControl = mock(SurfaceControl.class); + final SurfaceFreezer surfaceFreezer = container.mSurfaceFreezer; + final SurfaceControl.Transaction t = mock(SurfaceControl.Transaction.class); + spyOn(container); + doReturn(t).when(container).getPendingTransaction(); + doReturn(t).when(container).getSyncTransaction(); + + // Leash and snapshot created for change transition. + container.initializeChangeTransition(new Rect(0, 0, 1000, 2000)); + + assertNotNull(surfaceFreezer.mLeash); + + // Can't really take a snapshot, manually set one. + final SurfaceFreezer.Snapshot snapshot = mock(SurfaceFreezer.Snapshot.class); + surfaceFreezer.mSnapshot = snapshot; + final SurfaceControl prevLeash = surfaceFreezer.mLeash; + + container.initializeChangeTransition(new Rect(0, 0, 1500, 2500)); + + verify(t).remove(prevLeash); + verify(snapshot).destroy(t); + } + /* Used so we can gain access to some protected members of the {@link WindowContainer} class */ private static class TestWindowContainer extends WindowContainer { private final int mLayer;