Remove unstarted freeze surface before starting new freeze

Before, when freeze is calling again before the previous one starts
animation, the old one will never be removed.

Fix: 203491879
Test: atest WmTests:WindowContainerTests
      #testRemoveUnstartedFreezeSurfaceWhenFreezeAgain
Change-Id: If2ca5154f7c4420f43ba3964bcd1067b6e376417
This commit is contained in:
Chris Li
2021-11-04 17:33:09 +08:00
parent 33c3fc3421
commit ad7c4c26d7
2 changed files with 44 additions and 0 deletions

View File

@@ -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);

View File

@@ -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<TestWindowContainer> {
private final int mLayer;