From 993e9227886c31fdfc90a603645eea6e28582338 Mon Sep 17 00:00:00 2001 From: Chris Li Date: Mon, 27 Sep 2021 18:04:10 +0800 Subject: [PATCH] Set animation layer for SurfaceFreezer leash Before, when #onAnimationLeashCreated is called, it will set layer through SurfaceAnimator. However, that doesn't cover the case when the layer is created by the SurfaceFreezer, and has not been taken by the SurfaceAnimator. Bug: 196173550 Test: atest WmTests:WindowContainerTests#testAssignAnimationLayer Change-Id: Ia3cc0eca3550e29fee00fafa8ddf356d00512df7 --- .../com/android/server/wm/SurfaceFreezer.java | 12 +++++++ .../android/server/wm/WindowContainer.java | 26 +++++++++----- .../server/wm/WindowContainerTests.java | 35 +++++++++++++++++++ 3 files changed, 65 insertions(+), 8 deletions(-) diff --git a/services/core/java/com/android/server/wm/SurfaceFreezer.java b/services/core/java/com/android/server/wm/SurfaceFreezer.java index fce2f8da10c78..0f562d77b9886 100644 --- a/services/core/java/com/android/server/wm/SurfaceFreezer.java +++ b/services/core/java/com/android/server/wm/SurfaceFreezer.java @@ -123,6 +123,18 @@ class SurfaceFreezer { } } + void setLayer(SurfaceControl.Transaction t, int layer) { + if (mLeash != null) { + t.setLayer(mLeash, layer); + } + } + + void setRelativeLayer(SurfaceControl.Transaction t, SurfaceControl relativeTo, int layer) { + if (mLeash != null) { + t.setRelativeLayer(mLeash, relativeTo, layer); + } + } + boolean hasLeash() { return mLeash != null; } diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java index 26fe2fc596042..8a91095b52fe2 100644 --- a/services/core/java/com/android/server/wm/WindowContainer.java +++ b/services/core/java/com/android/server/wm/WindowContainer.java @@ -2320,10 +2320,15 @@ class WindowContainer extends ConfigurationContainer< } protected void setLayer(Transaction t, int layer) { - - // Route through surface animator to accommodate that our surface control might be - // attached to the leash, and leash is attached to parent container. - mSurfaceAnimator.setLayer(t, layer); + if (mSurfaceFreezer.hasLeash()) { + // When the freezer has created animation leash parent for the window, set the layer + // there instead. + mSurfaceFreezer.setLayer(t, layer); + } else { + // Route through surface animator to accommodate that our surface control might be + // attached to the leash, and leash is attached to parent container. + mSurfaceAnimator.setLayer(t, layer); + } } int getLastLayer() { @@ -2331,10 +2336,15 @@ class WindowContainer extends ConfigurationContainer< } protected void setRelativeLayer(Transaction t, SurfaceControl relativeTo, int layer) { - - // Route through surface animator to accommodate that our surface control might be - // attached to the leash, and leash is attached to parent container. - mSurfaceAnimator.setRelativeLayer(t, relativeTo, layer); + if (mSurfaceFreezer.hasLeash()) { + // When the freezer has created animation leash parent for the window, set the layer + // there instead. + mSurfaceFreezer.setRelativeLayer(t, relativeTo, layer); + } else { + // Route through surface animator to accommodate that our surface control might be + // attached to the leash, and leash is attached to parent container. + mSurfaceAnimator.setRelativeLayer(t, relativeTo, layer); + } } protected void reparentSurfaceControl(Transaction t, SurfaceControl newParent) { 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 00f3d8b874f73..68053eb324b2f 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java @@ -1071,6 +1071,41 @@ public class WindowContainerTests extends WindowTestsBase { verify(surfaceAnimator).setRelativeLayer(t, relativeParent, 1 /* layer */); } + @Test + public void testAssignAnimationLayer() { + final WindowContainer container = new WindowContainer(mWm); + container.mSurfaceControl = mock(SurfaceControl.class); + final SurfaceAnimator surfaceAnimator = container.mSurfaceAnimator; + final SurfaceFreezer surfaceFreezer = container.mSurfaceFreezer; + final SurfaceControl relativeParent = mock(SurfaceControl.class); + final SurfaceControl.Transaction t = mock(SurfaceControl.Transaction.class); + spyOn(container); + spyOn(surfaceAnimator); + spyOn(surfaceFreezer); + + container.setLayer(t, 1); + container.setRelativeLayer(t, relativeParent, 2); + + // Set through surfaceAnimator if surfaceFreezer doesn't have leash. + verify(surfaceAnimator).setLayer(t, 1); + verify(surfaceAnimator).setRelativeLayer(t, relativeParent, 2); + verify(surfaceFreezer, never()).setLayer(any(), anyInt()); + verify(surfaceFreezer, never()).setRelativeLayer(any(), any(), anyInt()); + + clearInvocations(surfaceAnimator); + clearInvocations(surfaceFreezer); + doReturn(true).when(surfaceFreezer).hasLeash(); + + container.setLayer(t, 1); + container.setRelativeLayer(t, relativeParent, 2); + + // Set through surfaceFreezer if surfaceFreezer has leash. + verify(surfaceFreezer).setLayer(t, 1); + verify(surfaceFreezer).setRelativeLayer(t, relativeParent, 2); + verify(surfaceAnimator, never()).setLayer(any(), anyInt()); + verify(surfaceAnimator, never()).setRelativeLayer(any(), any(), anyInt()); + } + /* 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;