Loading services/core/java/com/android/server/wm/SurfaceAnimator.java +4 −0 Original line number Diff line number Diff line Loading @@ -188,6 +188,10 @@ class SurfaceAnimator { mAnimation.startAnimation(mLeash, t, type, mInnerAnimationFinishedCallback); if (snapshotAnim != null) { mSnapshot = freezer.takeSnapshotForAnimation(); if (mSnapshot == null) { Slog.e(TAG, "No snapshot target to start animation on for " + mAnimatable); return; } mSnapshot.startAnimation(t, snapshotAnim, type); } } Loading services/core/java/com/android/server/wm/SurfaceFreezer.java +31 −8 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import android.graphics.PixelFormat; import android.graphics.Point; import android.graphics.Rect; import android.hardware.HardwareBuffer; import android.util.Slog; import android.view.SurfaceControl; import com.android.internal.annotations.VisibleForTesting; Loading @@ -49,8 +50,10 @@ import com.android.internal.protolog.common.ProtoLog; */ class SurfaceFreezer { private final Freezable mAnimatable; private final WindowManagerService mWmService; private static final String TAG = "SurfaceFreezer"; private final @NonNull Freezable mAnimatable; private final @NonNull WindowManagerService mWmService; @VisibleForTesting SurfaceControl mLeash; Snapshot mSnapshot = null; Loading @@ -59,7 +62,7 @@ class SurfaceFreezer { /** * @param animatable The object to animate. */ SurfaceFreezer(Freezable animatable, WindowManagerService service) { SurfaceFreezer(@NonNull Freezable animatable, @NonNull WindowManagerService service) { mAnimatable = animatable; mWmService = service; } Loading @@ -86,11 +89,14 @@ class SurfaceFreezer { freezeTarget = freezeTarget != null ? freezeTarget : mAnimatable.getFreezeSnapshotTarget(); if (freezeTarget != null) { SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer = createSnapshotBuffer( SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer = createSnapshotBufferInner( freezeTarget, startBounds); final HardwareBuffer buffer = screenshotBuffer == null ? null : screenshotBuffer.getHardwareBuffer(); if (buffer == null || buffer.getWidth() <= 1 || buffer.getHeight() <= 1) { // This can happen when display is not ready. Slog.w(TAG, "Failed to capture screenshot for " + mAnimatable); unfreeze(t); return; } mSnapshot = new Snapshot(t, screenshotBuffer, mLeash); Loading Loading @@ -124,6 +130,11 @@ class SurfaceFreezer { * snapshot. */ void unfreeze(SurfaceControl.Transaction t) { unfreezeInner(t); mAnimatable.onUnfrozen(); } private void unfreezeInner(SurfaceControl.Transaction t) { if (mSnapshot != null) { mSnapshot.cancelAnimation(t, false /* restarting */); mSnapshot = null; Loading Loading @@ -188,6 +199,18 @@ class SurfaceFreezer { return SurfaceControl.captureLayers(captureArgs); } @VisibleForTesting SurfaceControl.ScreenshotHardwareBuffer createSnapshotBufferInner( SurfaceControl target, Rect bounds) { return createSnapshotBuffer(target, bounds); } @VisibleForTesting GraphicBuffer createFromHardwareBufferInner( SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer) { return GraphicBuffer.createFromHardwareBuffer(screenshotBuffer.getHardwareBuffer()); } class Snapshot { private SurfaceControl mSurfaceControl; private AnimationAdapter mAnimation; Loading @@ -198,10 +221,7 @@ class SurfaceFreezer { */ Snapshot(SurfaceControl.Transaction t, SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer, SurfaceControl parent) { // We can't use a delegating constructor since we need to // reference this::onAnimationFinished GraphicBuffer graphicBuffer = GraphicBuffer.createFromHardwareBuffer( screenshotBuffer.getHardwareBuffer()); GraphicBuffer graphicBuffer = createFromHardwareBufferInner(screenshotBuffer); mSurfaceControl = mAnimatable.makeAnimationLeash() .setName("snapshot anim: " + mAnimatable.toString()) Loading Loading @@ -275,5 +295,8 @@ class SurfaceFreezer { * will be generated (but the rest of the freezing logic will still happen). */ @Nullable SurfaceControl getFreezeSnapshotTarget(); /** Called when the {@link #unfreeze(SurfaceControl.Transaction)} is called. */ void onUnfrozen(); } } services/core/java/com/android/server/wm/WindowContainer.java +7 −4 Original line number Diff line number Diff line Loading @@ -614,7 +614,6 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< final DisplayContent dc = getDisplayContent(); if (dc != null) { mSurfaceFreezer.unfreeze(getSyncTransaction()); dc.mChangingContainers.remove(this); } while (!mChildren.isEmpty()) { final E child = mChildren.peekLast(); Loading Loading @@ -1067,9 +1066,6 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< // part of a change transition. if (!visible) { mSurfaceFreezer.unfreeze(getSyncTransaction()); if (mDisplayContent != null) { mDisplayContent.mChangingContainers.remove(this); } } WindowContainer parent = getParent(); if (parent != null) { Loading Loading @@ -2647,6 +2643,13 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< return getSurfaceControl(); } @Override public void onUnfrozen() { if (mDisplayContent != null) { mDisplayContent.mChangingContainers.remove(this); } } @Override public Builder makeAnimationLeash() { return makeSurface().setContainerLayer(); Loading services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java +1 −0 Original line number Diff line number Diff line Loading @@ -419,6 +419,7 @@ public class AppTransitionTests extends WindowTestsBase { task.getBounds(taskBounds); taskFragment.setBounds(0, 0, taskBounds.right / 2, taskBounds.bottom); spyOn(taskFragment); mockSurfaceFreezerSnapshot(taskFragment.mSurfaceFreezer); assertTrue(mDc.mChangingContainers.isEmpty()); assertFalse(mDc.mAppTransition.isTransitionSet()); Loading services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java +1 −0 Original line number Diff line number Diff line Loading @@ -82,6 +82,7 @@ public class TaskFragmentTest extends WindowTestsBase { @Test public void testStartChangeTransition_resetSurface() { mockSurfaceFreezerSnapshot(mTaskFragment.mSurfaceFreezer); final Rect startBounds = new Rect(0, 0, 1000, 1000); final Rect endBounds = new Rect(500, 500, 1000, 1000); mTaskFragment.setBounds(startBounds); Loading Loading
services/core/java/com/android/server/wm/SurfaceAnimator.java +4 −0 Original line number Diff line number Diff line Loading @@ -188,6 +188,10 @@ class SurfaceAnimator { mAnimation.startAnimation(mLeash, t, type, mInnerAnimationFinishedCallback); if (snapshotAnim != null) { mSnapshot = freezer.takeSnapshotForAnimation(); if (mSnapshot == null) { Slog.e(TAG, "No snapshot target to start animation on for " + mAnimatable); return; } mSnapshot.startAnimation(t, snapshotAnim, type); } } Loading
services/core/java/com/android/server/wm/SurfaceFreezer.java +31 −8 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import android.graphics.PixelFormat; import android.graphics.Point; import android.graphics.Rect; import android.hardware.HardwareBuffer; import android.util.Slog; import android.view.SurfaceControl; import com.android.internal.annotations.VisibleForTesting; Loading @@ -49,8 +50,10 @@ import com.android.internal.protolog.common.ProtoLog; */ class SurfaceFreezer { private final Freezable mAnimatable; private final WindowManagerService mWmService; private static final String TAG = "SurfaceFreezer"; private final @NonNull Freezable mAnimatable; private final @NonNull WindowManagerService mWmService; @VisibleForTesting SurfaceControl mLeash; Snapshot mSnapshot = null; Loading @@ -59,7 +62,7 @@ class SurfaceFreezer { /** * @param animatable The object to animate. */ SurfaceFreezer(Freezable animatable, WindowManagerService service) { SurfaceFreezer(@NonNull Freezable animatable, @NonNull WindowManagerService service) { mAnimatable = animatable; mWmService = service; } Loading @@ -86,11 +89,14 @@ class SurfaceFreezer { freezeTarget = freezeTarget != null ? freezeTarget : mAnimatable.getFreezeSnapshotTarget(); if (freezeTarget != null) { SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer = createSnapshotBuffer( SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer = createSnapshotBufferInner( freezeTarget, startBounds); final HardwareBuffer buffer = screenshotBuffer == null ? null : screenshotBuffer.getHardwareBuffer(); if (buffer == null || buffer.getWidth() <= 1 || buffer.getHeight() <= 1) { // This can happen when display is not ready. Slog.w(TAG, "Failed to capture screenshot for " + mAnimatable); unfreeze(t); return; } mSnapshot = new Snapshot(t, screenshotBuffer, mLeash); Loading Loading @@ -124,6 +130,11 @@ class SurfaceFreezer { * snapshot. */ void unfreeze(SurfaceControl.Transaction t) { unfreezeInner(t); mAnimatable.onUnfrozen(); } private void unfreezeInner(SurfaceControl.Transaction t) { if (mSnapshot != null) { mSnapshot.cancelAnimation(t, false /* restarting */); mSnapshot = null; Loading Loading @@ -188,6 +199,18 @@ class SurfaceFreezer { return SurfaceControl.captureLayers(captureArgs); } @VisibleForTesting SurfaceControl.ScreenshotHardwareBuffer createSnapshotBufferInner( SurfaceControl target, Rect bounds) { return createSnapshotBuffer(target, bounds); } @VisibleForTesting GraphicBuffer createFromHardwareBufferInner( SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer) { return GraphicBuffer.createFromHardwareBuffer(screenshotBuffer.getHardwareBuffer()); } class Snapshot { private SurfaceControl mSurfaceControl; private AnimationAdapter mAnimation; Loading @@ -198,10 +221,7 @@ class SurfaceFreezer { */ Snapshot(SurfaceControl.Transaction t, SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer, SurfaceControl parent) { // We can't use a delegating constructor since we need to // reference this::onAnimationFinished GraphicBuffer graphicBuffer = GraphicBuffer.createFromHardwareBuffer( screenshotBuffer.getHardwareBuffer()); GraphicBuffer graphicBuffer = createFromHardwareBufferInner(screenshotBuffer); mSurfaceControl = mAnimatable.makeAnimationLeash() .setName("snapshot anim: " + mAnimatable.toString()) Loading Loading @@ -275,5 +295,8 @@ class SurfaceFreezer { * will be generated (but the rest of the freezing logic will still happen). */ @Nullable SurfaceControl getFreezeSnapshotTarget(); /** Called when the {@link #unfreeze(SurfaceControl.Transaction)} is called. */ void onUnfrozen(); } }
services/core/java/com/android/server/wm/WindowContainer.java +7 −4 Original line number Diff line number Diff line Loading @@ -614,7 +614,6 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< final DisplayContent dc = getDisplayContent(); if (dc != null) { mSurfaceFreezer.unfreeze(getSyncTransaction()); dc.mChangingContainers.remove(this); } while (!mChildren.isEmpty()) { final E child = mChildren.peekLast(); Loading Loading @@ -1067,9 +1066,6 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< // part of a change transition. if (!visible) { mSurfaceFreezer.unfreeze(getSyncTransaction()); if (mDisplayContent != null) { mDisplayContent.mChangingContainers.remove(this); } } WindowContainer parent = getParent(); if (parent != null) { Loading Loading @@ -2647,6 +2643,13 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< return getSurfaceControl(); } @Override public void onUnfrozen() { if (mDisplayContent != null) { mDisplayContent.mChangingContainers.remove(this); } } @Override public Builder makeAnimationLeash() { return makeSurface().setContainerLayer(); Loading
services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java +1 −0 Original line number Diff line number Diff line Loading @@ -419,6 +419,7 @@ public class AppTransitionTests extends WindowTestsBase { task.getBounds(taskBounds); taskFragment.setBounds(0, 0, taskBounds.right / 2, taskBounds.bottom); spyOn(taskFragment); mockSurfaceFreezerSnapshot(taskFragment.mSurfaceFreezer); assertTrue(mDc.mChangingContainers.isEmpty()); assertFalse(mDc.mAppTransition.isTransitionSet()); Loading
services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java +1 −0 Original line number Diff line number Diff line Loading @@ -82,6 +82,7 @@ public class TaskFragmentTest extends WindowTestsBase { @Test public void testStartChangeTransition_resetSurface() { mockSurfaceFreezerSnapshot(mTaskFragment.mSurfaceFreezer); final Rect startBounds = new Rect(0, 0, 1000, 1000); final Rect endBounds = new Rect(500, 500, 1000, 1000); mTaskFragment.setBounds(startBounds); Loading